一、简单工厂模式:
简单工厂模式属于创建型模式,又称为静态工厂方法(StaticFactory Method)模式,它不属于23种GOF设计模式之一。
本质:选择创建哪一种产品类的实例。
该模式有以下角色:
(1)工厂(Creator)角色:它是简单工厂模式的核心,主要负责根据传入的参数,动态决定应该创建哪一个产品类的实例。
(2)抽象产品(Product)角色:它一般是具体产品继承的父类或者实现的接口。它负责描述所有实例所共有的公共接口。
(3)具体产品(Concrete Product)角色:工厂类所创建的对象就是此角色的实例。它负责实现具体的生产功能。
/** * 抽象产品接口 */ public interface IProduct { //1.定义实例的公共方法接口 public void producting(); } /** * 具体产品A */ public class ProductA implements IProduct { //2.1 产品A实例的具体实现 public void producting() { System.out.print("Producting ProductA."); } } /** * 具体产品B */public class ProductB implements IProduct { //2.2 产品A实例的具体实现 public void producting() { System.out.print("Producting ProductB."); } } /** * 工厂类:简单工厂模式的核心 */ public class Creator { //3.提供静态的工厂方法给外部客户调用 public static IProduct create(String productName) { //4.根据客户传入的参数选择具体的实现方法。 if(productName.equals("a")) { return new ProductA(); } else if(productName.equals("b")) { return new ProductB(); } else throw new RuntimeException("没有此产品!"); } } /** * 主程序 */public class main { public static void main(String []args) { IProduct product = Creator.create("a"); product.producting(); product = Creator.create("b"); product.producting(); } }运行结果:Producting ProductA. Producting ProductB.
优点:客户可以不必了解产品的具体实现而消费产品,具体的实现选择交由工厂管理,明确了各自的职责和权利,有利于整个软件体系结构的优化。
缺点:由于工厂类集中了所有实例的创建逻辑,违反了高内聚原则及开闭原则,当需要添加类时,就需要修改工厂类;而且当具体产品类不断增多时,各种逻辑的判断和选择可能会交织在一起;这些都给系统的维护和扩展带来的问题。
二、工厂方法模式:
工厂方法模式又称为多态性工厂模式。工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
该模式有以下角色:
(1)抽象工厂(Creator)角色:它是工厂方法模式的核心,它主要负责提供具体工厂类实现的接口。
(2)具体工厂(Concrete Creator)角色:实现抽象工厂接口的具体工厂类,它主要负责提供给客户调用来创建具体产品实例。
(3)抽象产品(Product)角色:它一般是具体产品继承的父类或者实现的接口。它负责描述所有实例所共有的公共接口。
(4)具体产品(Concrete Product)角色:工厂类所创建的对象就是此角色的实例。它负责实现具体的生产功能。
示例:
/** * 抽象产品接口 */ public interface IProduct { //1.定义实例的公共方法接口 public void producting(); } /** * 具体产品A */ public class ProductA implements IProduct { //2.1 产品A实例的具体实现 public void producting() { System.out.print("producting ProductA."); } } /** * 具体产品B */ public class ProductB implements IProduct { //2.2 产品B实例的具体实现 public void producting() { System.out.print("product ProductB."); } } /** * 抽象工厂 */ public interface Creator { //3.定义具体工厂类实现的方法接口 public IProduct create(); } /** * 具体工厂类A:用于生产产品A */ public class ProductACreator implements Creator { //4.1 提供客户调用的工厂方法 public IProduct create() { return new ProductA(); } } /** * 具体工厂类B:用于生产产品B */ public class ProductBCreator implements Creator { //4.2 提供客户调用的工厂方法 public IProduct create() { return new ProductB(); } } /** * 主程序 */ public class main { public static void main(String []args) { Creator productACreator = new ProductACreator(); //实例化工厂A IProduct productA = productACreator.create(); productA.producting(); Creator productBCreator = new ProductBCreator(); //实例化工厂B IProduct productB = productBCreator.create(); productB.producting(); } }
运行结果:producting ProductA。 product ProductB
优点:克服了简单工厂模式违反开闭原则和低内聚的缺点,把具体的创建产品实例的工作交给工厂子类实现,当我们需要添加新产品时,只需要添加一个具体的产品类和一个具体的工厂类,原有的工厂对象不需要进行修改。
三、抽象工厂模式:
本质:选择产品簇的实现。
该模式主要有以下角色:
(1)抽象工厂(AbstractFactory)角色:它是抽象工厂模式的核心,它主要负责提供具体工厂类实现的接口。
(2)具体工厂(Concrete Creator)角色:实现抽象工厂接口的具体工厂类,它主要负责提供给客户调用来创建具体产品实例。
(3)抽象产品(Product)角色:它一般是具体产品继承的父类或者实现的接口。它负责描述所有实例所共有的公共接口。
(4)具体产品(Concrete Product)角色:工厂类所创建的对象就是此角色的实例。它负责实现具体的生产功能。
示例:/** *抽象产品A类 */ public interface IProductA { //1.1 定义产品A的方法接口 public void printA(); } /** *抽象产品B类 */ public interface IProductB { //1.2 定义产品B的方法接口 public void printB(); } /** *具体产品A1类 */ public class ProductA1 implements IProductA { //2.1.1 产品A1的具体实现 public void printA() { System.out.print("This is productA1."); } } /** *具体产品A2类 */ public class ProductA2 implements IProductA { //2.1.2 产品A1的具体实现 public void printA() { System.out.print("This is productA2."); } } /** *具体产品B1类 */ public class ProductB1 implements IProductB { //2.2.1 产品B1的具体实现 public void printB() { System.out.print("This is productB1."); } } /** *具体产品B2类 */ public class ProductB2 implements IProductB { //2.2.2 产品B2的具体实现 public void printB() { System.out.print("This is productB2."); } } /** * 抽象工厂 */ public interface Creator { //3. 提供客户调用的工厂方法 public IProductA createProductA(); public IProductB createProductB(); } /** * 具体工厂类:专门生产型号1的产品 */ public class Creator1 implements Creator { //4.1 具体创建实例的方法 public IProductA createProductA() { return new ProductA1(); } public IProductB createProductB() { return new ProductB1(); } } /** * 具体工厂类:专门生产型号2的产品 */ public class Creator2 implements Creator { //4.2 具体创建实例的方法 public IProductA createProductA() { return new ProductA2(); } public IProductB createProductB() { return new ProductB2(); } } /** *主程序 */ public class main { public static void main(String []args) { Creator creator1 = new Creator1(); //实例化型号1的工厂 IProductA productA1 = creator1.createProductA(); //生产类型A、型号1的产品A1 productA1.printA(); creator1 = new Creator1(); //实例化型号1的工厂 IProductB productB1 = creator1.createProductB(); //生产类型B、型号1的产品B1 productB1.printB(); Creator creator2 = new Creator2(); //实例化型号2的工厂 productA1 = creator2.createProductA(); //生产类型A、型号2的产品A2 productA1.printA(); creator2 = new Creator2(); productB1 = creator2.createProductB(); productB1.printB(); } }运行结果:This is productA1. This is productB1. This is productA2. This is productB2.
Note:我们先了解下以下两个词概念:产品类和产品类族。
(1)产品类:如上示例中,ProductA和ProductB属于不同的产品类。
(2)产品类族:如上示例中,ProductA1和ProductA2、ProductB1和ProductB2分别属于同一产品类族。
当我们需要添加一个产品类族时,如ProductA3,我们只需要增加一个具体的产品类ProductA3和一个具体的工厂类Creator3,不必对其它的类或接口进行修改,所以是遵循开闭原则的。而当我们需要添加一个产品类时,如ProductC,我们不仅需要添加一个抽象产品类IProductC、具体产品类ProductC1,还需要对抽象工厂Creator、具体工厂Creator1、Creator2进行修改添加,所以对于抽象工厂模式添加一个产品类是违反了开闭原则的。
优点:分离接口和实现;使得切换产品簇变得容易。
缺点:不容易扩展新的产品;容易造成类层次复杂。