每日设计模式-工厂模式

工厂模式

概念

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

举一个简单的栗子

需求

假设现在我们正在开一家比萨店,店里有许多的种类的披萨, 比如奶油披萨,虾仁披萨。每个披萨都需要经过准备,制作,切割,包装四个步骤。最后我们需要在一个前台中将披萨销售出去

简易类图

在这里插入图片描述

简易实现

  • Pizza

    package factory.model;
    
    public abstract class Pizza {
        private String name;
    
        public Pizza(String name){
            this.name = name;
        }
    
        public void prepare(){
            System.out.println(name + "正在准备");
        }
    
        public void make(){
            System.out.println(name + "正在制作");
        }
    
        public void cut(){
            System.out.println(name + "正在切割");
        }
        public void pack(){
            System.out.println(name + "正在打包");
        }
    }
    

    这是一个抽象类,所有的披萨都继承这个类。

  • MilkPizza

    package factory.model;
    
    public class MilkPizza extends Pizza{
        public MilkPizza() {
            super("牛奶披萨");
        }
    }
    
  • ShrimpPizza

    package factory.model;
    
    public class ShrimpPizza extends Pizza {
        public ShrimpPizza() {
            super("虾仁披萨");
        }
    }
    
    
  • Order

    package factory.order;
    
    import factory.model.MilkPizza;
    import factory.model.Pizza;
    
    import java.util.Scanner;
    
    public class Order {
    
        public void orderPizza(){
            do{
                System.out.print("请输入披萨类型");
                Scanner scanner = new Scanner(System.in);
                String type = scanner.next();
                Pizza pizza = null;
                if ("milk".equals(type)){
                    pizza = new MilkPizza();
                } else if ("shrimp".equals(type)){
                	pizza = new ShrimpPizza();
            	}
                if(pizza == null){
                    break;
                }
                pizza.prepare();
                pizza.make();
                pizza.cut();
                pizza.pack();
    
            }while (true);
        }
    
    }
    
  • PizzaStore

    package factory.store;
    
    import factory.order.Order;
    
    public class PizzaStore{
        public static void main(String[] args) {
            Order order = new Order();
            order.orderPizza();
        }
    }
    

代码分析

优点:

  • 这是最容易想到的代码
  • 整体逻辑较为清晰

缺点:

  • 比如我们现在全国有128家门店,突然总部提出新增一个板栗披萨。如果按照现在这种设计的话,我们需要修改128个orderPizza方法,这显然不切实际。

针对于以上的缺点,我们引入简单工厂设计模式

简单工厂设计模式

这种设计思想本质上,就是在Order类与Pizza类之间加一个缓冲层,让工厂去接管创建Pizza的功能

代码修改

  • SimpleFactory

    package factory;
    
    import factory.model.MilkPizza;
    import factory.model.Pizza;
    import factory.model.ShrimpPizza;
    
    public enum  SimpleFactory {
    
        SIMPLE_FACTORY;
    
        public Pizza createPizza(String type){
            Pizza pizza = null;
            if ("milk".equals(type)){
                pizza = new MilkPizza();
            } else if ("shrimp".equals(type)){
                pizza = new ShrimpPizza();
            }
            return pizza;
        }
    }
    
  • Order

    package factory.order;
    
    import factory.SimpleFactory;
    import factory.model.Pizza;
    
    import java.util.Scanner;
    
    public class Order {
    
        public void orderPizza(){
    
            do{
                System.out.print("请输入披萨类型");
                Scanner scanner = new Scanner(System.in);
                String type = scanner.next();
                Pizza pizza = SimpleFactory.SIMPLE_FACTORY.createPizza(type);
                if(pizza == null){
                    break;
                }
                pizza.prepare();
                pizza.make();
                pizza.cut();
                pizza.pack();
    
            }while (true);
        }
    
    }
    

缺点

  • 虽然解决了无法统一创建披萨的问题。但是也带来了新的问题。
    • 如果存在两个门店,一个门店有胡椒披萨,而另一个门店没有胡椒披萨。这个时候当前的设计模式现在无法满足需求

工厂方法模式

