【设计模式(一)】创建型模式--工厂方法模式

创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。

在了解工厂方法模式之前,有必要对“简单工厂”模式进⾏⼀定的了解,简单工厂模式是⼀种创建型设计模式,但并不属于23种设计模式之⼀,更多的是⼀种编程习惯。

简单工厂模式的核心思想是将产品的创建过程封装在⼀个工厂类中,把创建对象的流程集中在这个工厂类里面

简单工厂包含如下角色:

  • 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品 :实现或者继承抽象产品的子类
  • 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。

以咖啡店点咖啡为例,Coffee接口是抽象产品,AmericanCoffee和LatteCoffee是具体产品,SimpleCoffeeFactory是具体工厂。

简单工厂类简化了客户端(咖啡店CoffeeStore)操作,客户端可以调用工厂方法来获取具体产品,而无需直接与具体产品类交互,降低了耦合,但是有⼀个很⼤的问题就是不够灵活,如果需要添加新的产品,就需要修改工厂类的代码。

咖啡接口和具体咖啡产品代码

public interface Coffee {
    void getName();
}

public class AmericanCoffee implements Coffee{
    @Override
    public void getName() {
        System.out.println("我是美国咖啡");
    }
}

public class LatteCoffee implements Coffee{
    @Override
    public void getName(){
        System.out.println("我是拿铁咖啡");
    }
}

工厂(此处使用静态工厂)和客服端代码

public class SimpleCoffeeFactory {
    public static Coffee createCoffee(String type){
        switch (type){
            case "AmericanCoffee" -> {return new AmericanCoffee();}
            case "LatteCoffee" -> {return new LatteCoffee();}
            default ->{
                System.out.println("没有这种咖啡");
                return null;
            }
        }
    }
}

public class CoffeeStore {
    public Coffee orderCoffee(String type){
        //客户端从工厂拿咖啡,而不是直接自己创建咖啡
        Coffee coffee = SimpleCoffeeFactory.createCoffee(type);
        if(coffee != null){
            coffee.getName();
        }
        return coffee;
    }
}

工厂方法模式

工厂方法模式也是⼀种创建型设计模式,简单工厂模式只有⼀个工厂类,负责创建所有产品,如果要添加新的产品,通常需要修改工厂类的代码。而工厂方法模式引入了抽象工厂和具体工厂的概念,每个具体工厂只负责创建⼀个具体产品,添加新的产品只需要添加新的工厂类而无需修改原来的代码,这样就使得产品的⽣产更加灵活,支持扩展,符合开闭原则。

工厂方法模式分为以下几个角色

  • 抽象工厂:一个接口,包含一个抽象的工厂方法(⽤于创建产品对象)。
  • 具体工厂:实现抽象工厂接口,创建具体的产品。
  • 抽象产品:定义产品的接口。
  • 具体产品:实现抽象产品接口,是工厂创建的对象。

将上面咖啡例子改成工厂模式代码,咖啡接口和具体咖啡实现类不用变,只需提取一个抽象工厂接口,每种咖啡都有一个具体的工厂实现类负责生产咖啡,咖啡店指定具体咖啡实现类来生产不同咖啡。

public interface Factory {
    Coffee creatCoffee();
}

public class AmericanCoffeeFactory implements Factory{
    @Override
    public Coffee creatCoffee() {
        return new AmericanCoffee();
    }
}

public class LatteCoffeeFactory implements Factory{
    @Override
    public Coffee creatCoffee() {
        return new LatteCoffee();
    }
}

public class CoffeeStore {
    public Coffee orderCoffee(Factory factory){
        Coffee coffee = factory.creatCoffee();
        coffee.getName();
        return coffee;
    }
}

优点:

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
  • 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

缺点:

  • 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
posted @ 2024-07-04 16:55  hudad  阅读(5)  评论(0编辑  收藏  举报