34.18. Lazy Materialization with a Virtual Proxy

It is sometimes desirable to defer the materialization of an object until it is absolutely required, usually for performance reasons. For example, suppose that ProductSpecification objects reference a Manufacturer object, but only very rarely does it need to be materialized from the database. Only rare scenarios cause a request for manufacturer information, such as manufacturer rebate scenarios in which the company name and address are required.

The deferred materialization of “children” objects is known as lazy materialization. Lazy materialization can be implemented using the Virtual Proxy GoF pattern—one of many variations of Proxy.

A Virtual Proxy is a proxy for another object (the real subject) that materializes the real subject when it is first referenced; therefore, it implements lazy materialization. It is a lightweight object that stands for a “real” object that may or may not be materialized.

A concrete example of the Virtual Proxy pattern with ProductSpecification and Manufacturer is shown in Figure 34.16. This design is based on the assumption that proxies know the OID of their real subject, and when materialization is required, the OID is used to help identify and retrieve the real subject.

Figure 34.16. Manufacturer Virtual Proxy.


Note that the ProductSpecification has attribute visibility to an IManufacturer instance. The Manufacturer for this ProductSpecification may not yet be materialized in memory. When the ProductSpecification sends a getAddress message to the ManufacturerProxy (as though it were the materialized manufacturer object), the proxy materializes the real Manufacturer, using the OID of the Manufacturer to retrieve and materialize it.

Implementation of a Virtual Proxy

The implementation of a Virtual Proxy varies by language. The details are outside the scope of this chapter, but here is a synopsis:

LanguageVirtual Proxy Implementation
C++Define a templatized smart pointer class. No IManufacturer interface definition is actually needed.
JavaThe ManufacturerProxy class is implemented. The IManufacturer interface is defined.

However, these are not normally manually coded. Rather, one creates a code generator that analyzes the subject classes (e.g., Manufacturer) and generates IManufacturer and ProxyManufacturer.

Another Java alternative is the Dynamic Proxy API.
SmalltalkDefine a Virtual Morphing Proxy (or Ghost Proxy), which uses #doesNotUnderstand: and #become: to morph into the real subject. No IManufacturer definition is needed.

Who Creates the Virtual Proxy?

Observe in Figure 34.16 that the ManufacturerProxy collaborates with the PersistenceFacade in order to materialize its real subject. But who creates the ManufacturerProxy? Answer: The database mapper class for ProductSpecification. The mapper class is responsible for deciding, when it materializes an object, which of its “child” objects should also be eagerly materialized, and which should be lazily materialized with a proxy.

Consider these alternative solutions: one uses eager materialization, the other lazy materialization.

							// EAGER MATERIALIZATION OF MANUFACTURER
							class ProductSpecificationRDBMapper extends AbstractPersistenceMapper
							{
							protected Object getObjectFromStorage( OID oid )
							{
							ResultSet rs =
							RDBOperations.getInstance().getProductSpecificationData( oid );
							ProductSpecification ps = new ProductSpecification();
							ps.setPrice( rs.getDouble( "PRICE" ) );
							// here's the essence of it
							String manufacturerForeignKey = rs.getString( "MANU_OID" );
							OID manuOID = new OID( manufacturerForeignKey );
							ps.setManufacturer( (IManufacturer)
							PersistenceFacade.getInstance().get(manuOID,Manufacturer.class);
							...
							}
						

Here is the lazy materialization solution:

							// LAZY MATERIALIZATION OF MANUFACTURER
							class ProductSpecificationRDBMapper extends AbstractPersistenceMapper
							{
							protected Object getObjectFromStorage( OID oid )
							{
							ResultSet rs =
							RDBOperations.getInstance().getProductSpecificationData( oid );
							ProductSpecification ps = new ProductSpecification();
							ps.setPrice( rs.getDouble( "PRICE" ) );
							// here's the essence of it
							String manufacturerForeignKey = rs.getString( "MANU_OID" );
							OID manuOID = new OID( manufacturerForeignKey );
							ps.setManufacturer( new ManufacturerProxy( manuOID ) );
							...
							}
						

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.173.78