Partitioning Patterns - FSU Computer Science

Download Report

Transcript Partitioning Patterns - FSU Computer Science

Partitioning Patterns
How 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.
PP - Layered Initialization
Suppose you have a business rule engine which must select a type
of database on which to query to resolve issues in the rule base.
trigger
to resolve
business rule
Oracle
query
Resolve
Business
Rules
query
request
Select
Database
DB2
query
n
query
Perform
Oracle
Query
Perform
DB2
Query
Perform
n
Query
You cannot perform query until you know what type of database
PP - Layered Initialization
You need to initialize the database prior to query.
Initialize
Database
trigger
to resolve
business rule
Oracle
query
Resolve
Business
Rules
query
request
Select
Database
DB2
query
n
query
Perform
Oracle
Query
Perform
DB2
Query
Perform
n
Query
PP - Layered Initialization
ServiceImpFactoryIF
DataQueryFactoryIF
request creation
DataQuery
ServiceImpFactory
uses
DataQueryImplFactory
creates
Service
OracleQuery
ServiceImpIIF
DB2Query
…..
DataQueryImplIF
Data Query factory method object appears like this.
PP - Layered Initialization
import 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;
} // createDataQueryImpl(String)
} // class MyDataQueryFactory
} // try
PP - Layered Initialization
package 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
public void setFactory(DataQueryFactoryIF factory) {
if (this.factory != null)
throw new Error("Data query factory already defined");
this.factory = factory;
} // setFactory(DataQueryFactoryIF)
been set
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;
// 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 Initialization
package 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.
PP - Filter
Define the classes necessary to perform the transformation.
Source
input
Organize
Lines
lines
Sink
For any general transformation.
Source
input
Tranform
Data
output
Sink
PP - Filter
AbstractSourceFilter
AbstractSink
AbstractSink
gets
ConcreteSourceFilter
gets
AbstractSource
Source Filter
ConcreteSource
PP - Filter
AbstractSinkFilter
AbstractSource
gets
ConcreteSinkFilter
gets
AbstractSink
Sink Filter
ConcreteSink
PP - Filter
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() {
} // class ByteCountInStream
return byteCount;
} // getByteCount()
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 - 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.
PP - Composite
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
Suppose you have characters, gifs, and frames and you wish
to combine them into lines and columns.
characters, gifs, frames
Format
Document
formated
You need to create a structure of the objects that comprise the
formatted document.
PP - Composite
AbstractComponent
DocumentElement
Abstract Composite
ConcreteComponent
Character
edits
Image
CompositeDocumentElement
ConcreteComposite
Document
Page Column Frame
LineofText