partitioning patterns how to partition complex actors and concepts into multiple classes. layered...

Post on 03-Jan-2016

219 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Partitioning PatternsHow to partition complex actors and concepts into multiple classes.

Layered Initialization

Filter

Composite

PP - Layered Initialization

Synopsis:

You need multiple implementations with common logic in super and specialized in subs.

However the common logic decides which specialized subclass to create.

Therefore layered initialization encapsulates common and specialized logic to create the multiple implementations.

PP - Layered Initialization

Context:

You have a piece of logic that requires partial execution prior to determining which subclass methods might be used.

You need to layer the initializations of the objects to process the complex logic or complex data.

PP - Layered Initialization

Forces:

A specialized class must be chosen to process complex data.

Constructor of the specialized classes and their sub classes are invoked after it has been decided which specialized class to instanciate.

Solution:

Essence of this pattern is to layer the initializations of the objects participating in the pattern.

PP - Layered Initialization

1. Objects that performs logic common to all cases is initialized

2. Initialization concludes by determining the class to instantiate

3. Specialized class constructor performs next layer of initialization logic.

4. After all initialization, one top-level object exist for logic

5. If method needs more specialized logic, it calls method one layer down

Consequences:

Complexity of initialization of objects using data requires analysis before initialization can proceed.

ResolveBusiness

Rules

query request

PP - Layered Initialization

trigger to resolve business rule

Suppose you have a business rule engine which must select a typeof database on which to query to resolve issues in the rule base.

SelectDatabase

Perform OracleQuery

Perform DB2

Query

Perform n

Query

Oraclequery

DB2query

nquery

You cannot perform query until you know what type of database

ResolveBusiness

Rules

query request

PP - Layered Initialization

trigger to resolve business rule

You need to initialize the database prior to query.

SelectDatabase

Perform OracleQuery

Perform DB2

Query

Perform n

Query

Oraclequery

DB2query

nquery

InitializeDatabase

PP - Layered Initialization

DataQueryFactoryIF DataQueryrequest creation

DataQueryImplFactory

OracleQuery DB2Query …..

DataQueryImplIF

creates

uses

Data Query factory method object appears like this.

ServiceImpFactoryIF

ServiceImpFactory

Service

ServiceImpIIF

PP - Layered Initializationimport java.util.Hashtable;

// Factory Method class for creating instances of classes for database queries.

class MyDataQueryFactory implements DataQueryFactoryIF {

private static Hashtable classes = new Hashtable();

// populate the classes hashtable

static {

classes.put("INVENTORY", dataQuery.OracleQuery.class);

classes.put("SALES", dataQuery.SybaseQuery.class);

classes.put("PERSONNEL", dataQuery.OracleQuery.class);

classes.put("WHEATHER", dataQuery.JDBCQuery.class);

//...

}

PP - Layered Initialization // Create a DataQueryImplIF object that retrieves data from the specified database.

// @param dbName the name of the database that will be queried

// @return An instance of a class specific to either JDBC or the physical database engine.

// If the specified database is not know to this method, it returns null.

public DataQueryFactoryIF createDataQueryImpl(String dbName) {

Class clazz = (Class)classes.get(dbName);

try {

return (DataQueryFactoryIF)clazz.newInstance();

} catch (Exception e) { return null; } // try

} // createDataQueryImpl(String)

} // class MyDataQueryFactory

PP - Layered Initializationpackage dataQuery;

// This class takes a database query and returns a result.

public class DataQuery {

// Factory object for creating DataQueryImplIF objects.

private DataQueryFactoryIF factory;

// Set the factory object

// @exception Error if this method is called after a factory has been set

public void setFactory(DataQueryFactoryIF factory) {

if (this.factory != null)

throw new Error("Data query factory already defined");

this.factory = factory;

} // setFactory(DataQueryFactoryIF)

PP - Layered Initialization / Constructor * @param query A string containing the query

public DataQuery(String query) {

//...

while ( /*...*/ ) {

String dbName = null;

//...

// Construct a database specific query object

DataQueryImplIF dq;

dq = (DataQueryImplIF)factory.createDataQueryImpl(dbName);

//...

} // while //...

} // Constructor(String) //...

} // class DataQuery

