工厂方法模式,单件模式与抽象工厂模式。
虽然抽象工厂模式中,也有工厂,但这里的工厂一般产生的一族不同的对象。而工厂模式则是为产生一族对象,这些对象它们通常具有相同的基类接口。实际上,抽象工厂是在工厂级别上进行了抽象,而工厂模式则是在类创建的级别上进行了抽象。它们之间也是相互联系的,比如抽象工厂中的工厂类一般采用单件模式实现,而工厂方法用可以用来产生抽象工厂里不同的工厂类。
各个具体工厂与抽象工厂之间的关系,就像工厂模式中各个类与抽象基类之间的关系。
工厂方法模式
通过调用不同的方法返回需要的类,而不是去实例化具体的类。 对实例创建进行了包装。 工厂方法是一组方法, 他们针对不同条件返回不同的类实例,这些类一般有共同的父类。工厂方法模式实施一种按需分配的策略, 即传入参数进行选择, 工厂方法根据参数进行选择,返回具体的实例。
java:
根据InputStream is来选择要创建的ImageReader
public class ImageReaderFactory {
public static ImageReader getImageReader( InputStream is ) {
int imageType = figureOutImageType( is );
switch( imageType ) {
case ImageReaderFactory.GIF:
return new GifReader( is );
case ImageReaderFactory.JPEG:
return new JpegReader( is );
// etc.
}
}
}
ImageReader接口和它的两个子类模板
public interface ImageReader {
public DecodedImage getDecodedImage();
}
public class GifReader implements ImageReader {
public GifReader( InputStream in ) {
// ….
}
public class JpegReader implements ImageReader {
//….
}
单件模式
保证,该类的对象只有一个实例存在。实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
java实现
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
// Private constructor suppresses
// default public constructor
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
c++实现
这个例子对多线程的情况并不是安全的:
template<typename T> class Singleton {
public:
static T& Instance()
{
static T theSingleInstance; //assumes T has a default constructor
return theSingleInstance;
}
};
class OnlyOne : public Singleton<OnlyOne> {
private:
OnlyOne(){}
OnlyOne(OnlyOne& rhs){}
friend class Singleton<OnlyOne>;
//..rest of interface defined here
};
抽象工厂
抽象工厂实际上,是一批工厂族的接口。当需要某个系列的时候,可以从抽象工厂中选择创建一个具体的工厂类。抽象工厂适合在现有的一些工厂类型中切换,但是如果要增加一个新的工厂类型,则需要做出比较大的改动
假设我们有两种产品接口 Button 和 Border ,每一种产品都支持多种系列,比如 Mac 系列和Windows 系列。这样每个系列的产品分别是 MacButton, WinButton, MacBorder, WinBorder 。为了可以在运行时刻创建一个系列的产品族,我们可以为每个系列的产品族建立一个工厂 MacFactory 和 WinFactory 。每个工厂都有两个方法CreateButton 和 CreateBorder 并返回对应的产品,可以将这两个方法抽象成一个接口 AbstractFactory 。这样在运行时刻我们可以选择创建需要的产品系列。
那么产品结构就是这样的
class Button; // Abstract Class
class MacButton: public Button {};
class WinButton: public Button {};
class Border; // Abstract Class
class MacBorder: public Border {};
class WinBorder: public Border {};
对应的工厂是这样的
class AbstractFactory {
public:
virtual Button* CreateButton() =0;
virtual Border* CreateBorder() =0;
};
class MacFactory: public AbstractFactory {
public:
MacButton* CreateButton() { return new MacButton; }
MacBorder* CreateBorder() { return new MacBorder; }
};
class WinFactory: public AbstractFactory {
public:
WinButton* CreateButton() { return new WinButton; }
WinBorder* CreateBorder() { return new WinBorder; }
};
那么客户可以根据需要选择Mac风格或者Win风格的Button
AbstractFactory* fac;
switch (style) {
case MAC:
fac = new MacFactory;
break;
case WIN:
fac = new WinFactory;
break;
}
Button* button = fac->CreateButton();
Border* border = fac->CreateBorder();
这个部分 实际上就可以使用工厂方法来产生,AbstractFactory。