简单工厂模式(Simple Factory Pattern)并不是一种标准的设计模式(不在GoF设计模式的23种之列),而是一种编程习惯,用于创建对象而不必指定将要创建的对象的确切类。它有一个工厂类,可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类和接口。
首先,定义一个接口或抽象类来规范产品对象的行为。
public interface Product {
void use();
}
然后,实现具体的产品类。
public class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("Using ConcreteProductA");
}
}
public class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("Using ConcreteProductB");
}
}
接下来,创建一个工厂类来生成基于给定信息的具体产品对象。
public class SimpleFactory {
public Product createProduct(String type) {
switch (type) {
case "A":
return new ConcreteProductA();
case "B":
return new ConcreteProductB();
default:
throw new IllegalArgumentException("Unknown product type");
}
}
}
最后,客户端代码使用工厂类来创建产品对象。
public class Client {
public static void main(String[] args) {
SimpleFactory factory = new SimpleFactory();
Product productA = factory.createProduct("A");
productA.use();
Product productB = factory.createProduct("B");
productB.use();
}
}
在这个例子中,SimpleFactory
类根据传入的参数(例如,类型"A"或"B")决定实例化哪一个具体产品类(ConcreteProductA
或 ConcreteProductB
)。客户端不需要直接实例化产品对象,而是通过工厂类来请求创建对象,这样就降低了客户端与具体产品类之间的耦合度。简单工厂模式适用于产品种类不太复杂,且不频繁添加新产品的情况。
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类中进行。
在以下的例子中,将通过一个简单的日志记录器的例子来演示如何实现工厂方法模式。这个例子包括一个Logger
接口和两个实现了这个接口的具体日志记录器类(FileLogger
和ConsoleLogger
),以及一个LoggerFactory
接口和为每种日志记录器提供创建功能的具体工厂类。
首先,定义Logger
接口和两个具体的日志记录器类:
// 日志记录器接口
public interface Logger {
void log(String message);
}
// 将消息记录到控制台的具体日志记录器
public class ConsoleLogger implements Logger {
public void log(String message) {
System.out.println("ConsoleLogger: " + message);
}
}
// 将消息记录到文件的具体日志记录器
public class FileLogger implements Logger {
public void log(String message) {
System.out.println("FileLogger: " + message);
}
}
接下来,定义LoggerFactory
接口和具体的工厂类:
// 日志记录器工厂接口
public interface LoggerFactory {
Logger createLogger();
}
// 创建控制台日志记录器的工厂
public class ConsoleLoggerFactory implements LoggerFactory {
public Logger createLogger() {
// 创建一个新的控制台日志记录器实例
return new ConsoleLogger();
}
}
// 创建文件日志记录器的工厂
public class FileLoggerFactory implements LoggerFactory {
public Logger createLogger() {
// 创建一个新的文件日志记录器实例
return new FileLogger();
}
}
最后,客户端代码利用工厂来创建日志记录器:
public class Client {
public static void main(String[] args) {
LoggerFactory factory;
Logger logger;
// 使用控制台日志记录器
factory = new ConsoleLoggerFactory();
logger = factory.createLogger();
logger.log("This is a message.");
// 使用文件日志记录器
factory = new FileLoggerFactory();
logger = factory.createLogger();
logger.log("This is another message.");
}
}
在这个例子中,LoggerFactory
定义了一个创建对象的方法createLogger
,而具体的工厂类(ConsoleLoggerFactory
和FileLoggerFactory
)实现了这个方法来创建具体类型的日志记录器。这样,客户端代码就可以在不知道具体日志记录器类的情况下,通过工厂接口来创建日志记录器对象。这种方式使得添加新的日志记录器类型时,客户端代码不需要做任何修改,符合开闭原则。
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。这种模式特别适用于那些系统中,有多个系列的产品需要创建,并且系统需要在多个系列产品之间切换时。该模式允许客户端使用抽象的接口来创建一组相关的产品,而不需要知道(或关心)具体产品的具体类。
下面是一个简单的Java实现示例,假设有一个GUI元素的库,其中包括按钮和复选框,这些GUI元素有不同的风格(如Windows和Mac风格)。我们将使用抽象工厂模式来抽象和封装这些元素的创建过程。
首先,定义抽象产品接口和具体产品类:
// 抽象产品:按钮
public interface Button {
void paint();
}
// 具体产品:Windows风格按钮
public class WindowsButton implements Button {
public void paint() {
System.out.println("Rendering a button in Windows style.");
}
}
// 具体产品:Mac风格按钮
public class MacButton implements Button {
public void paint() {
System.out.println("Rendering a button in Mac style.");
}
}
// 抽象产品:复选框
public interface Checkbox {
void paint();
}
// 具体产品:Windows风格复选框
public class WindowsCheckbox implements Checkbox {
public void paint() {
System.out.println("Rendering a checkbox in Windows style.");
}
}
// 具体产品:Mac风格复选框
public class MacCheckbox implements Checkbox {
public void paint() {
System.out.println("Rendering a checkbox in Mac style.");
}
}
接下来,定义抽象工厂接口和具体工厂类:
// 抽象工厂
public interface GUIFactory {
Button createButton();
Checkbox createCheckbox();
}
// 具体工厂:Windows风格工厂
public class WindowsFactory implements GUIFactory {
public Button createButton() {
return new WindowsButton();
}
public Checkbox createCheckbox() {
return new WindowsCheckbox();
}
}
// 具体工厂:Mac风格工厂
public class MacFactory implements GUIFactory {
public Button createButton() {
return new MacButton();
}
public Checkbox createCheckbox() {
return new MacCheckbox();
}
}
最后,客户端代码可能看起来像这样:
public class Application {
private Button button;
private Checkbox checkbox;
public Application(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}
public void paint() {
button.paint();
checkbox.paint();
}
public static void main(String[] args) {
GUIFactory factory = new WindowsFactory();
Application app = new Application(factory);
app.paint();
// 切换到Mac风格
factory = new MacFactory();
app = new Application(factory);
app.paint();
}
}
在这个例子中,Application
类不直接依赖于具体的按钮或复选框类(如WindowsButton
或MacCheckbox
),而是通过GUIFactory
接口来创建这些对象。这样,通过更换不同的GUIFactory
实现(如WindowsFactory
或MacFactory
),就可以在不同的GUI风格之间切换,而无需修改Application
类的代码。这就是抽象工厂模式的魅力。