|
|
Abstract factory Pattern
|
Define
abstract factory pattern
|
Definition
Provides one level of interface higher than the factory pattern. It is
used to return one of several factories.
|
Where
to use & benefits
|
Creates families of related or
dependent objects like Kit.
Provides a class library of products, exposing interface not
implementation.
Needs to isolate concrete classes from their super classes.
A system needs independent of how its products are created, composed,
and represented.
Try to enforce a constraint.
An alternative to Facade to hide platform-specific classes
Easily extensible to a system or a family
Related patterns include
- Factory method, which is often implemented with an abstract
factory.
- Singleton, which is often implemented with an abstract
factory.
- Prototype, which is often implemented with an abstract
factory.
- Facade, which is often used with an abstract factory by
providing an
interface for creating implementing class.
|
|
Give
an example of Abstract factory patterns
|
Suppose you need to write a
program to show data in two different places. Let's say from a local or
a remote database. You need to make a connection to a database before
working on the data. In this case, you have two choices, local or
remote. You may use abstract factory design pattern to design the
interface in the following way:

class DataInfo {}
interface Local {
DataInfo[] loadDB(String filename);
}
interface Remote extends Local{
void connect2WWW(String url);
}
class LocalMode implements Local {
public DataInfo[] loadDB(String name) {
System.out.print("Load from a local database ");
return null;
}
}
class RemoteMode implements Remote {
public void connect2WWW(String url) {
System.out.println("Connect to a remote site ");
}
public DataInfo[] loadDB(String name) {
System.out.println("Load from a remote
database ");
return null;
}
}
// The Abstract Factory
interface ConnectionFactory {
Local getLocalConnection();
Remote getRemoteConnection();
}
class DataManager implements ConnectionFactory {
boolean local = false;
DataInfo[] data;
//...
public Local getLocalConnection() {
return new LocalMode();
}
public Remote getRemoteConnection() {
return new RemoteMode();
}
public void loadData() {
if(local){
Local conn = getLocalConnection();
data
= conn.loadDB("db.db");
}else {
Remote conn = getRemoteConnection();
conn.connect2WWW("www.some.where.com");
data
= conn.loadDB("db.db");
}
}
// work on data
public void setConnection(boolean b) {
local = b;
}
}
//Use the following Test class to test the above classes
class Test {
public static void main(String[] args) {
DataManager dm = new
DataManager();
DataInfo[] di = null;
String dbFileName = "db.db";
if (args.length == 1) {
//assume local is set to true
dm.setConnection(true);
LocalMode lm = (LocalMode)dm.getLocalConnection();
di = lm.loadDB(dbFileName);
} else {
//Note:
dm.local = false is default setting
RemoteMode
rm = (RemoteMode)dm.getRemoteConnection();
rm.connect2WWW("www.javacamp.org/db/");
di =
rm.loadDB(dbFileName);
}
//use one set of methods to
deal with loaded data.
//You don't need to worry
about connection from this point.
//Like di.find(),
di.search() etc.
}
}
|
|