利用工厂模式可以将对象的创建过程和使用进行分离(也就是解藕),从而促进了对象创建过程的封装。
在回顾前一篇随记初学Java设计模式随记 -- 工厂模式(Factory Pattern)中例子1和例子4时,可能会有这么几个的疑问:
为什么要有一个抽象产品类?
为什么工厂方法返回的是一个抽象产品类类型?
为什么在客户端调用时,也是通过抽象产品类来定义要产品类对象?
这就是工厂模式中产品类的多态性。
由于具体产品类继承(或实现)自抽象产品类,客户端就不必知道具体产品的真实类型,一样可以得到自己想要的产品。
这种多态性,促进了工厂模式的封装效果,工厂类将创建哪种产品,以及如何创建产品对象的细节完全封装了起来。
通过现实世界来理解多态性:
顾客A本来想买奥迪A6,正好厂家生产了新款的奥迪A8,奥迪A6停产了,而且价格差不多。于是,顾客A就更改了订单,买奥迪A8了。
那么,在例子1的基础上,我们只需要新添加一个具体产品类AudiA8Car,再修改工厂类CarFactory就可以了。
例子5:
奥迪A8(具体产品角色):
添加了一个新的具体产品类,一汽大众生产的新款汽车。
/*
* 奥迪A8,是一汽大众生产的一款汽车 (具体产品类)
*/
public class AudiA8Car extends Car {
public AudiA8Car(){
this.name = "奥迪A8";
}
public String toString(){
return "一辆"+ this.name;
}
}
一汽大众(工厂角色):
修改了静态的工厂方法manufactureCar(),原来返回的是AudiA6Car的对象,现在返回的是AudiA8Car的对象
/*
* 生产汽车的工厂,一汽大众 (工厂类)
*/
public class CarFactory {
/*
* 生产汽车(通过一个静态方法来得到一辆汽车的对象)
*/
public static Car manufactureCar(){
// 奥迪A6停产了
// return new AudiA6Car();
// 新款汽车奥迪A8
return new AudiA8Car();
}
}
汽车(抽象产品类角色):
与例子1相同,没有做任何变化。
/*
* 奥迪A6,是一汽大众生产的一款汽车 (具体产品类)
*/
public class AudiA6Car extends Car {
public AudiA6Car(){
this.name = "奥迪A6";
}
public String toString(){
return "一辆"+ this.name;
}
}
买这款奥迪A6汽车的顾客A(客户端):
也与例子1 相同,没有任何变化。
/*
* 购买汽车的顾客A(客户端)
*/
public class CustomerA {
public static void main(String[] args){
// 通过汽车工厂来制造出了一辆汽车
Car myCar = CarFactory.manufactureCar();
System.out.println("一辆汽车被造好,并且出厂了。");
// 顾客得到了一辆汽车,十分的高兴
System.out.println("我终于买了"+myCar+"。真是太好了!");
}
}
运行结果:
一辆汽车被造好,并且出厂了。
我终于买了一辆奥迪A8。真是太好了!
根据上面的运行结果,可以看到这种多态性带来的好处:
提高了封装效果,客户端不做任何改动,就实现了需求的变化。
总的来说,
工厂模式通过解耦和多态性,使得对象的创建和使用进行分离,并封装了复杂的对象创建过程,统一了对象的使用方式。
有利于代码的维护和修改,使代码更容易适应需求的变化,并降低了这些变化对系统的影响。