设计模式(工厂方法-Factory Method)结构|原理|优缺点|场景|示例

                                     设计模式(分类)        设计模式(六大原则)   

    创建型(5种)        工厂方法         抽象工厂模式        单例模式        建造者模式        原型模式

    结构型(7种)        适配器模式        装饰器模式        代理模式        ​​​​​​外观模式      桥接模式        组合模式       享元模式

    行为型(11种)      策略模式        模板方法模式        观察者模式        迭代器模式     责任链模式     命令模式    备忘录模式          状态模式         访问者模式        中介者模式 


设计模式中的工厂方法(Factory Method)是一种创建型模式,它提供了一种创建对象的灵活方式,通过将对象的创建过程封装在子类中来实现对象的创建延迟。工厂方法模式的核心在于定义一个用于创建对象的接口(或抽象类),并允许子类决定实例化哪个类的对象。以下是对工厂方法模式的详细说明:

模式结构

工厂方法模式通常包含以下角色:

  1. 抽象产品(Product):定义了一个产品的接口,是所有具体产品类的公共父类或接口,声明了产品的通用行为。

  2. 具体产品(Concrete Product):实现了抽象产品的接口,是工厂方法所创建的对象的具体类型。可以有多个具体产品类,每个类对应一种具体产品。

  3. 抽象工厂(Creator):定义了一个创建产品对象的接口,声明了一个创建产品的工厂方法。该方法通常返回抽象产品类型,以便调用者可以使用统一的方式处理各种具体产品。

  4. 具体工厂(Concrete Creator):实现了抽象工厂接口,提供了创建具体产品对象的实现。每一个具体工厂类对应一种具体产品类型,通过重写工厂方法来创建对应的具体产品对象。

工作原理

  • 客户端:需要创建对象时,不直接实例化具体产品类,而是通过调用具体工厂类的工厂方法来获取产品对象。
  • 具体工厂:负责实现工厂方法,该方法根据具体工厂的类型返回相应具体产品类型的实例。具体工厂隐藏了创建产品的具体细节,客户端只需关心所需产品的类型,无需了解创建过程。
  • 抽象产品:作为产品对象的通用接口,为客户端提供统一的操作入口,使得客户端可以使用抽象产品类型的引用来处理具体产品对象,无需关心实际使用的是哪种具体产品。

优缺点

优点
  • 封装性:将对象的创建过程封装在工厂类中,客户端无需关心对象的具体创建过程,只需知道所需产品的类型即可。
  • 灵活性:通过增加新的具体工厂和具体产品类,可以很容易地扩展系统以支持新的产品类型,符合“开闭原则”。
  • 解耦:客户端与具体产品类解耦,只需要和抽象产品以及具体工厂打交道,降低了系统的耦合度。
  • 代码结构清晰:通过工厂方法模式,可以将产品类的实例化代码集中在一起,使得代码结构更加清晰,易于维护。
缺点
  • 类的层级结构增加:引入了额外的抽象层和具体工厂类,可能导致类的层级结构变得复杂。
  • 增加系统的理解与设计难度:对于不熟悉工厂方法模式的开发者,可能需要花费更多时间理解系统的设计和实现。
  • 每次新增产品时都需要添加新的具体工厂:如果产品种类繁多,可能会导致具体工厂类数量的增长。

适用场景

  • 对象创建过程比较复杂:当创建对象涉及大量初始化工作,或者需要依赖具体环境、条件来确定创建何种对象时,工厂方法模式可以将这些复杂性封装在工厂类中。
  • 系统需要支持多种产品类型:如果有多种不同类型的产品需要创建,并且希望在不修改客户端代码的情况下引入新产品,工厂方法模式可以很好地适应这种需求。
  • 隔离直接创建对象的责任:如果不想让客户端直接接触对象创建的细节,或者需要将对象的创建过程与使用过程分离,可以使用工厂方法模式。

代码示例(以Java为例)

// 抽象产品
public interface Car {
    void drive();
}

// 具体产品A
public class SportsCar implements Car {
    @Override
    public void drive() {
        System.out.println("Driving a sports car.");
    }
}

// 具体产品B
public class SedanCar implements Car {
    @Override
    public void drive() {
        System.out.println("Driving a sedan car.");
    }
}

// 抽象工厂
public abstract class CarFactory {
    public abstract Car createCar();
}

// 具体工厂A
public class SportsCarFactory extends CarFactory {
    @Override
    public Car createCar() {
        return new SportsCar();
    }
}

// 具体工厂B
public class SedanCarFactory extends CarFactory {
    @Override
    public Car createCar() {
        return new SedanCar();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        CarFactory factory = new SportsCarFactory(); // 或者 new SedanCarFactory()
        Car car = factory.createCar();
        car.drive();
    }
}

