从简单工厂模式到抽象工厂模式的思考

又一次看到了工厂模式,经过思考之后对工厂模式又有了新的认识。首先举例说下使用工厂模式的好处:现在有一个绘画的类(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里面需要根据不同的参数返回不同的工厂实例。其实不管是简单工程模式还是抽象工厂模式都是工厂模式,不过是在不同的类里面判断而已,如果是直接返回被调用的对象,只是简单工厂;如果是返回的工厂对象,则是抽象工厂。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章