定义一个抽象的创建对象方法,借由子类决定实例化的类。

  • AbstractOrder

    package factory.order;
    
    import factory.SimpleFactory;
    import factory.model.Pizza;
    
    import java.util.Scanner;
    
    public abstract class AbstractOrder {
    
        public void orderPizza(){
            do{
                System.out.print("请输入披萨类型");
                Scanner scanner = new Scanner(System.in);
                String type = scanner.next();
                Pizza pizza = create(type);
                if(pizza == null){
                    break;
                }
                pizza.prepare();
                pizza.make();
                pizza.cut();
                pizza.pack();
    
            }while (true);
        }
    
        protected abstract Pizza create(String type);
    }
    
  • BeijingOrder

    package factory.order;
    
    import factory.model.MilkPizza;
    import factory.model.PepperPizza;
    import factory.model.Pizza;
    import factory.model.ShrimpPizza;
    
    public class BeijingOrder extends AbstractOrder {
        @Override
        protected Pizza create(String type) {
            Pizza pizza = null;
            if ("milk".equals(type)){
                pizza = new MilkPizza();
            } else if ("shrimp".equals(type)){
                pizza = new ShrimpPizza();
            }else if ("pepper".equals(type)){
                pizza = new PepperPizza();
            }
            return pizza;
        }
    }
    
  • ShanghaiOrder

    package factory.order;
    
    import factory.model.MilkPizza;
    import factory.model.Pizza;
    import factory.model.ShrimpPizza;
    
    public class ShanghaiOrder extends  AbstractOrder {
        @Override
        protected Pizza create(String type) {
            Pizza pizza = null;
            if ("milk".equals(type)){
                pizza = new MilkPizza();
            } else if ("shrimp".equals(type)){
                pizza = new ShrimpPizza();
            }
            returnpizza;
        }
    }
    
  • PizzaStore

    package factory.store;
    
    import factory.order.AbstractOrder;
    import factory.order.BeijingOrder;
    
    public class PizzaStore{
        public static void main(String[] args) {
            AbstractOrder beijing = new BeijingOrder();
            beijing.orderPizza();
        }
    }
    

抽象工厂模式

这个模式可以看作工厂方法模式与简单工厂模式的结合。它将创建Pizza的类抽象成一个接口,所有需要用到创建Pizza功能的类都去实现这个接口。

  • IFactory

    package factory;
    
    import factory.model.Pizza;
    
    public interface IFactory {
    
        Pizza create(String type);
    }
    
    
  • BeiJingFactory

    package factory;
    
    import factory.IFactory;
    import factory.model.MilkPizza;
    import factory.model.PepperPizza;
    import factory.model.Pizza;
    import factory.model.ShrimpPizza;
    
    public class BeiJingFactory implements IFactory {
        @Override
        public Pizza create(String type) {
            Pizza pizza = null;
            if ("milk".equals(type)){
                pizza = new MilkPizza();
            } else if ("shrimp".equals(type)){
                pizza = new ShrimpPizza();
            }else if ("pepper".equals(type)){
                pizza = new PepperPizza();
            }
            return pizza;
        }
    }
    
    
  • Order

    package factory.order;
    
    import factory.IFactory;
    import factory.model.Pizza;
    
    import java.util.Scanner;
    
    public class Order {
    
        public void orderPizza(IFactory factory){
    
            do{
                System.out.print("请输入披萨类型");
                Scanner scanner = new Scanner(System.in);
                String type = scanner.next();
                Pizza pizza = factory.create(type);
                if(pizza == null){
                    break;
                }
                pizza.prepare();
                pizza.make();
                pizza.cut();
                pizza.pack();
    
            }while (true);
        }
    
    }
    
  • PizzaStore

    package factory.store;
    
    import factory.BeiJingFactory;
    import factory.order.Order;
    
    public class PizzaStore{
        public static void main(String[] args) {
            Order order = new Order();
            order.orderPizza(new BeiJingFactory());
        }
    }
    
    

说明

   pizza.pack();

      }while (true);
  }

}




- `PizzaStore`

```java
package factory.store;

import factory.BeiJingFactory;
import factory.order.Order;

public class PizzaStore{
    public static void main(String[] args) {
        Order order = new Order();
        order.orderPizza(new BeiJingFactory());
    }
}

说明

  • 这种方式较之前两种更具备拓展性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值