工厂模式
- 工厂模式分类
简单工厂模式是类的创建模式,又叫静态工厂方法(static factory method)模式。简单工厂模式就是由一个工厂类根据传入的参数决定创建哪一种的产品类。
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据LSP原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。
- 工厂模式的应用
应用场景:现在以一个生活中很常见的例子作为举例,说明各个工厂模式的应用。一般果园中会有各种各样的水果,每类水果都配有一个园丁。
简单工厂模式:起初果园规模不大,所有水果有一个园丁管理。
抽象产品Fruit:
1 public interface Fruit { 2 void fruitType(); 3 }
具体产品:
1 public class Apple implements Fruit { 2 @Override 3 public void fruitType() { 4 System.out.println("这个是苹果"); 5 } 6 7 } 8 public class Grape implements Fruit{ 9 @Override 10 public void fruitType() { 11 System.out.println("这个是葡萄"); 12 } 13 }
工厂:
1 public class FruitFactory { 2 public static Fruit factory(String fruit){ 3 if("apple".equalsIgnoreCase(fruit)){ 4 return new Apple(); 5 }else if("grape".equalsIgnoreCase(fruit)){ 6 return new Grape(); 7 }else{ 8 return null; 9 } 10 } 11 }
简单工厂模式的优点:由工厂实现业务逻辑来判断产品的创建时机,而客户端只需要向工厂提供需要的产品,然后等待工厂返回使用即可。
简单工厂模式的缺点:将所有的业务逻辑放在一个工厂方法中,当这个工厂方法不能使用时整个系统将崩溃,同时如果需要扩展新的产品,需要重新修改工厂方法,可扩展性比较差。
工厂方法模式:随着果园规模的扩大,一个园丁管理起来比较费时,于是引入了多个园丁。
产品接口和产品实现如上:
工厂接口:
1 public interface Fruit { 2 void fruitType(); 3 }
具体接口:
1 public class AppleFactory implements Factory{ 2 @Override 3 public Fruit createFactory() { 4 // TODO Auto-generated method stub 5 return new Apple(); 6 } 7 } 8 public class GrapeFactory implements Factory{ 9 @Override 10 public Fruit createFactory() { 11 // TODO Auto-generated method stub 12 return new Grape(); 13 } 14 }
可以看出,工厂方法模式是简单工厂模式的推广,对于新增加的产品类型只要集成工厂接口,继续分配相应的园丁或者在现有工厂实现的基础上进行修改即可。
抽象工厂模式:当果园规模又进行了扩大,苹果、葡萄种类也进行了扩展,产生了一个产品族,需要更加细化管理。
抽象工厂:
1 public interface Factory1 { 2 Fruit createFactory1(); 3 Fruit createFactory2(); 4 }
抽象工厂模式实现:
1 public class AppleFactory1 implements Factory1{ 2 @Override 3 public Fruit createFactory1() { 4 // TODO Auto-generated method stub 5 return new Apple1(); 6 } 7 @Override 8 public Fruit createFactory2() { 9 // TODO Auto-generated method stub 10 return new Apple2(); 11 } 12 13 }
抽象工厂模式优点: 抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
抽象工厂模式缺点:产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
- 总结
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。
所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。