工厂模式(二)

1.工厂方法模式

接着简单工厂模式,我们来看工厂方法模式。
先看一个新的需求:披萨项目有了新的需求,客户在下单披萨时可以选择下单不同地区不同口味的pizza,比如北京的奶酪pizza,伦敦的胡椒pizza等。

我们可以像前面简单工厂模式一样,分别创建多个不同地区的简单工厂类。比如BJPizzaSimpleFactory,LDPizzaSimpleFactory等。但是这样在实际开发中软件的可维护性和可扩展性并不好。
因此,我们可以采用工厂方法模式

工厂方法模式介绍:
将pizza对象的实例化功能抽象为抽象方法,在不同口味的点餐子类中实现,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。

pizza抽象类:

package factory.factorymethod.pizzastore.pizza;

/**
 * @Author Worm
 * @Date 2020/8/10 10:02
 * @Version 1.0
 **/
public abstract class Pizza {
    protected String name;

    public abstract void prepare();

    public void bake() {
        System.out.println(name + " baking;");
    }

    public void cut() {
        System.out.println(name + " cutting;");
    }

    public void box() {
        System.out.println(name + " boxing;");
    }

    public void setName(String name) {
        this.name = name;
    }
}

一个pizza子类的例子,实际上有多个。

package factory.factorymethod.pizzastore.pizza;

/**
 * @Author Worm
 * @Date 2020/8/10 14:43
 * @Version 1.0
 **/
public class BJCheesePizza extends Pizza {
    @Override
    public void prepare() {
        setName("北京奶酪pizza");
        System.out.println("北京奶酪pizza准备原材料");
    }
}

OrderPizza类里实现一个抽象方法,由具体的子类去实现。

package factory.factorymethod.pizzastore.order;

import factory.factorymethod.pizzastore.pizza.Pizza;
import factory.simplefactory.pizzastore.order.SimpleFactory;
import factory.simplefactory.pizzastore.pizza.CheesePizza;
import factory.simplefactory.pizzastore.pizza.GreekPizza;
import factory.simplefactory.pizzastore.pizza.PepperPizza;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @Author Worm
 * @Date 2020/8/10 10:08
 * @Version 1.0
 **/
public abstract class OrderPizza {
    public OrderPizza() {
        Pizza pizza = null;
        String orderType;
        do {
            orderType = gettype();
            pizza = createPizza(orderType);/*抽象方法,由工厂子类完成*/
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        } while (true);
    }

    private String gettype() {
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    //定义一个抽象方法,让各个工厂子类自己实现
    abstract Pizza createPizza(String orderType);

}

不同的OrderPizza子类:

package factory.factorymethod.pizzastore.order;

import factory.factorymethod.pizzastore.pizza.BJCheesePizza;
import factory.factorymethod.pizzastore.pizza.BJPepperPizza;
import factory.factorymethod.pizzastore.pizza.Pizza;

/**
 * @Author Worm
 * @Date 2020/8/10 14:55
 * @Version 1.0
 **/
public class BJOrderPizza extends OrderPizza {
    @Override
    Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if (orderType.equals("cheese")) {
            pizza = new BJCheesePizza();

        } else if (orderType.equals("pepper")) {
            pizza = new BJPepperPizza();
        }
        return pizza;
    }
}
package factory.factorymethod.pizzastore.order;

import factory.factorymethod.pizzastore.pizza.*;


/**
 * @Author Worm
 * @Date 2020/8/10 14:55
 * @Version 1.0
 **/
public class LDOrderPizza extends OrderPizza {
    @Override
    Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if (orderType.equals("cheese")) {
            pizza = new LDCheesePizza();

        } else if (orderType.equals("pepper")) {
            pizza = new LDPepperPizza();
        }
        return pizza;
    }
}

客户端:

package factory.factorymethod.pizzastore.order;

/**
 * @Author Worm
 * @Date 2020/8/10 15:00
 * @Version 1.0
 **/
public class PizzaStore {
    public static void main(String[] args) {
//创建北京口味的各种pizza
//        new BJOrderPizza();
        new LDOrderPizza();
    }
}

