简单工厂、工厂方法、抽象工厂设计模式

工厂设计模式

刚学完工厂模式了, 工厂模式分有三种,分别为简单工厂、工厂方法、抽象工厂。这里会简单的介绍到三个工厂的使用方式和优缺点;首先我们需要了解一些概念

概念:

  1. 产品:
    具体的产品类

  2. 抽象产品:
    抽象类、接口、类(只要是对外暴露的都可以是接口)

  3. 产品簇:
    产品簇是指由一个工厂生产,位于不同产品等级结构中的一组产品

  4. 产品等级:
    产品等级即产品的继承结构,如一个抽象类是洗衣机,其子类有海尔洗衣机、海信洗衣机、tcl洗衣机,这样抽象洗衣机与具体品牌的的洗衣机之间构成了一个产品等级结构,抽象洗衣机是父类,具体品牌的洗衣机是子类

一、简单工厂

1. 使用方式
  1. 定义一个产品接口,接口定义共有的属性
public interface Food {
    
    
    void eat();
}
  1. 定义具体的产品类实现接口
public class Hamburger implements Food{
    
    

    @Override
    public void eat() {
    
    
        System.out.println("汉堡被吃了");
    }
}

public class Noodle implements Food {
    
    

    @Override
    public void eat() {
    
    
        System.out.println("面条被吃了");
    }
}
  1. 定义一个工厂类,编写静态方法,根据客户端给的参数返回具体产品对象
public class FoodFactory {
    
    
    public static Food add(int i){
    
    
        Food food = null;
        switch(i){
    
    
            case 1:
                food = new Hamburger();
                break;
            case 2:
                food = new Noodle();
                break;
        }
        return food;
    }
}

2. 类图

在这里插入图片描述

优点:

  1. 使客户端与底层解耦,就算底层方法名发生改变也不会影响到客户端的使用
  2. 客户端不需要知道所创建的具体产品类的类名,只需要知道具体产品类对应的参数

缺点:

  1. 因为工厂类集中了所有产品的创建逻辑,一旦工厂类不能工作,整个系统都会受影响
  2. 系统扩展困难,一旦添加新的产品,就不得不修改工厂逻辑,在产品类较多时,可能会造成逻辑过于复杂
  3. 违反开闭原则,因为添加新得产品,势必要修改工厂逻辑。

二、工厂方法

1. 使用方式
  1. 在简单工厂的基础上,定义一个产品接口,再定义具体的产品工厂类
public interface FoodFactory {
    
    
    public Food getFood();
}
  1. 具体的产品工厂生产具体产品
public class HamburgerFactory implements FoodFactory {
    
    
    @Override
    public Food getFood() {
    
    
        return new Hamburger();
    }
}

public class NoodleFactory implements FoodFactory {
    
    
    @Override
    public Food getFood() {
    
    
        return new Noodle();
    }
}
  1. 在客户端中,使用产品工厂生产具体产品
public class BTest {
    
    
    @Test
    public void test01() {
    
    
        HamburgerFactory hbgFactory = new HamburgerFactory();
        Food hamburger = hbgFactory.getFood();
        hamburger.eat();

        NoodleFactory nodFactory = new NoodleFactory();
        Food noodle = nodFactory.getFood();
        noodle.eat();
    }
}
2. 类图

在这里插入图片描述

优点:

  1. 符合开闭原则,添加新的产品只要新建一个工厂类和具体产品类即
    缺点:
  2. 增加代码量,当有多个产品等级的时候,会出现很多的工厂类,造成类爆炸

三、抽象工厂

1. 使用方式
  1. 当有多个产品簇时,我们可以定义一个抽象工厂,在抽象工厂里面定义实际的生产工厂
public interface Factory {
    
    
    public Food getFood();
    public Drinks getDrink();
}
  1. 生产工厂里面生产具体产品
public class KFCFactory implements Factory {
    
    
    @Override
    public Food getFood() {
    
    
        return new Hamburger();
    }

    @Override
    public Drinks getDrink() {
    
    
        return new Cola();
    }
}

public class MCDFactory implements Factory {
    
    
    @Override
    public Food getFood() {
    
    
        return new Noodle();
    }

    @Override
    public Drinks getDrink() {
    
    
        return new OrangeJuice();
    }
}

2. 类图

在这里插入图片描述

优点:

  1. 解决了工厂方法类爆炸的问题,将工厂抽象化,可以减少四分之一的类
  2. 更适合多产品簇的复杂场景

总结:三种模式各有各的优点和缺点,在演变的过程中也是更加的复杂,但要记住越复杂,越能适应复杂的业务场景。在选择的时候可以根据自己的业务需求选择最合适的!

猜你喜欢

转载自blog.csdn.net/weixin_41058733/article/details/110081462