PP - Layered Initializationpackage dataQuery;

// Factory classes that create instances of classes that implement the

// DataQueryImplIF interface must implement this interface.

public interface DataQueryFactoryIF {

// Create a DataQueryImplIF object that retrieves data from the specified database.

// @param dbName - name of database that will be queried

// @return An instance of a class specific to either JDBC or the physical database engine.

public DataQueryFactoryIF createDataQueryImpl(String dbName);

} // DataQueryFactoryIF

PP - Layered Initialization // Constructor * @param query A string containing the query

public DataQuery(String query) {

//...

while ( /*...*/ ) {

String dbName = null;

//...

// Construct a database specific query object

DataQueryImplIF dq;

dq = (DataQueryImplIF)factory.createDataQueryImpl(dbName);

//...

} // while //...

} // Constructor(String) //...

} // class DataQuery

PP - Layered Initialization package dataQuery;

// Classes the perform data queries on data bases implement this interface.

interface DataQueryImplIF {

//...

} // interface DataQueryImplIF

// Class to perform queries using JDBC

class JDBCQuery implements DataQueryImplIF {

//...

} // class JDBCQuery

PP - Layered Initializationpackage dataQuery;

// Class to perform queries against an Oracle Database.

class OracleQuery implements DataQueryImplIF {

//...

} // class OracleQuery

// Class to perform queries against an Sybase Database.

class SybaseQuery implements DataQueryImplIF {

//...

} // class SybaseQuery

PP - Filter

Synopsis:

Allows objects that perform different transformation and computations on streams of data and that have compatible interfaces to dynamically connect in order to perform arbitrary operations on streams of data.

PP - Filter

Context:

Define classes that perform the more common transformations and analysis.

Solution:

Filter pattern organizes classes that participate in it as data sources, sinks and filters. They perform transformation and analysis operations.

1. Data flows as a result of data sink object calling a method in a data source object

2. Data flows when a data source object passes data to a method of a sink object.

Consequences:

Filter pattern is structured as a set of sources, sinks and filters.

OrganizeLines

lines Sinkinput

Define the classes necessary to perform the transformation.

PP - Filter

Source

TranformData

output SinkinputSource

For any general transformation.

AbstractSink

PP - Filter

AbstractSourceFilter

ConcreteSourceFilter

AbstractSource

ConcreteSourceSource Filter

gets

gets

AbstractSink

AbstractSource

PP - Filter

AbstractSinkFilter

ConcreteSinkFilter

AbstractSink

ConcreteSinkSink Filter

gets

gets

import java.io.IOException;

// Filter class to count the number of bytes read from an InStream

public class ByteCountInStream extends FilterInStream {

private long byteCount = 0;

// Constructor @param inStream InStream this object should delegate read operations to.

public ByteCountInStream(InStream inStream) throws IOException {

super(inStream);

} // Constructor(InStream)

PP - Filter

// Read bytes from a stream of bytes and fill an array with those bytes.

// @param array The array of bytes to fill.

// @exception IOException if a I/O error occurs.

public int read(byte[] array) throws IOException {

int count;

count = super.read(array);

if (count >0) byteCount += count;

return count;

} // read(byte[])

// return the number of bytes that have been read by this object.

public long getByteCount() { return byteCount; } // getByteCount()

} // class ByteCountInStream

PP - Filter

import java.io.IOException;

import java.io.RandomAccessFile;

// This class reads a stream of bytes from a file.

public class FileInStream extends InStream {

private RandomAccessFile file;

// Constructor @param fName The name of the file to read

public FileInStream(String fName) throws IOException {

file = new RandomAccessFile(fName, "r");

} // Constructor(String)

PP - Filter

// Read bytes from a file and fill an array with those bytes.

// @param array The array of bytes to fill.

// @return If not enough bytes available to fill array this method returns after partial fill.

// This methods returns -1 if the end of the data stream is encountered.

// @exception IOException if a I/O error occurs.

public int read(byte[] array) throws IOException {

return file.read(array);

} // read(byte[])

} // class FileInStream

