1.什么是工厂模式?以及工厂模式的几个组成部分。
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
主要有以下的几个组成部分:
1.抽象产品
2.具体产品(继承自抽象产品)
3.抽象工厂(负责提供产生对象的接口方法)
4.具体工厂(实现产生对象的方法,生产某种具体的对象产品)
2.层层递进,探究工厂模式的优点与缺点
现在引入这样一个场景:我们需要一个咖啡点餐系统,要求根据客户的需求提供不同的咖啡品种。
- 初步分析,我们需要一个抽象咖啡类,当我们需要引入新的咖啡品种时,只需要继承即可。CoffeeStore里面传入类型参数,根据参数去获取对应类型的咖啡。
UML类图如图所示:
创建抽象coffee和Concrete coffee的代码简单,这里不贴出来。主要来看CoffeeStore类是如何根据需求创建Coffee的。
class CofferStore{
public Coffee orderCoffee(String type){
Coffee coffee=null;
if("AmericanCoffee".equals(type)){
coffee=new AmericanCoffee();
}else if("LatterCoffee".equals(type)){
coffee=new LatterCoffee();
}else{
throw new RuntimeException("没有找到需要的咖啡种类!");
}
coffee.addSuger();
coffee.addMilk();
return coffee;
}
}
根据传入的coffee type创建对应的咖啡种类。那么我们思考这种做法有什么问题存在?
- 对于type的精确性有着严格的要求,客户输入type时要求完全与现有的类型匹配。
- 当我们增加咖啡的品种时,就需要修改if-else语句块的代码来新增一个判断分支,就无疑违背了close-open principle。
针对上述的问题,引入简单工厂模式(Simple Factory)
- 简单工厂模式的思想是这样的,将coffee的创建放在工厂当中,CoffeeStore只需要创建好工厂,把参数传递给工厂进而创建对象。
UML图:
同样贴出关键部分的代码:
class CofferStore{
public Coffee orderCoffee(String type){
SimpleCoffeeFactory factory=new SimpleCoffeeFactory();
Coffee coffee=factory.createCoffee(type);
coffee.addSuger();
coffee.addMilk();
return coffee;
}
}
class SimpleCoffeeFactory{
public Coffee createCoffee(String type){
Coffee coffee=null;
if("AmericanCoffee".equals(type)){
coffee=new AmericanCoffee();
}else if("LatterCoffee".equals(type)){
coffee=new LatterCoffee();
}else{
throw new RuntimeException("没有找到需要的咖啡种类!");
}
return coffee;
}
}
这种做法把耦合的问题抛给了后台工厂,但是当我们需要新增咖啡的种类时,仍然需要去修改工厂部分的代码,把问题延后了,但是没有解决。
- 工厂模式
工厂模式的思想是这样的:创建一个抽象的工厂类提供创建对象的抽象方法,针对不同的产品对象,创建对应的工厂类完成创建。这样一来,就解决了耦合问题。
UML类图:
abstract class SimpleCoffeeFactory{
public abstract Coffee createCoffee();
}
class AmericanFactory{
public Coffee createCoffee(){
return new AmericanCoffee();
}
}
class LatterFactory{
public Coffee createCoffee(){
return new LatterCoffee();
}
}
class CoffeeStore{
private SimpleCoffeeFactory factory;
public void setFactory(SimpleCoffeeFactory factory){
this.factory=factory;
}
public Coffee orderCoffee(){
return factory.createCoffee();
}
}
public class Main{
public static void main(String []args){
SimpleCoffeeFactory factory=new AmericanFactory();
CoffeeStore store=new CoffeeStore();
store.setFactory(factory);
store.orderCoffee();
}
}
我们需要不同的产品时,只需要设置不同的产品工厂即可。需要添加新的产品时,只需要继承SimpleCoffeeFactory类即可,无需修改之前的代码。缺点是当我们增加新产品的时候,需要增加类,会使整个程序的结构更加复杂化。