工厂模式介绍
工厂模式是一种常见的创建型设计模式,它提供了一种创建对象的最佳实践,将对象的创建过程封装到一个单独的类中,从而将对象的使用代码与具体对象的实现代码解耦。
在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
}
}
优点:
- 客户端代码与具体产品的实现分离,使得客户端代码更容易扩展和维护;
- 提供了一种可以切换产品族的方式,只需要切换具体工厂类即可;
- 遵循开闭原则,新增产品族时只需要增加具体工厂和具体产品类即可,不需要修改原有代码;
- 封装了产品的创建过程,对客户端隐藏了具体产品的实现细节。
缺点:
- 抽象工厂模式增加了系统的抽象性和理解难度,需要理解抽象工厂和具体工厂之间的关系,以及抽象产品和具体产品之间的关系;
- 增加了系统的复杂度和代码量,需要定义大量的接口和抽象类;
- 不容易支持新种类的产品,需要修改抽象工厂接口和所有具体工厂类。
总的来说,抽象工厂方法模式适用于需要创建一系列相关或依赖对象的产品族,并且这些产品族的实现是相对稳定的,不容易扩展新的产品种类,但需要支持新增的产品族。
工厂模式的优点在于它可以降低代码的耦合度,提高代码的可维护性和可扩展性。它还可以隐藏对象创建的细节,使得客户端不需要知道对象的创建过程,只需要通过工厂类获取对象即可。然而,工厂模式也存在一些缺点,比如增加了代码的复杂度和维护成本。