设计模式-工厂模式-以餐饮为例

简单工厂模式

简单工厂模式,指将一些对象的创建从由使用者进行创建,改为由一个工厂类来统一创建对象,使用者只需要传入对应的参数告知工厂类需要哪一种对象即可。

这里以餐厅为例,餐厅后厨负责做菜,服务员充当工厂角色,用来传递顾客的点餐给后厨,后厨做完之后由服务员传递

首先需要定义一个后厨接口,用于服务员(工厂)创建餐品(对象)

public interface Cooker {
    public void cook();
}

然后定义三种菜品类继承后厨接口

public class Fish implements Cooker{
    @Override
    public void cook() {
        System.out.println("一份酸菜鱼");
    }
}
public class Meat implements Cooker{
    @Override
    public void cook() {
        System.out.println("一份小炒肉");
    }
}
public class Vegetable implements Cooker{
    @Override
    public void cook() {
        System.out.println("一份手撕包菜");
    }
}

最后定义一个服务员类(工厂类),用于点餐

public class RestaurantFactory {
    public static final int FISH=1;
    public static final int MEAT=2;
    public static final int VEGETABLE=3;
    //点菜
    public Cooker getCook(int cookName)
    {
        switch (cookName)
        {
            case FISH:
                return new Fish();
            case MEAT:
                return new Meat();
            case VEGETABLE:
                return new Vegetable();
            default:
                return null;
        }
    }
}

测试用户点餐

public class FactoryTest {
    @Test
    public void simpleFactoryTest()
    {
        //获取工厂实例,类似服务员
        RestaurantFactory restaurantFactory = new RestaurantFactory();
        Cooker cooker = restaurantFactory.getCook(RestaurantFactory.FISH);
        cooker.cook();
    }
}

点餐结果

一份酸菜鱼

工厂方法模式

简单工厂方法有以下几个问题

  • 工厂类负责创建所有的类,如果工厂类出现问题则整个系统出现问题
  • 新增加新产品就需要在工厂类中修改逻辑
  • 过多的产品会导致工厂类代码过于复杂

所以在业务复杂时,提出了工厂方法模式。将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。

这里以餐厅发展分店为例,其中每一个分店都可能有自己的特色产品,所有每一个分店都会有一个自己的工厂类。而我们将总店的工厂类变为抽象类,具体的菜品生成实现由各个分店工厂类自行实现。

总店的工厂类

public abstract class RestaurantFactory {
    //点菜
    public abstract Cooker getCook(int cookName);

}

餐厅A的工厂类,需继承总店工厂类

public class RestaurantA extends RestaurantFactory{
    public static final int FISH=1;
    public static final int MEAT=2;
    //点菜
    public Cooker getCook(int cookName)
    {
        switch (cookName)
        {
            case FISH:
                return new Fish();
            case MEAT:
                return new Meat();
            default:
                return null;
        }
    }
}

餐厅B工厂类

public class RestaurantB extends RestaurantFactory{
    public static final int MEAT=2;
    public static final int VEGETABLE=3;
    //点菜
    public Cooker getCook(int cookName)
    {
        switch (cookName)
        {
            case MEAT:
                return new Meat();
            case VEGETABLE:
                return new Vegetable();
            default:
                return null;
        }
    }
}

测试类

    @Test
    public void simpleFactoryTest()
    {
        //获取工厂实例,类似服务员
        RestaurantFactory restaurantFactoryA = new RestaurantA();
        Cooker cookerA = restaurantFactoryA.getCook(RestaurantA.FISH);
        cookerA.cook();
        RestaurantFactory restaurantFactoryB = new RestaurantB();
        Cooker cookerB = restaurantFactoryB.getCook(RestaurantB.MEAT);
        cookerB.cook();
    }

测试结果

一份酸菜鱼
一份小炒

抽象工厂模式

抽线工厂模式则是对工厂方法模式的最上层维度进行进一步的扩展,主要用于解决将产品分为多个产品族,每一个产品族都交由对应的工厂负责。