PP - Filter

import java.io.IOException;

// Abstract filter class for InStream objects.

// This class does no actual tranformation or analysis of data.

// It just provides a read method that delegates the actual read to another InStream object.

public class FilterInStream extends InStream {

private InStream inStream;

// Constructor @param inStream InStream this object should delegate read operations to.

public FilterInStream(InStream inStream) throws IOException {

this.inStream = inStream;

} // Constructor(InStream)

PP - Filter

// Read bytes from a stream of bytes and fill an array with those bytes.

// @param array The array of bytes to fill.

// @exception IOException if a I/O error occurs.

public int read(byte[] array) throws IOException {

return inStream.read(array);

} // read(byte[])

} // class FilterInStream

PP - Filter

import java.io.IOException;

// Abstract class for reading a stream of bytes into an byte[].

public abstract class InStream {

// Read bytes and fill an array with those bytes.

// @param array The array of bytes to fill.

// @return If not enough bytes available to fill the array method returns after partial fill.

// This methods returns -1 if the end of the data stream is encountered.

// @exception IOException if a I/O error occurs.

public abstract int read(byte[] array) throws IOException;

} // class InStream

PP - Filter

import java.io.IOException;

// Filter class to perform eight bit character translation.

// This class treats bytes in bytes stream as eight bit character codes.

// It then translates with a translation table.

public class TranslateInStream extends FilterInStream {

private byte[] translationTable;

private final static int TRANS_TBL_LENGTH = 256;

PP - Filter

// Constructor

// @param inStream The InStream that this objects should delegate read operations to

// @param table Array of bytes used to determine translation values for character codes.

// Value to replace character code. If shorter than length then no translation.

// If array longer than TRANS_TBL_LENGTH additional elements are ignored.

public TranslateInStream(InStream inStream, byte[] table) throws IOException {

super(inStream);

// Create translation table by copying translation data.

translationTable = new byte[TRANS_TBL_LENGTH];

System.arraycopy(table, 0, translationTable, 0,

Math.min(TRANS_TBL_LENGTH, table.length));

for (int i = table.length; i < TRANS_TBL_LENGTH; i++) {

translationTable[i] = (byte)i;

} // for

} // Constructor(InStream)

PP - Filter

// Read bytes from a stream of bytes and fill an array with those bytes.

// @param array The array of bytes to fill.

// @exception IOException if a I/O error occurs.

public int read(byte[] array) throws IOException {

int count;

count = super.read(array);

for (int i = 0; i < count; i++) {

array[i] = translationTable[array[i]];

} // for

return count;

} // read(byte[])

} // class ByteCountInStream

PP - Filter

PP - Composite Alias: Recursive Composition

Synopsis:

Recursively building a composite object from other objects.

Allows you to build complex objects by recursively composing similar objects in a treelike manner. Allows objects in the tree to be manipulated in a consistent manner, by requiring all of the objects in the tree to have a common superclass or interface.

PP - Composite Alias: Recursive Composition

Context:

There is a fair amount of complexity involved in these objects. Composite pattern removes that complexity by allowing these objects to know how to handle the complexity.

Forces:

You have a complex object that you want to decompose into a part whole hierarchy of objects.

Solution:

Minimize the complexity of a composite object organized into part whole hierarchies by providing an abstract superclass for all objects in the hierarchy and an abstract superclass for all composition in the hierarchy.

Consequences:

High cohesion may arise as a result of applying this pattern.

PP - Composite

FormatDocument

formated

You need to create a structure of the objects that comprise the formatted document.

characters, gifs, frames

Suppose you have characters, gifs, and frames and you wishto combine them into lines and columns.

PP - Composite

DocumentElement edits

PP - Composite

Character Image CompositeDocumentElement

Document Page Column Frame LineofText

AbstractComponent

ConcreteComponent Abstract Composite

ConcreteComposite

top related