工厂模式可以分为三类: 简单工厂模式、工厂方法模式、抽象工厂模式。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
使用工厂模式的好处:工厂模式是用工厂方法代替new操作的一种模式,轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程。工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性、解耦的目的。
一.特点
简单工厂模式:专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式。它的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类的实例。简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。
工厂方法模式:工厂方法是粒度很小的设计模式,因为模式的表现只是一个抽象的方法。提前定义用于创建对象的接口,让子类(具体工厂)决定实例化具体的某一个类,即在工厂和产品中间增加接口(抽象工厂),工厂不再负责产品的创建,由接口针对不同条件返回具体的类实例,由具体类实例(具体工厂)去实现。工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现ocp,实现了可扩展。其次实现更复杂的层次结构,可以应用于产品结果复杂的场合。工厂方法模式是对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
抽象工厂模式:抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。它有多个抽象产品类,每个抽象产品类可以派生出多个具体产品类,一个抽象工厂类,可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例。每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结果。
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
二.优点
简单工厂模式:工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。简单工厂模式通过这种做法实现了对责任的分割。简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。通过它,外界可以从直接创建具体产品对象的尴尬局面中摆脱出来。外界与具体类隔离开来,偶合性低。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
工厂方法模式:工厂方法模式是为了克服简单工厂模式的缺点(主要是为了满足OCP)而设计出来的。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。工厂方法模式完全满足OCP,即它有非常良好的扩展性。
抽象工厂模式:抽象工厂模式主要在于应对“新系列”的需求变化。分离了具体的类,抽象工厂模式帮助你控制一个应用创建的对象的类,因为一个工厂封装创建产品对象的责任和过程。它将客户和类的实现分离,客户通过他们的抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。它使得易于交换产品系列。一个具体工厂类在一个应用中仅出现一次——即在它初始化的时候。这使得改变一个应用的具体工厂变得很容易。它只需改变具体的工厂即可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。它有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。抽象工厂模式有助于这样的团队的分工,降低了模块间的耦合性,提高了团队开发效率。
三.缺点
简单工厂模式:当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦增加产品或者删除产品,整个系统都要受到影响。系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了"开放–封闭"原则(OCP).另外,简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。
工厂方法模式:假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦。比如说,每增加一个产品,相应的也要增加一个子工厂,会加大了额外的开发量。
抽象工厂模式:抽象工厂模式在于难于应付“新对象”的需求变动。难以支持新种类的产品。难以扩展抽象工厂以生产新种类的产品。这是因为抽象工厂几乎确定了可以被创建的产品集合,支持新种类的产品就需要扩展该工厂接口,这将涉及抽象工厂类及其所有子类的改变。
四.适用范围
简单工厂模式:工厂类负责创建的对象比较少,客户只知道传入了工厂类的参数,对于始何创建对象(逻辑)不关心。
工厂方法模式:当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时,当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候,可以使用工厂方法,支持多扩展少修改的OCP原则。
抽象工厂模式:一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。这个系统有多于一个的产品族,而系统只消费其中某一产品族。同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
代码实现:
创建一个 Shape 接口和实现 Shape 接口的实体类。下一步是定义工厂类 ShapeFactory。FactoryPatternDemo,演示类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。

//将工厂方法中的判断,提取到枚举中, 工厂方法使用反射创建对象。
public interface Shape { void draw();}
public class Circle implements Shape {
@Override public void draw() {
System.out.println("圆形");
}
}
public class Rectangle implements Shape {
@Override public void draw() {
System.out.println("矩形");
}
}
public class Square implements Shape {
@Override public void draw() {
System.out.println("正方形");
}
}
public enum ShapeTypeEnum {
CIRCLE("com.example.factorymethods.Circle"),
SQUARE("com.example.factorymethods.Square"),
RECTANGLE("com.example.factorymethods.Rectangle");
private String className;
ShapeTypeEnum(String className) {
this.className = className;
}
public String getClassName() {
return className;
}
}
public class ShapeFactory {
private ShapeFactory(){}
/**
*
* 创建不同的图形实例
* @param shapeTypeEnum
* @return
*/
public static Shape createShape(ShapeTypeEnum shapeTypeEnum){
Shape shape = null;
String className = shapeTypeEnum.getClassName();
try {
Class clazz = Class.forName(className);
shape = (Shape)clazz.newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return shape;
}
}
public class FactoryMethodsDemo {
public static void main(String[] args) {
ShapeFactory.createShape(ShapeTypeEnum.CIRCLE).draw();
ShapeFactory.createShape(ShapeTypeEnum.SQUARE).draw();
ShapeFactory.createShape(ShapeTypeEnum.RECTANGLE).draw();
}
}
1238



被折叠的 条评论
为什么被折叠?



