Update Factory

Summary

Purpose

Generates update information based on modified domain object attributes.

Scenario

In the Selection Factory pattern we mentioned that a primary function for any domain object mapping is  to identify the set of relational data on which to operate. Applications indicate this set using identity objects and the relational concept that is analogous to an identity object is the WHERE clause in SQL statements. And in the Domain Object Factory, we also mentioned that another primary function for any domain object mapping is populating domain objects based on query resultsEach row of a query result contains data needed to create and initialize a new domain object. Still, another primary function for any domain object mapping is updating physical data based on new and changed domain object attributes. This is essentially the reverse of what the Domain Object Factory describes.

Each domain object that the application references corresponds to one or more tables whose data must be updated to reflect any changes in the analogous domain object. In some cases, this is as simple as copying data directly from the domain object's attributes to the corresponding table. However, in most cases there are additional translations and mappings that should be processed before any table update can be applied. 

To illustrate, consider the Customer example given earlier in the Domain Object Factory pattern. There we said that the Domain Object Factory is responsible for translating a row from a given table to an object that exposes the row's columns as properties. Here the Update Factory pattern is responsible for translating new and changed domain object attributes into table update operations. This situation is shown below:

 

An update operation in the context of the Update Factory corresponds to either a SQL INSERT or a SQL UPDATE statement, depending on whether the domain object is new or changed. The Update Factory pattern therefore, describes a strategy for encapsulating the details of translating domain object changes to update operations using a single factory object (the update factory). 

Structure & UML

The following figure illustrates the static structure for the Update Factory pattern :

IUpdate interface defines the update operation representation for your system and ConcreteUpdate implements it. If the domain object mapping interacts directly with a database, you can use UPDATE and INSERT SQL statements, whereas if the domain object mapping sits on top of a data accessor, then you can define an update operation that is independent of any database technology.

IUpdateFactory interface defines a single operation for generating a new Update object based on a given domain object. ConcreteFactoryUpdate implements this operation for a specific domain object type or target database entity. Client code should only refer to IUpdate and IUpdateFactory interfaces, keeping them decoupled from any actual impelmentation.

The following figure illustrates the sequence diagram for the Update Factory pattern:

When a client requires a new update operation for a domain object, it passes the domain object to the ConcreteUpdateFactory.NewUpdate method, which in turn returns a ConcreteUpdate object that the client can use to issue database write operations.

Example

The following code implements the IUpdateFactory for the example given in the Scenario section:

public interface IUpdateFactory
{
    string NewUpdate ( object obIdentityObject );
}

// IUpdateFactory implementation that generates a Update clause
// based on a given ProductCode
public class ProductUpdateFactory : IUpdateFactory
{
    // IUpdateFactory implementation
    public Hashtable NewUpdate( object obDomain )
    {
        // Get the Product object
        Product pr = (Product)obDomain;

        // Store updated values in a dictionary
        Hashtable map = new Hashtable();
        map.Add( "Category", pr.Category );
        map.Add( "Price", pr.Price );
        map.Add( "Origin", pr.Origin );

        return map;
    }
}

public class Product
{
    private int nCategory;
    private double dPrice;
    private string strOrigin = "";

    public int Category
    {
        get { return nCategory; }
        set { nCategory= value; }
    }
    public double Price
    {
        get { return dPrice; }
        set { dPrice = value; }
    }
    public string Origin
    {
        get { return strOrigin; }
        set { strOrigin = value; }
    }
}

static void Main(string[] args)
{   
    /* Create a new domain object and assign values */
    Product obProduct = new Product();
    obProduct.Category = 10;
    obProduct.Price = 10.0;
    obProduct.Origin = "UK";
    
    // Use Update factory to obtain a Update (WHERE) clause
    IUpdateFactory ufProduct = new ProductUpdateFactory();
    Hashtable mapUpdate = ufProduct.NewUpdate( obProduct );

    // Use the obtained update map to build a SQL INSERT statement
    ... 
}

Applicability

Use this pattern when:

Strategies / Variants

Consider these strategies when designing a update factory:

Benefits

Related Patterns