设计模式-工厂模式

设计模式专栏

    • 模式介绍
    • 模式类型
      • 简单工厂
      • 工厂方法模式
      • 抽象工厂模式
    • 主要特点
    • 应用场景
    • 代码示例
      • Java实现工厂模式
      • python实现工厂模式
    • spring中的应用
    • 查看更多


模式介绍

工厂模式是一种创建型设计模式,它提供了一个用于创建对象的接口,但允许子类决定实例化哪个类。工厂方法让一个类的实例化延迟到其子类。工厂模式是一种常见的设计模式,它提供了一种创建对象的接口,但具体创建的对象类型可以在运行时决定。工厂模式通常包括一个工厂类和多个产品类,工厂类负责创建产品类的实例。

工厂模式的优点包括:

分离了创建对象和使用的代码,使得代码更加灵活和可维护。

隐藏了对象创建的具体实现细节,让调用方与具体实现解耦。

可以通过扩展工厂类来增加新的产品类,而不需要修改调用方的代码。

工厂模式是一种灵活且可维护的设计模式,它通过将对象的创建和使用代码分离,隐藏了对象创建的具体实现细节,并且可以通过扩展工厂类来增加新的产品类。

模式类型

工厂模式可以分为简单工厂模式、工厂方法模式和抽象工厂模式。

简单工厂

  • 简单工厂模式 :它属于工厂模式的一种,是一个创建对象的类,由这个类来封装实例化对象的行为(代码)。其实现了一个创建对象的类,由这个类来封装实例化对象的行为,它假定一个类族有相同的接口。简单工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

  • 示例

以下是一个使用Java实现简单工厂模式的示例:

假设我们要创建一个简单的计算器,可以执行加、减、乘、除四种运算。我们可以使用简单工厂模式来实现这个计算器。

  1. 首先,定义一个接口Operation,表示一个运算操作:
public interface Operation {
    double calculate(double num1, double num2);
}
  1. 接下来,为每种运算创建一个实现类,实现Operation接口:
public class Addition implements Operation {
    @Override
    public double calculate(double num1, double num2) {
        return num1 + num2;
    }
}

public class Subtraction implements Operation {
    @Override
    public double calculate(double num1, double num2) {
        return num1 - num2;
    }
}

public class Multiplication implements Operation {
    @Override
    public double calculate(double num1, double num2) {
        return num1 * num2;
    }
}

public class Division implements Operation {
    @Override
    public double calculate(double num1, double num2) {
        if (num2 != 0) {
            return num1 / num2;
        } else {
            throw new IllegalArgumentException("Division by zero is not allowed.");
        }
    }
}
  1. 创建一个工厂类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.");
        }
    }
}
  1. 最后,创建一个客户端类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 {
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

public class Circle implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

接下来,我们创建一个抽象工厂类,该类声明了创建对象的接口:

public abstract class ShapeFactory {
   public abstract Shape createShape(String shapeType);
}

然后,我们创建具体工厂类,这些类实现了抽象工厂类并返回具体类的对象:

public class RectangleFactory extends ShapeFactory {
   @Override
   public 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 {
   @Override
   public 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实现的抽象工厂模式的示例:

首先,我们定义两个产品族:ProductAProductB。每个产品族都有两个具体产品:ConcreteProductA1, ConcreteProductA2, ConcreteProductB1, ConcreteProductB2

public interface ProductA {
    void operation1();
}

public interface ProductB {
    void operation2();
}

public class ConcreteProductA1 implements ProductA {
    @Override
    public void operation1() {
        System.out.println("ConcreteProductA1 operation1");
    }
}

public class ConcreteProductA2 implements ProductA {
    @Override
    public void operation1() {
        System.out.println("ConcreteProductA2 operation1");
    }
}

public class ConcreteProductB1 implements ProductB {
    @Override
    public void operation2() {
        System.out.println("ConcreteProductB1 operation2");
    }
}

public class ConcreteProductB2 implements ProductB {
    @Override
    public void operation2() {
        System.out.println("ConcreteProductB2 operation2");
    }
}

接下来,我们定义抽象工厂接口AbstractFactory,它声明了创建产品的方法。然后我们创建两个具体工厂ConcreteFactoryAConcreteFactoryB,它们实现了抽象工厂接口并分别创建ProductAProductB的实例。

public interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

public class ConcreteFactoryA implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}

public class ConcreteFactoryB implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public 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(); 
        }
    }

主要特点

  • 提供一个创建对象的接口,但子类决定要实例化哪个类。这意味着客户端只需要知道所创建对象的接口,而不必关心创建的具体实现。
  • 创建过程在其子类执行。也就是说,工厂方法让子类决定实例化哪个类,而具体类的实例化过程是在子类中完成的。
  • 隐藏复杂的逻辑处理过程。工厂模式通过将对象的创建和使用代码分离,让调用方与具体实现解耦,从而隐藏了对象创建的复杂逻辑。
  • 增加新的产品时,只需要扩展一个工厂类。这意味着工厂模式具有良好的扩展性,可以通过扩展工厂类来增加新的产品类,而不需要修改调用方的代码。
  • 屏蔽产品的具体实现,只关心产品的接口。这意味着调用方只需要关心所创建对象的接口,而不必关心具体实现,增加了代码的灵活性和可维护性。

工厂模式通过将对象的创建和使用代码分离,隐藏了对象创建的复杂逻辑,提供了良好的扩展性,并且屏蔽了产品的具体实现,只关心产品的接口。

应用场景

  1. 创建多个具有共同父类的子类对象,但具体创建哪个子类对象需要在运行时决定。

  2. 需要对一个类的实例化进行封装,并且调用方不需要知道具体是哪个子类的实例被创建。

  3. 需要提供一个通用的接口来创建对象,但具体创建哪个对象需要在运行时决定。

  4. 当一个对象的创建和使用是解耦的时候,即应用程序将对象的创建和初始化职责交给工厂对象,这也是工厂模式的常见应用场景。这样做的好处是,如果需求变更,需要将一个对象替换为另一个对象时,只需要修改创建该对象的工厂方法,而不需要修改所有使用该对象的代码。

  5. 当对象的创建过程比较复杂,或者在多个地方都需要使用时,通过将创建对象的代码统一放到工厂里面统一管理,可以减少代码的重复率,同时方便维护。

  6. 当一个类有很多子类,并且经常发生变化时,工厂模式可以将创建和使用分离,使用者不需要知道具体的创建过程,只需要使用即可。

工厂模式适用于需要创建多个具有共同父类的子类对象,但具体创建哪个子类对象需要在运行时决定的情况。同时,工厂模式也适用于需要对一个类的实例化进行封装,并且调用方不需要知道具体是哪个子类的实例被创建的情况。此外,当一个对象的创建和使用是解耦的时候,工厂模式也可以很好地应用。

代码示例

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):
    @staticmethod
    def 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框架中扮演着非常重要的角色,它帮助我们简化了对象的创建和管理,提高了代码的可维护性和可重用性。

查看更多

  • 设计模式-单例模式

你可能感兴趣的:(设计模式,设计模式,简单工厂模式,工厂方法模式,抽象工厂模式)