注: 1)Product A和Product B具有相同的父类,但是具有不同的实现。
2)Creator可根据不同的输入变量决定所需实例化的类。
i. 将方法与处理分离,处理可以独立于方法名而存在。
i. 当一个类不能静态确定她所必须创建的对象的类的时候。(Client可以在运行时,通过Creator来获得所需的Product子类)
ii. 当一个类希望由她的子类来实现她所定义的行为的时候。(由Product A和Product B来定义Product的行为)
iii. 当你希望将创建类的信息局部化的时候。(可以把if-else的选择代码,放到Creator内)
public interface Product {
public void method();
}
public class ProductA implements Product{
public void method(){
do some thing;
}
}
public class ProductB implements Product{
public void method(){
do another thing;
}
}
public class Creator{
public Product getProduct(){
if(some condition){
return new ProductA();
}else{
return new ProductB();
}
}
}
i. 可根据输入的条件,在一堆相似的类当中选择其中的一个并进行实例化。
ii. 现在的趋势是一个Creator只负责实例化一个Product,一方面可以让Creator的代码变得短小,另一方面可避免if-else结构。
注: 1)Factory和ProductA,ProductB形成一个层次。
2)FactoryA和FactoryB继承Factory,并负责实例化ProductA和ProductB的子类。
i. 可以通过更换Concrete Factory而实现对整个Product的替换。
i. 一个系统要独立于她的产品的创建,组合和表示。(例如,Java中的UI,Client的LookAndFeel可以独立于控件的创建和表示。)
ii. 一个系统要由多个产品系列中的一个来配置。(一个系统可以由Product A1和Product B1或者Product A2和Product B2来配置)
iii. 当你要强调一个系列相关的产品对象的设计以便进行联合使用时。
iv. 当你提供一个产品类库,而只想显示他们的接口而不是实现时(Client通过Factory只看到了Product A和Product B的接口)
public interface Factory{
public ProductA getProductA();
public ProductB getProductB();
}
public class FactoryA implements Factory{
public Po rductA getProductA(){
return new ProductA1();
}
public ProductB getProductB(){
return new ProductB1();
}
}
public class FactoryB implements Factory{
public Po rductA getProductA(){
return new ProductA2();
}
public ProductB getProductB(){
return new ProductB2();
}
}
public interface ProductA{
}
public class ProductA1 implements ProductA{}
public class ProductA2 implements ProductA{}
public interface ProductB{
}
public class ProductB1 implements ProductB{}
public class ProductB2 implements ProductB{}
i. 与Factory类似,但返回的是一组类而不仅是一个类,从某种程度上说是Factory模式在更高层次上的抽象。
ii. AbstractFactory将产品对象的创建延迟到他的实现类当中(FactoryA和FactoryB)
iii. AbstractFactory模式帮助你控制一个应用创建的对象的类。因为一个工厂封装创建产品对象的责任和过程。她将客户与类的实现分离。客户通过他们的抽象接口操纵实例。类名也在具体工厂的实现中被分离,他们并不出现在客户代码中。
iv. 难以生产新种类的产品,因为AbstractFactory接口限制了可以被创建的产品集合,支持新种类的产品需要扩展工厂接口。
v. Swing中的UI部分,是Abstract Factory的一个应用。
3. Singleton模式
注:全局只有一个Singleton实例。
i. 可对唯一的实例进行受控访问。
ii. 缩小名空间。(是对全局变量的一种替代,避免了那些存储唯一实例的全局变量污染名空间)
iii. 允许可变数目的实例。(在Singleton类内可进行实例计数)
i. 当类只能有一个实例而且客户可以从一个众所周知的访问点访问她时。
ii. 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。(只要修改Singleton中的方法即可)
i. 抛出异常:
public class Singleton{
static Boolean fla g = false;
public Singleton() throws SingletonException{
if(!flag){
fla g = true;
}else{
throw new SingletonException();
}
}
}
优点:可以子类化。
缺点:不能共享实例,客户端要捕捉异常。
ii. 静态类:
public class Singleton{
public static methodA(){}
public static methodB(){}
}
优点:不用处理异常。
缺点:如果要将这个类改为可支持多实例访问时,比较麻烦。
iii. 静态方法:
public class Singleton{
private static Singleton instance = null;
private Singleton(){…}
public static Singleton getSingleton(){
if(instance == null)
instance = new Singleton();
return instance;
}
}
优点:不用担心当需要多个实例时会抛出异常,可以很容易支持共享实例和实例化多个实例。
缺点:不能子类化。(因为构造函数是私有的)
i. 保证整个系统有且只有一个实例,并且在系统的各个部分都能对该实例进行访问。
ii. Java当中的Math类是一个Singleton的应用。
4. Builder模式
注: 1)与Factory很相似,把对象的实例化外托到Builder中。
2)根据Director所识别出的标记,Builder可以一步步的构造出一个复杂的对象。
3)与Factory相比,程序员对构造过程可以有更多的参与。
i. 程序员能更大的参与其中,构造出更复杂的对象。(在ConcreteBuilder中定义复杂的实现逻辑)
ii. 将一个复杂对象的构建与他的表示分离,使得同样的构建过程产生不同的表示。(即Director和Builder可以分开改变)
i. 当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时。
ii. 当构造过程必须允许被构造的对象有不同的表示时。
public class Director{
private Builder builder = new Builder();
public void build(){
if(condition a){
builder.buildPardA();
}else if(condition b){
builder.buildPardB();
}else{
builder.buildPardC();
}
}
}
public interface Builder{
public void buildPartA();
public void buildPartB();
public void buildPartC();
}
public class ConcreteBuilder implements Builder{
public void buildPartA(){…}
public void buildPartB(){…}
public void buildPartC(){…}
}
i. 她首先假定一个对象需要由其他的多个对象组成,但这些对象怎么进行组合和布局就要根据输入(condition)了。
ii. Director通过产生事件,Builder通过对事件作出响应,从而一步步的定制产品的构造。这就是所谓的构建与表示分离,通过Director产生或指明构建的步骤,而通过Builder进行具体的表示。
iii. XML文件的解析是Builder模式的一个应用。Parser是Director,DefaultHandler是Builder,通过扩展DefaultHandler我们可以对XML文件的解析结果进行定制。
iv. XSLT也是一个Builder模式的应用。通过提供不同的XSL文件(相当于Builder),即可以从同一个XML文件得到不同的输出,而对XML文件进行分析的Parser就相当于Director。