//在这个例子中,客户端通过调用具体工厂(如SportsCarFactory或SedanCarFactory)的createCar()方法来获取所需的Car对象。
//具体创建哪种类型的Car对象由具体工厂决定,客户端无需知道具体的创建细节,只需与Car接口和工厂类交互。这样,系统在不修改现有代码的情况下就能轻易地添加新的汽车类型和对应的工厂类,实现了良好的扩展性

代码示例(以Python为例)

在这个Python示例中:

  • Animal类作为抽象产品,定义了动物的基本属性(如name)和抽象方法make_sound(),要求子类必须实现该方法。
  • DogCat类是具体产品,它们继承自Animal类并实现了各自的make_sound()方法,分别模拟狗和猫发出的声音。
  • AnimalFactory类作为抽象工厂,定义了一个静态方法create_animal(),该方法接收动物类型和名字作为参数,根据传入的动物类型创建相应的具体动物对象。这里使用静态方法简化了示例,实际应用中也可以定义为普通方法并创建AnimalFactory的实例来调用。
  • 客户端代码中,创建了AnimalFactory实例,并通过调用其create_animal()方法创建了DogCat对象。客户端无需知道如何直接创建这些对象,只需与AnimalFactory交互并传递所需动物的类型和名称即可。

        这个例子展示了工厂方法模式在Python中的应用,通过工厂方法创建对象,客户端代码与具体的动物创建逻辑解耦,增加了系统的灵活性和可扩展性。如果需要添加新的动物类型(如兔子),只需定义新的动物类并更新工厂方法中的逻辑即可,无需改动客户端代码。

# 抽象产品
class Animal:
    def __init__(self, name):
        self.name = name

    def make_sound(self):
        raise NotImplementedError("Subclasses must implement this abstract method")

    def __str__(self):
        return f"{self.name} makes {self.make_sound()} sound"

# 具体产品
class Dog(Animal):
    def make_sound(self):
        return "Woof!"

class Cat(Animal):
    def make_sound(self):
        return "Meow!"

# 抽象工厂
class AnimalFactory:
    @staticmethod
    def create_animal(animal_type, name):
        if animal_type == "dog":
            return Dog(name)
        elif animal_type == "cat":
            return Cat(name)
        else:
            raise ValueError(f"Unsupported animal type: {animal_type}")

# 客户端代码
def main():
    animal_factory = AnimalFactory()

    dog = animal_factory.create_animal("dog", "Rex")
    print(dog)

    cat = animal_factory.create_animal("cat", "Whiskers")
    print(cat)

if __name__ == "__main__":
    main()

  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工厂方法模式(Factory Method)是一种创建型设计模式,它提供了一种将对象的创建委托给子类的方式。在工厂方法模式中,父类负责定义创建对象的接口,而子类则负责实现这个接口并创建对象。 以下是一个简单的工厂方法模式的实现示例: ```java // 抽象产品 interface Product { void doSomething(); } // 具体产品1 class ConcreteProduct1 implements Product { @Override public void doSomething() { System.out.println("ConcreteProduct1 do something"); } } // 具体产品2 class ConcreteProduct2 implements Product { @Override public void doSomething() { System.out.println("ConcreteProduct2 do something"); } } // 抽象工厂 interface Factory { Product createProduct(); } // 具体工厂1 class ConcreteFactory1 implements Factory { @Override public Product createProduct() { return new ConcreteProduct1(); } } // 具体工厂2 class ConcreteFactory2 implements Factory { @Override public Product createProduct() { return new ConcreteProduct2(); } } ``` 使用工厂方法模式的优点包括: 1. 降低代码耦合度:工厂方法模式将对象的创建和使用分离开来,降低了对象之间的耦合度。 2. 更好的扩展性:添加新的产品时,只需要添加一个对应的具体产品类和具体工厂类即可,不需要修改已有的代码。 3. 符合单一职责原则:每个具体工厂类只负责创建一种产品,符合单一职责原则。 工厂方法模式的缺点包括: 1. 增加了类的个数:工厂方法模式需要创建大量的工厂类和产品类,增加了类的个数。 2. 增加了系统的复杂度:工厂方法模式将对象的创建和使用分离开来,增加了系统的复杂度。 工厂方法模式的应用场景包括: 1. 当一个类不知道它所必须创建的对象的类时,可以使用工厂方法模式。 2. 当一个类希望由它的子类来指定所创建的对象时,可以使用工厂方法模式。 3. 当需要将对象的创建和使用分离开来以便分别独立地变化时,可以使用工厂方法模式。 4. 当需要提供一个全局的访问点来创建某种类型的对象时,可以使用工厂方法模式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值