2.抽象工厂模式

同样的,与工厂方法模式类似,我们也可以采用抽象工厂模式。

抽象工厂模式:是对简单工厂模式的进一步改进和抽象。它将工厂抽象为两层,ABSFactory(抽象工厂)和具体的工厂子类,程序员可以根据项目创建对应的工厂子类,将单个的简单工厂变为工厂簇。

pizza基类及其子类与前面相同。

抽象工厂接口:

package factory.absfactory.pizzastore.order;

import factory.absfactory.pizzastore.pizza.Pizza;

/**
 * @Author Worm
 * @Date 2020/8/10 15:35
 * @Version 1.0
 **/
//一个抽象工厂模式的抽象层
public interface ABSFactory {

    Pizza createPizza(String orderType);
}

各个工厂子类:

package factory.absfactory.pizzastore.order;

import factory.absfactory.pizzastore.pizza.BJCheesePizza;
import factory.absfactory.pizzastore.pizza.BJPepperPizza;
import factory.absfactory.pizzastore.pizza.Pizza;


/**
 * @Author Worm
 * @Date 2020/8/10 15:36
 * @Version 1.0
 **/
public class BJFactory implements ABSFactory {
    @Override
    public Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if (orderType.equals("cheese")) {
            pizza = new BJCheesePizza();
        } else if (orderType.equals("pepper")) {
            pizza = new BJPepperPizza();
        }
        return pizza;
    }
}
package factory.absfactory.pizzastore.order;

import factory.absfactory.pizzastore.pizza.*;


/**
 * @Author Worm
 * @Date 2020/8/10 15:36
 * @Version 1.0
 **/
public class LDFactory implements ABSFactory {
    @Override
    public Pizza createPizza(String orderType) {
        Pizza pizza = null;
        if (orderType.equals("cheese")) {
            pizza = new LDCheesePizza();
        } else if (orderType.equals("pepper")) {
            pizza = new LDPepperPizza();
        }
        return pizza;
    }
}

OrderPizza:

package factory.absfactory.pizzastore.order;

import factory.absfactory.pizzastore.pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @Author Worm
 * @Date 2020/8/10 15:44
 * @Version 1.0
 **/
public class OrderPizza {
    ABSFactory absFactory;

    public OrderPizza(ABSFactory absFactory) {
        setFactory(absFactory);
    }

    private void setFactory(ABSFactory factory) {
        System.out.println("使用抽象工厂模式");
        Pizza pizza = null;
        String orderType = "";
        absFactory = factory;
        do {
            orderType = gettype();
            //这里根据需要传入的可能会是不同的工厂子类
            pizza = absFactory.createPizza(orderType);
            if (pizza != null) {
                pizza.prepare();
                pizza.bake();
                pizza.box();
                pizza.cut();
            } else {
                System.out.println("订购失败");
                break;

            }
        } while (true);
    }


    private String gettype() {
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type:");
            String str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}

客户端:

package factory.absfactory.pizzastore.order;

/**
 * @Author Worm
 * @Date 2020/8/10 15:58
 * @Version 1.0
 **/
public class PizzaStore {
    public static void main(String[] args) {
//        new OrderPizza(new BJFactory());
        new OrderPizza(new LDFactory());
    }
}

3.源码分析

工厂模式在JDK-Calendar中的应用
Calendar cal = Calendar.getInstance();
进入createCalendar方法
在这里插入图片描述
运用了简单工厂模式在这里插入图片描述

4.工厂模式总结

工厂模式的意义在于将实例化的代码提取出来,放到一个类中统一管理维护,使之与主项目解耦,提高项目的扩展性和维护性。
工厂模式有三种实现形式:简单工厂模式,工厂方法模式,抽象工厂模式。

遵循了设计模式的依赖抽象原则:
创建对象实例时不直接new而是将该动作放在一个工厂的方法中并返回(也称之为变量不要直接持有具体类的引用)。
不要让类继承具体类,而要继承抽象类或实现接口。
以及不要覆盖基类中以实现的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值