以经营餐厅的例子来说。这里我引入美团外卖来作为最上层的抽象工厂,美团外卖中可能会有不同的业务(产品族),然后每个业务都有自己的产品类,业务中也会有不同的品牌,品牌有自己的产品及工厂

具体例子
美团外卖中存在外卖点餐业务,其中可以点餐的餐厅有餐厅A与餐厅B,两者分别有两个不同的菜。

点餐业务(产品族)抽象类

public abstract class Eat {
    public abstract void cook();
}

有两家餐厅,A与B

//A品牌店
public abstract class RestaurantTypeA extends Eat{
}
//B品牌店
public abstract class RestaurantTypeB extends Eat{
}

餐厅A的菜品有鱼和肉

public class AFIsh extends RestaurantTypeA {
    @Override
    public void cook() {
        System.out.println("用户点了A餐厅的酸菜鱼");
    }
}
public class AMeat extends RestaurantTypeA {
    @Override
    public void cook() {
        System.out.println("用户点了A餐厅的小炒肉");
    }
}

餐厅B的菜品有鱼和蔬菜

public class BFish extends RestaurantTypeB {
    @Override
    public void cook() {
        System.out.println("用户点了B餐厅的红烧鲈鱼");
    }
}
public class BVegetable extends RestaurantTypeB {
    @Override
    public void cook() {
        System.out.println("用户点了B餐厅的白灼菜心");
    }
}

然后是对应的工厂类,用来创建产品族产品

首先是抽象工厂类

//最高级抽象工厂,美团
public abstract class MeiTuan {
    public abstract Eat getCook(String cookName) throws ClassNotFoundException, IllegalAccessException, InstantiationException;
}

品牌A的工厂类

public class RestaurantFactoryA extends MeiTuan {
    @Override
    public Eat getCook(String cookName) throws ClassNotFoundException,
            IllegalAccessException, InstantiationException{
            Class dish=Class.forName(cookName);
            return (RestaurantTypeA)dish.newInstance();
    }
}

品牌B的工厂类

public class RestaurantFactoryB extends MeiTuan {
    @Override
    public Eat getCook(String cookName) throws ClassNotFoundException,
            IllegalAccessException, InstantiationException{
        Class dish=Class.forName(cookName);
        return (RestaurantTypeB)dish.newInstance();
    }
}

超级工厂类,用来创建工厂的类

public class FactoryProducer {
    public static MeiTuan getFactory(String name) throws IllegalAccessException, InstantiationException, ClassNotFoundException
    {
        Class cl = Class.forName(name);
        System.out.println("创建工厂"+name);
        return (MeiTuan)cl.newInstance();
    }
}

测试用例

  @Test
    public void abstractFactoryTest()throws IllegalAccessException,
            InstantiationException, ClassNotFoundException
    {
        //获取工厂(餐厅)实例
        MeiTuan factory = FactoryProducer.getFactory("com.java.design.dal.po.factory.RestaurantFactoryA");
        Eat ADish = factory.getCook("com.java.design.dal.po.factory.AFIsh");
        ADish.cook();
        Eat ADish1 = factory.getCook("com.java.design.dal.po.factory.AMeat");
        ADish1.cook();
        MeiTuan factory1 = FactoryProducer.getFactory("com.java.design.dal.po.factory.RestaurantFactoryB");
        Eat BDish = factory1.getCook("com.java.design.dal.po.factory.BFish");
        BDish.cook();
        Eat BDish1 = factory1.getCook("com.java.design.dal.po.factory.BVegetable");
        BDish1.cook();
    }

测试结果

创建工厂com.java.design.dal.po.factory.RestaurantFactoryA
用户点了A餐厅的酸菜鱼
用户点了A餐厅的小炒肉
创建工厂com.java.design.dal.po.factory.RestaurantFactoryB
用户点了B餐厅的红烧鲈鱼
用户点了B餐厅的白灼菜心

可以看出来,抽象工厂中可能会有多个产品族(我这里只举了一个),然后每个产品族会有对应的工厂去生产。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值