工厂模式介绍
工厂模式是一种常见的创建型设计模式,它提供了一种创建对象的最佳实践,将对象的创建过程封装到一个单独的类中,从而将对象的使用代码与具体对象的实现代码解耦。
在Java中,工厂模式可以分为三种:简单工厂模式、工厂方法模式和抽象工厂模式。
- 简单工厂模式:简单工厂模式是最基本的工厂模式,它定义了一个工厂类,根据客户端的需求创建不同的产品对象。
- 工厂方法模式:工厂方法模式通过定义一个工厂接口和多个具体的工厂实现类,实现了客户端与具体产品类的解耦。
- 抽象工厂模式:抽象工厂模式是一种针对产品族的创建模式,它通过定义一个抽象工厂接口和多个具体工厂实现类,实现了客户端与具体产品族的解耦。
简单工厂模式
通常由以下三个角色组成:
- 抽象产品类:定义产品的共性,可以是抽象类、接口或者具体类。
- 具体产品类:实现抽象产品类定义的接口,生产出具体的产品。
- 工厂类:负责创建具体产品的实例,它通常包含一个静态的工厂方法,根据传入的参数不同返回不同的具体产品实例。
下面是一个简单工厂模式的示例代码:
// 抽象产品类 interface Product { void show(); } // 具体产品类A class ProductA implements Product { @Override public void show() { System.out.println("ProductA"); } } // 具体产品类B class ProductB implements Product { @Override public void show() { System.out.println("ProductB"); } } // 工厂类 class Factory { public static Product createProduct(String type) { Product product = null; if ("A".equals(type)) { product = new ProductA(); } else if ("B".equals(type)) { product = new ProductB(); } return product; } } // 客户端代码 public class Client { public static void main(String[] args) { Product productA = Factory.createProduct("A"); productA.show(); // ProductA Product productB = Factory.createProduct("B"); productB.show(); // ProductB } }
在这个例子中,抽象产品类 Product 定义了产品的共性,具体产品类 ProductA 和 ProductB 分别实现了 Product 接口,并实现了自己的产品特性。工厂类 Factory 负责创建具体产品的实例,根据传入的参数不同返回不同的具体产品实例。最后,客户端通过调用工厂类的静态方法来获取所需的产品对象。
优点:在于它将对象的创建过程封装在工厂类中,客户端只需要调用工厂类的方法即可获取所需的对象,从而简化了客户端代码的编写。
缺点:在于当需要添加新的产品时,需要修改工厂类的代码,增加了工厂类的复杂度和维护成本。
工厂方法模式
Java工厂模式中的工厂方法模式是一种更为灵活的工厂模式,它将对象的创建过程延迟到子类中进行,从而让客户端代码与具体产品类的实现解耦。
工厂方法模式通常由以下四个角色组成:
- 抽象产品类:定义产品的共性,可以是抽象类、接口或者具体类。
- 具体产品类:实现抽象产品类定义的接口,生产出具体的产品。
- 抽象工厂类:定义工厂方法的接口,用于返回一个具体产品的实例。
- 具体工厂类:实现抽象工厂类定义的工厂方法,返回具体产品的实例。
下面是一个工厂方法模式的示例代码:
// 抽象产品类 interface Product { void show(); } // 具体产品类A class ProductA implements Product { @Override public void show() { System.out.println("ProductA"); } } // 具体产品类B class ProductB implements Product { @Override public void show() { System.out.println("ProductB"); } } // 抽象工厂类 interface Factory { Product createProduct(); } // 具体工厂类A class FactoryA implements Factory { @Override public Product createProduct() { return new ProductA(); } } // 具体工厂类B class FactoryB implements Factory { @Override public Product createProduct() { return new ProductB(); } } // 客户端代码 public class Client { public static void main(String[] args) { Factory factoryA = new FactoryA(); Product productA = factoryA.createProduct(); productA.show(); // ProductA Factory factoryB = new FactoryB(); Product productB = factoryB.createProduct(); productB.show(); // ProductB } }
在这个例子中,抽象产品类 Product 定义了产品的共性,具体产品类 ProductA 和 ProductB 分别实现了 Product 接口,并实现了自己的产品特性。抽象工厂类 Factory 定义了工厂方法的接口,用于返回一个具体产品的实例。具体工厂类 FactoryA 和 FactoryB 实现了 Factory 接口的工厂方法,分别返回 ProductA 和 ProductB 的实例。客户端通过创建具体工厂类的实例来获取所需的产品对象。
优点:在于它将对象的创建过程延迟到具体工厂类中进行,客户端代码只需要和抽象工厂类和抽象产品类打交道,不需要知道具体的产品类是哪个,从而提高了代码的灵活性和可扩展性。
缺点:在于它需要定义抽象工厂类和具体工厂类,增加了类的数量和复杂度。
抽象工厂模式
Java工厂模式中的抽象工厂方法模式是一种更为高级的工厂模式,它通过引入抽象工厂类和抽象产品类的概念,使得工厂可以生产多种不同类型的产品,而不仅仅是一个产品。这种模式通常被用于一组相关或相互依赖的产品族的创建。
抽象工厂方法模式通常由以下四个角色组成:
- 抽象产品类:定义产品的共性,可以是抽象类、接口或者具体类。
- 具体产品类:实现抽象产品类定义的接口,生产出具体的产品。
- 抽象工厂类:定义了一个工厂方法接口,用于返回一组相关或相互依赖的产品。
- 具体工厂类:实现抽象工厂类定义的工厂方法,返回一组相关或相互依赖的产品。
下面是一个抽象工厂方法模式的示例代码:
// 抽象产品类 interface Button { void paint(); } // 具体产品类A class WinButton implements Button { @Override public void paint() { System.out.println("WinButton"); } } // 具体产品类B class MacButton implements Button { @Override public void paint() { System.out.println("MacButton"); } } // 抽象产品类 interface TextField { void paint(); } // 具体产品类A class WinTextField implements TextField { @Override public void paint() { System.out.println("WinTextField"); } } // 具体产品类B class MacTextField implements TextField { @Override public void paint() { System.out.println("MacTextField"); } } // 抽象工厂类 interface GUIFactory { Button createButton(); TextField createTextField(); } // 具体工厂类A class WinGUIFactory implements GUIFactory { @Override public Button createButton() { return new WinButton(); } @Override public TextField createTextField() { return new WinTextField(); } } // 具体工厂类B class MacGUIFactory implements GUIFactory { @Override public Button createButton() { return new MacButton(); } @Override public TextField createTextField() { return new MacTextField(); } } // 客户端代码 public class Client { public static void main(String[] args) { GUIFactory factory = new WinGUIFactory(); Button button = factory.createButton(); TextField textField = factory.createTextField(); button.paint(); // WinButton textField.paint(); // WinTextField factory = new MacGUIFactory(); button = factory.createButton(); textField = factory.createTextField(); button.paint(); // MacButton textField.paint(); // MacTextField } }
优点:
- 客户端代码与具体产品的实现分离,使得客户端代码更容易扩展和维护;
- 提供了一种可以切换产品族的方式,只需要切换具体工厂类即可;
- 遵循开闭原则,新增产品族时只需要增加具体工厂和具体产品类即可,不需要修改原有代码;
- 封装了产品的创建过程,对客户端隐藏了具体产品的实现细节。
缺点:
- 抽象工厂模式增加了系统的抽象性和理解难度,需要理解抽象工厂和具体工厂之间的关系,以及抽象产品和具体产品之间的关系;
- 增加了系统的复杂度和代码量,需要定义大量的接口和抽象类;
- 不容易支持新种类的产品,需要修改抽象工厂接口和所有具体工厂类。
总的来说,抽象工厂方法模式适用于需要创建一系列相关或依赖对象的产品族,并且这些产品族的实现是相对稳定的,不容易扩展新的产品种类,但需要支持新增的产品族。
工厂模式的优点在于它可以降低代码的耦合度,提高代码的可维护性和可扩展性。它还可以隐藏对象创建的细节,使得客户端不需要知道对象的创建过程,只需要通过工厂类获取对象即可。然而,工厂模式也存在一些缺点,比如增加了代码的复杂度和维护成本。