工厂模式,属于创建型模式,我们不在自己创建对象,而是交由工厂来创建。
这样的好处是,我们使用工厂来封装对对象的需求,否则,你可能写一大堆if else来判断,然后新增一个对象的话,又得改这段代码。
简单的工厂模式就是,调用者对工厂说,给我一个A零件,工厂就创建一个A零件,调用者说,给我一个C零件,工厂就创建一个C零件。就这么简单。
上图(借用别人的,学习目的:)):
[img]http://dl.iteye.com/upload/attachment/0065/8765/c879d240-57df-34dd-9e57-a84b7a09b546.gif[/img]
这种简单的代码更清晰:
其实简单工厂模式看上不这么的。还是很废话。如果新增产品C,D,E呢?
一样需要修改工厂。这时用户使用的工厂还是需要改动。这里我们可以用很多方法,例如使用反射,或者使用动态注册(工厂能生产的产品都要在工厂中注册,使用一个key/value来实现,key为名称,value就是创建对象的具体方法或实例)
这时,问题还没有完,工厂的能力是无限的,这时工厂需要生产与上面的产品参数不一样的产品了,这怎么办? 其实上面的工厂是一个很不好的例子,因为这样我们又得增加if else语句了。这下我们发现,其实工厂也是会改变的。那么就把改变的东西封装起来吧。
于是出现了抽象工厂。我们的抽象工厂与抽象产品做接口,具体的东西,就由下面的实现类去折腾吧。
[img]http://dl.iteye.com/upload/attachment/0065/8753/32f24ce6-ff42-374f-b6a0-12933f8bb8d6.gif[/img]
这里,我们把上面的例子改改,假设产品A与产品B不是同一类产品了,他们的创建方法不一样了,A需要增加一个序列号。
而此时,我们的工厂也变成抽象的了。
这里对工厂使用了单例模式。怎么样,抽象工厂代码更为简洁吧,实际中,可能会拥有很多的产品与工厂,这就需要权衡抽象工厂和简单工厂了。
总之,设计模式中,粒度问题是一个关键问题,如何衡量系统的类的粒度,和系统自身息息相关。如果能准确把握,就能很优雅的解决问题。
这样的好处是,我们使用工厂来封装对对象的需求,否则,你可能写一大堆if else来判断,然后新增一个对象的话,又得改这段代码。
简单的工厂模式就是,调用者对工厂说,给我一个A零件,工厂就创建一个A零件,调用者说,给我一个C零件,工厂就创建一个C零件。就这么简单。
上图(借用别人的,学习目的:)):
[img]http://dl.iteye.com/upload/attachment/0065/8765/c879d240-57df-34dd-9e57-a84b7a09b546.gif[/img]
这种简单的代码更清晰:
#产品接口
public interface Product {
public String getName();
}
#产品A
public class ProductA implements Product{
@Override
public String getName() {
// TODO Auto-generated method stub
return "A";
}
}
#产品B
public class ProductB implements Product {
@Override
public String getName() {
// TODO Auto-generated method stub
return "B";
}
}
#工厂
public class ProductFactory {
public static Product getProduct(String name){
if("A".equals(name)){
return new ProductA();
}else if("B".equals(name)){
return new ProductB();
}else return null;
}
}
其实简单工厂模式看上不这么的。还是很废话。如果新增产品C,D,E呢?
一样需要修改工厂。这时用户使用的工厂还是需要改动。这里我们可以用很多方法,例如使用反射,或者使用动态注册(工厂能生产的产品都要在工厂中注册,使用一个key/value来实现,key为名称,value就是创建对象的具体方法或实例)
这时,问题还没有完,工厂的能力是无限的,这时工厂需要生产与上面的产品参数不一样的产品了,这怎么办? 其实上面的工厂是一个很不好的例子,因为这样我们又得增加if else语句了。这下我们发现,其实工厂也是会改变的。那么就把改变的东西封装起来吧。
于是出现了抽象工厂。我们的抽象工厂与抽象产品做接口,具体的东西,就由下面的实现类去折腾吧。
[img]http://dl.iteye.com/upload/attachment/0065/8753/32f24ce6-ff42-374f-b6a0-12933f8bb8d6.gif[/img]
这里,我们把上面的例子改改,假设产品A与产品B不是同一类产品了,他们的创建方法不一样了,A需要增加一个序列号。
public class ProductA implements Product{
private long sero ;
@Override
public String getName() {
// TODO Auto-generated method stub
return "A";
}
public void setSero(long sero){
this.sero = sero;
}
}
而此时,我们的工厂也变成抽象的了。
public interface AbstractFactory {
public Product getProduct();
}
#factory a create productA
public class FactoryA implements AbstractFactory {
private static FactoryA _instance;
private FactoryA(){}
public static FactoryA getInstance(){
if(_instance==null){
_instance = new FactoryA();
}
return _instance;
}
@Override
public Product getProduct() {
// TODO Auto-generated method stub
ProductA p = new ProductA();
p.setSero(10000L);
return p;
}
}
//factory B create ProductB类似,略去
//使用
public static void main(String[] args) {
// TODO Auto-generated method stub
Product p = FactoryA.getInstance().getProduct();
System.out.println(p.getName());
}
这里对工厂使用了单例模式。怎么样,抽象工厂代码更为简洁吧,实际中,可能会拥有很多的产品与工厂,这就需要权衡抽象工厂和简单工厂了。
总之,设计模式中,粒度问题是一个关键问题,如何衡量系统的类的粒度,和系统自身息息相关。如果能准确把握,就能很优雅的解决问题。