- 模式介绍
- 模式类型
- 简单工厂
- 工厂方法模式
- 抽象工厂模式
- 主要特点
- 应用场景
- 代码示例
- Java实现工厂模式
- python实现工厂模式
- spring中的应用
- 查看更多
模式介绍
工厂模式是一种创建型设计模式,它提供了一个用于创建对象的接口,但允许子类决定实例化哪个类。工厂方法让一个类的实例化延迟到其子类。工厂模式是一种常见的设计模式,它提供了一种创建对象的接口,但具体创建的对象类型可以在运行时决定。工厂模式通常包括一个工厂类和多个产品类,工厂类负责创建产品类的实例。
工厂模式的优点包括:
分离了创建对象和使用的代码,使得代码更加灵活和可维护。
隐藏了对象创建的具体实现细节,让调用方与具体实现解耦。
可以通过扩展工厂类来增加新的产品类,而不需要修改调用方的代码。
工厂模式是一种灵活且可维护的设计模式,它通过将对象的创建和使用代码分离,隐藏了对象创建的具体实现细节,并且可以通过扩展工厂类来增加新的产品类。
模式类型
工厂模式可以分为简单工厂模式、工厂方法模式和抽象工厂模式。
简单工厂
-
简单工厂模式 :它属于工厂模式的一种,是一个创建对象的类,由这个类来封装实例化对象的行为(代码)。其实现了一个创建对象的类,由这个类来封装实例化对象的行为,它假定一个类族有相同的接口。简单工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
-
示例
以下是一个使用Java实现简单工厂模式的示例:
假设我们要创建一个简单的计算器,可以执行加、减、乘、除四种运算。我们可以使用简单工厂模式来实现这个计算器。
- 首先,定义一个接口
Operation,表示一个运算操作:
public interface Operation {double calculate(double num1, double num2);
}
- 接下来,为每种运算创建一个实现类,实现
Operation接口:
public class Addition implements Operation {@Overridepublic double calculate(double num1, double num2) {return num1 + num2;}
}public class Subtraction implements Operation {@Overridepublic double calculate(double num1, double num2) {return num1 - num2;}
}public class Multiplication implements Operation {@Overridepublic double calculate(double num1, double num2) {return num1 * num2;}
}public class Division implements Operation {@Overridepublic double calculate(double num1, double num2) {if (num2 != 0) {return num1 / num2;} else {throw new IllegalArgumentException("Division by zero is not allowed.");}}
}
- 创建一个工厂类
OperationFactory,负责根据客户端的请求创建相应的运算实例:
public class OperationFactory {public static Operation createOperation(char operator) {switch (operator) {case '+':return new Addition();case '-':return new Subtraction();case '*':return new Multiplication();case '/':return new Division();default:throw new IllegalArgumentException("Invalid operator.");}}
}
- 最后,创建一个客户端类
Calculator,通过工厂类获取运算实例,并执行计算:
public class Calculator {public static void main(String[] args) {double num1 = 10.0;double num2 = 5.0;char operator = '/'; // 可以修改为其他运算符:+、-、* 或 /Operation operation = OperationFactory.createOperation(operator);double result = operation.calculate(num1, num2);System.out.println("Result: " + result);}
}
这样,我们就使用简单工厂模式实现了一个简单的计算器。客户端只需指定运算符和操作数,工厂类负责创建相应的运算实例,并执行计算。这种方式使得代码更加灵活和可扩展,如果需要添加新的运算类型,只需创建新的实现类,并在工厂类中添加相应的创建逻辑即可。
工厂方法模式
-
工厂方法模式 :它定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
-
示例
工厂方法模式是一种创建型设计模式,它提供了一种创建对象的接口,但具体创建的对象类型可以在运行时决定。下面是一个简单的Java实现工厂方法模式的示例:
首先,我们定义一个公共的接口:
public interface Shape {void draw();
}
然后,我们创建实现接口的具体类:
public class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}
}public class Circle implements Shape {@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");}
}
接下来,我们创建一个抽象工厂类,该类声明了创建对象的接口:
public abstract class ShapeFactory {public abstract Shape createShape(String shapeType);
}
然后,我们创建具体工厂类,这些类实现了抽象工厂类并返回具体类的对象:
public class RectangleFactory extends ShapeFactory {@Overridepublic Shape createShape(String shapeType) {if (shapeType != null) {if (shapeType.equalsIgnoreCase("rectangle")) {return new Rectangle();} else {return null;}} else {return null;}}
}public class CircleFactory extends ShapeFactory {@Overridepublic Shape createShape(String shapeType) {if (shapeType != null) {if (shapeType.equalsIgnoreCase("circle")) {return new Circle();} else {return null;}} else {return null;}}
}
最后,我们在客户端代码中使用工厂对象来创建对象:
public class FactoryPatternDemo {public static void main(String[] args) { ShapeFactory rectangleFactory = new RectangleFactory(); ShapeFactory circleFactory = new CircleFactory(); Shape rectangle = rectangleFactory.createShape("rectangle"); rectangle.draw(); Shape circle = circleFactory.createShape("circle"); circle.draw(); }
}
draw();
Shape circle = circleFactory.createShape("circle");
circle.draw();}
}
抽象工厂模式
-
抽象工厂模式 :它定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类。抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。从设计层面看,抽象工厂模式就是对简单工厂模式的改进或称为进一步的抽象。
-
示例
抽象工厂模式是一种创建型设计模式,它提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。以下是一个使用Java实现的抽象工厂模式的示例:
首先,我们定义两个产品族:ProductA和ProductB。每个产品族都有两个具体产品:ConcreteProductA1, ConcreteProductA2, ConcreteProductB1, ConcreteProductB2。
public interface ProductA {void operation1();
}public interface ProductB {void operation2();
}public class ConcreteProductA1 implements ProductA {@Overridepublic void operation1() {System.out.println("ConcreteProductA1 operation1");}
}public class ConcreteProductA2 implements ProductA {@Overridepublic void operation1() {System.out.println("ConcreteProductA2 operation1");}
}public class ConcreteProductB1 implements ProductB {@Overridepublic void operation2() {System.out.println("ConcreteProductB1 operation2");}
}public class ConcreteProductB2 implements ProductB {@Overridepublic void operation2() {System.out.println("ConcreteProductB2 operation2");}
}
接下来,我们定义抽象工厂接口AbstractFactory,它声明了创建产品的方法。然后我们创建两个具体工厂ConcreteFactoryA和ConcreteFactoryB,它们实现了抽象工厂接口并分别创建ProductA和ProductB的实例。
public interface AbstractFactory {ProductA createProductA();ProductB createProductB();
}public class ConcreteFactoryA implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA1();}@Overridepublic ProductB createProductB() {return new ConcreteProductB1();}
}public class ConcreteFactoryB implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA2();}@Overridepublic ProductB createProductB() {return new ConcreteProductB2();}
}
最后,我们在客户端代码中使用工厂对象来创建产品对象:
public class FactoryPatternDemo {public static void main(String[] args) {AbstractFactory factoryA = new ConcreteFactoryA(); AbstractFactory factoryB = new ConcreteFactoryB(); ProductA productA1 = factoryA.createProductA(); ProductA productA2 = factoryB.createProductA(); ProductB productB1 = factoryA.createProductB(); ProductB productB2 = factoryB.createProductB(); productA1.operation1(); }}
主要特点
- 提供一个创建对象的接口,但子类决定要实例化哪个类。这意味着客户端只需要知道所创建对象的接口,而不必关心创建的具体实现。
- 创建过程在其子类执行。也就是说,工厂方法让子类决定实例化哪个类,而具体类的实例化过程是在子类中完成的。
- 隐藏复杂的逻辑处理过程。工厂模式通过将对象的创建和使用代码分离,让调用方与具体实现解耦,从而隐藏了对象创建的复杂逻辑。
- 增加新的产品时,只需要扩展一个工厂类。这意味着工厂模式具有良好的扩展性,可以通过扩展工厂类来增加新的产品类,而不需要修改调用方的代码。
- 屏蔽产品的具体实现,只关心产品的接口。这意味着调用方只需要关心所创建对象的接口,而不必关心具体实现,增加了代码的灵活性和可维护性。
工厂模式通过将对象的创建和使用代码分离,隐藏了对象创建的复杂逻辑,提供了良好的扩展性,并且屏蔽了产品的具体实现,只关心产品的接口。
应用场景
-
创建多个具有共同父类的子类对象,但具体创建哪个子类对象需要在运行时决定。
-
需要对一个类的实例化进行封装,并且调用方不需要知道具体是哪个子类的实例被创建。
-
需要提供一个通用的接口来创建对象,但具体创建哪个对象需要在运行时决定。
-
当一个对象的创建和使用是解耦的时候,即应用程序将对象的创建和初始化职责交给工厂对象,这也是工厂模式的常见应用场景。这样做的好处是,如果需求变更,需要将一个对象替换为另一个对象时,只需要修改创建该对象的工厂方法,而不需要修改所有使用该对象的代码。
-
当对象的创建过程比较复杂,或者在多个地方都需要使用时,通过将创建对象的代码统一放到工厂里面统一管理,可以减少代码的重复率,同时方便维护。
-
当一个类有很多子类,并且经常发生变化时,工厂模式可以将创建和使用分离,使用者不需要知道具体的创建过程,只需要使用即可。
工厂模式适用于需要创建多个具有共同父类的子类对象,但具体创建哪个子类对象需要在运行时决定的情况。同时,工厂模式也适用于需要对一个类的实例化进行封装,并且调用方不需要知道具体是哪个子类的实例被创建的情况。此外,当一个对象的创建和使用是解耦的时候,工厂模式也可以很好地应用。
代码示例
Java实现工厂模式
好的,下面是一个简单的Java工厂模式的实现:
public interface Product {void use();
}
public class ConcreteProductA implements Product {public void use() {System.out.println("使用具体产品A");}
}
public class ConcreteProductB implements Product {public void use() {System.out.println("使用具体产品B");}
}
public class Factory {public Product createProduct(String type) {if (type.equals("A")) {return new ConcreteProductA();} else if (type.equals("B")) {return new ConcreteProductB();} else {throw new IllegalArgumentException("无效的产品类型:" + type);}}
}
public class Client {public static void main(String[] args) {Factory factory = new Factory();Product productA = factory.createProduct("A");productA.use(); // 输出 "使用具体产品A"Product productB = factory.createProduct("B");productB.use(); // 输出 "使用具体产品B"}
}
在这个例子中,我们定义了一个Product接口,它代表了所有的产品。然后我们创建了两个实现Product接口的具体产品ConcreteProductA和ConcreteProductB。接着我们创建了一个Factory类,它负责根据传入的参数来创建相应的具体产品。最后我们在Client类中通过Factory来创建具体的产品,并使用它们。
python实现工厂模式
好的,以下是一个Python实现的工厂模式的例子:
class Product(object):def use(self):raise NotImplementedError("子类必须实现use方法")
class ConcreteProductA(Product):def use(self):print("使用具体产品A")
class ConcreteProductB(Product):def use(self):print("使用具体产品B")
class Factory(object):@staticmethoddef create_product(type):if type == "A":return ConcreteProductA()elif type == "B":return ConcreteProductB()else:raise ValueError("无效的产品类型:{}".format(type))
class Client(object):def __init__(self):self.product_a = Factory.create_product("A")self.product_b = Factory.create_product("B")def use_product_a(self):self.product_a.use()def use_product_b(self):self.product_b.use()
if __name__ == "__main__":client = Client()client.use_product_a() # 输出 "使用具体产品A"client.use_product_b() # 输出 "使用具体产品B"
在这个例子中,我们定义了一个抽象的Product类,它代表了所有的产品。然后我们创建了两个实现了Product类的具体产品ConcreteProductA和ConcreteProductB。接着我们创建了一个Factory类,它负责根据传入的参数来创建相应的具体产品。最后我们在Client类中通过Factory来创建具体的产品,并使用它们。
spring中的应用
工厂模式在Spring框架中得到了广泛应用。Spring框架的核心是IoC(控制反转)容器,它就是一个典型的工厂模式的应用。
IoC容器负责对象的创建、初始化、生命周期管理等,它就是一个工厂,将原本需要程序员自己创建和管理的对象交由IoC容器来负责。程序员只需要通过配置文件或者注解的方式来告诉IoC容器需要创建哪些对象,以及它们的依赖关系,IoC容器就会自动将这些对象创建好,并且根据依赖关系组装好。
另外,Spring框架中的AOP(面向切面编程)也用到了工厂模式。AOP是通过动态代理的方式来实现的,它需要在运行时创建一个代理对象,这个代理对象需要实现目标对象的接口,并且调用目标对象的方法。这个代理对象的创建过程就是通过工厂模式来实现的。
总之,工厂模式在Spring框架中扮演着非常重要的角色,它帮助我们简化了对象的创建和管理,提高了代码的可维护性和可重用性。
查看更多
- 设计模式-单例模式