又一次看到了工厂模式,经过思考之后对工厂模式又有了新的认识。首先举例说下使用工厂模式的好处:现在有一个绘画的类(Print)里面有一个方法print()需要调用RedPen里面的write()方法,初学的时候是这样写的:
RedPen类:
public class RedPen {
public void write(){
System.out.println("use red color writing....");
}
}
Print类:
public class Print {
private RedPen pen;
public Print() {
super();
}
public Print(RedPen pen){
this.pen=pen;
}
public void print(){
pen.write();
}
public static void main(String[] args) {
RedPen redPen=new RedPen();
Print print=new Print(redPen);
print.print();
}
}
这样写似乎没有什么问题,A类需要调用B类的方法,直接New一个B类实例然后调用实例的方法;但是当考虑到程序的变更和问题的扩展时,问题也就出现了,比如现在我使用蓝色的笔(BluePen)来写,对于上面的代码,由于Print类里面构造的时候直接使用了RedPen是的程序的耦合度最高(硬编码耦合),所以当需要修改的时候,要重新修改Print的构造方法改成:
public Print(BluePen pen),但是如果Print依赖的类跟多的话(例如还有画刷,形状等)都采用上述方式的话,当程序需要对功能有所调整的时候需要修改的地方会更多,因此我们需要使用接口:
还是以上述例子,我们如果增加一个Pen的接口,Print类依赖于Pen,有一个用来生产Pen的工厂(PenFactory)扩展之后如下图:
因此Print的代码改为:
public class Print {
private Pen pen;
public Print() {
super();
}
public Print(Pen pen){
this.pen=pen;
}
public void print(){
pen.write();
}
public static void main(String[] args) {
PenFactory factory=new PenFactory();
Print print=new Print(factory.getPen("blue"));
print.print();
}
}
工厂类:
public class PenFactory {
public Pen getPen(String color){
if("red".equals(color))
return new RedPen();
else
return new BluePen();
}
}
显然经过重新设计之后,如果需要改成使用BluePen则只需要修改getPen()的参数即可,也就避免了对Print类作大量修改,这就就简单工厂模式,在简单工厂模式创建产品的方法中,根据传入的参数来判断到底创建哪个产品,如果不需要做判断的话则可以改成工厂模式:
修改之后Print类的代码改成:
public class Print {
private Pen pen;
public Print() {
super();
}
public Print(Pen pen){
this.pen=pen;
}
public void print(){
pen.write();
}
public static void main(String[] args) {
PenFactory factory=new RedPenFactory();
Print print=new Print(factory.getPen());
print.print();
}
}
到此为止我们已经实现了客户端代码(Print)与需要调用类的代码分离,但是Print却与具体的工厂类耦合起来,因此为了进一步达到解耦效果,则可以使用抽象工厂方法:
只需要在上面的基础上增加一个生产工厂的类:
自此就完成了Print与工厂类的完全解耦,在PenFactoryFactory的getPenFactory里面需要根据不同的参数返回不同的工厂实例。其实不管是简单工程模式还是抽象工厂模式都是工厂模式,不过是在不同的类里面判断而已,如果是直接返回被调用的对象,只是简单工厂;如果是返回的工厂对象,则是抽象工厂。