1.设计模式的分类
- 创建型模式(五种):工厂方法模式、单例模式、抽象工厂模式、原型模式、建造者模式。
- 结构型模式(七种):适配器模式、代理模式、装饰器模式、桥接模式、外观模式、享元模式、组合模式。
- 行为型模式(十一种):状态模式、模板方法模式、访问者模式、迭代子模式、责任链模式、备忘录模式、解释器模式、命令模式、中介者模式、观察者模式、策略模式。
工厂方法模式是一种创建型设计模式,用于定义创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
2.工厂方法模式的主要角色
2.1工厂接口(Factory Interface)
- 定义了一个抽象的工厂方法,用于创建产品对象。
- 工厂接口是所有具体工厂类的公共父类或接口。
2.2具体工厂(Concrete Factory)
- 实现了工厂接口,并具体化了工厂方法。
- 它负责创建具体产品对象的实例。
- 每个具体工厂类对应一个具体产品的创建逻辑。
2.3抽象产品(Product Interface)
- 定义了产品的接口,即产品对象的公共协议或规范。
- 它规定了产品对象应具有的属性和行为。
- 所有具体产品类都实现或继承了这个接口。
2.4具体产品(Concrete Product)
- 实现了抽象产品接口。
- 具体产品类是工厂方法模式中实际创建的对象。
- 每个具体产品类代表了产品接口的一个具体实现。
3.角色之间的协作关系
-
客户端(Client):客户端代码通常使用工厂接口来请求产品对象,而不是直接创建具体产品对象。这样,客户端代码与具体产品类解耦,提高了系统的灵活性和可扩展性。
-
工厂接口与具体工厂:工厂接口定义了创建产品的抽象方法,而具体工厂类实现了这些方法,以创建具体的产品对象。
-
抽象产品与具体产品:抽象产品定义了产品的规范,而具体产品实现了这些规范。这样,不同的产品类可以在不改变客户端代码的情况下被引入系统。
4.具体举例
假设我们有一个软件系统,它需要根据不同的操作系统来创建不同的GUI(图形用户界面)组件。比如,在Windows和Mac操作系统上,按钮(Button)的显示可能略有不同。
4.1抽象产品(Product Interface):
// 按钮的接口
interface Button {
void paint();
}
4.2具体产品(Concrete Product):
// Windows 按钮
class WindowsButton implements Button {
public void paint() {
System.out.println("绘制 Windows 风格的按钮");
}
}
// Mac 按钮
class MacButton implements Button {
public void paint() {
System.out.println("绘制 Mac 风格的按钮");
}
}
4.3工厂接口(Factory Interface):
// 按钮工厂接口
interface ButtonFactory {
Button createButton();
}
4.4具体工厂(Concrete Factory):
// Windows 按钮工厂
class WindowsButtonFactory implements ButtonFactory {
public Button createButton() {
return new WindowsButton();
}
}
// Mac 按钮工厂
class MacButtonFactory implements ButtonFactory {
public Button createButton() {
return new MacButton();
}
}
4.5客户端代码:
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String os = input.next();
ButtonFactory factory;
if (os.equals("Windows")) {
factory = new WindowsButtonFactory();
} else if (os.equals("Mac")) {
factory = new MacButtonFactory();
} else {
throw new IllegalArgumentException("未知的操作系统");
}
Button button = factory.createButton();
button.paint();
}
}
Button
接口声明了一个paint()
方法,用于绘制按钮。MacButton
和WindowsButton
是Button
接口的两个具体实现,分别绘制 Mac 和 Windows 风格的按钮。ButtonFactory
接口声明了一个createButton()
方法,用于创建按钮对象。MacButtonFactory
和WindowsButtonFactory
是ButtonFactory
接口的具体实现,分别用于创建MacButton
和WindowsButton
对象。
运行逻辑:
- 程序启动后,首先提示用户输入操作系统类型。
- 根据用户输入,程序决定使用哪个工厂类来创建按钮对象。
- 创建按钮对象后,调用其
paint()
方法来绘制按钮。 - 如果输入的操作系统类型不是预期的 "Windows" 或 "Mac",则程序将抛出异常并终止。
5.工厂方法设计模式的优缺点
5.1优点
- 封装性:隐藏了对象创建的具体细节,调用者只需要知道工厂接口即可。
- 扩展性:新增产品时,只需要添加相应的具体工厂类和产品类,无需修改已有代码。
- 解耦:客户端代码与具体产品类解耦,依赖于抽象而非具体实现。
5.2缺点
- 类的增加:每增加一个产品类,都需要增加一个对应的具体工厂类,导致类的数量成对增加。
6.工厂方法设计模式的适用场景
- 当一个类不知道它所必须创建的对象的类时。
- 当一个类需要由它的子类来指定它所创建的对象时。
- 当工具类和使用该工具的类从工具类中参数化时。