Head First Design Patterns——简单工厂模式(静态工厂)

在本篇文章中,有关于UML类图的基本知识,如果有还不太清楚的可以参照:

UML的正确食用方式————正解!!

在我们实例化对象时,第一个想到的就是new对象,没有房子,new一个,没有女朋友,new一个甚至好多个。new对象就是和类之间建立了耦合关系,如果有很多的对象,那么类与对象间就形成了强耦合,灵活性就变差了,所以,一般我们在开发过程中都是面向"接口"编程的,通过多态,可以与任何新类实现该接口。但是,同样,代码量太大,就搞不定了!那么除了new就再没有其他的办法了吗?这就涉及到了设计模式的设计:

用户在测试类中指定要创建的类型:

大家先看类图:
在这里插入图片描述

说明:Pizza类为抽象类,然后 CheesePizza和ClamPizza继承Pizza类并且重写prepare方法,然后,在SimpleFactory简单工厂中根据类型来创建指定的Pizza,然后在PizzStore中组合SimpleFactory,用户要什么Pizza,就在PizzaStore中告诉,然后让SimpleFactory造一个指定类型的,它本身并不用关心要什么类型的Pizza。不论什么Pizza最后都要bake,cut,box操作,在SimpleFactory创建完Pizza后,PizzaStore就执行bake,cut,box。当然会有同学问,如果再增加一个种类的Pizza呢,这时我们就可以在SimpleFactory中添加就搞定了,做到了“对扩展开放,对修改关闭”,满口了ocp原则!下面来看具体的实现过程

  • Pizza
public abstract class Pizza {

    private String name;
    public abstract void prepare();

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

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

}
  • ClamPizza
public class ClamPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("加入ClamPizza调料");
    }
}
  • CheesePizza
public class CheesePizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("加入CheesePizza调料");
    }
}

  • SimpleFactory
public  class SimpleFactory {

    public Pizza createPizza(String type){
        Pizza pizza = null;

        if (type.equals("Clam")){
            pizza = new ClamPizza();
            pizza.setName(type);
        }else if (type.equals("Cheese")){
            pizza = new CheesePizza();
            pizza.setName(type);
        }
        return pizza;
    }
}
  • PizzaStore
public class PizzaStore {

    SimpleFactory simpleFactory;

    public void setSimpleFactory(SimpleFactory simpleFactory) {
        this.simpleFactory = simpleFactory;
    }

    public Pizza orderPizza(String type, SimpleFactory simpleFactory){
        Pizza pizza;

        pizza = simpleFactory.createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;

    }
}
  • TestPizza
public class TestPizza {
    public static void main(String[] args) {

        //新建一个PizzaStore用来卖Pizza
        PizzaStore pizzaStore = new PizzaStore();

        //传入要买的类型,并且要有一个工厂
        pizzaStore.orderPizza("Clam",new SimpleFactory());
    }
}
  • 测试结果
    在这里插入图片描述

用户在控制台动态输入要创建的类型:

1)有两种披萨:希腊披萨(greek),奶酪披萨(cheese)
2)批萨的制作有bak,cut,box;
3)给定一个类型,创建披萨的流程

  • Pizza
//定义一个抽象的披萨类
public abstract  class Pizza {
	
	//抽象方法
    public abstract void prepare();

	//制做的工艺
    public void bake() {
        System.out.println("baking;");
    }

    public void cut() {
        System.out.println("cuting;");
    }

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

}
  • CheesePizza2
public class CheesePizza2 extends Pizza {
    @Override
    public void prepare() {
        System.out.println("给奶酪披萨准备原材料");
    }
}

  • GreekPizza2
public class GreekPizza2 extends Pizza{
    @Override
    public void prepare() {
        System.out.println("给希腊披萨准备原材料");
    }
}

  • orderPizza2
public class orderPizza2 {

    Pizza pizza = null;

    public Pizza orderPizza(String orderType){

        if (orderType.equals("greek")){
            pizza = new GreekPizza2();
        }else if (orderType.equals("cheese")){
            pizza = new CheesePizza2();
        }

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;

    }
}

  • PizzaStore
public class PizzaStore {
    public static void main(String[] args) {

        orderPizza2 orderPizza2 = new orderPizza2();
        orderPizza2.orderPizza("greek");
        orderPizza2.orderPizza("cheese");

    }
}
  • 测试

在这里插入图片描述

  • 还有类图
    在这里插入图片描述

虽然我们的功能实现了,但是当我们再加一个种类的披萨时,就要在orderPizza2 里面添加,如果能把orderPizza2 里面的根据名称创建哪种披萨的方法抽离出去,新建一个方法,专门用来创建对象,然后在orderPizza2内部聚合这个新的方法,这样做,就会对扩展开放,对修改关闭,从而满足了ocp原则,说干就干!

  • Pizza
public abstract  class Pizza {

    public abstract void prepare();

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

    public void cut() {
        System.out.println("cuting;");
    }

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

}
  • CheesePizza2
public class CheesePizza2 extends Pizza {
    @Override
    public void prepare() {
        System.out.println("经制做奶酪披萨准备原材料");
    }
}
  • GreekPizza2
public class GreekPizza2 extends Pizza{
    @Override
    public void prepare() {
        System.out.println("给希腊披萨准备原材料");
    }
}

  • SimpleFactory2
public class SimpleFactory2 {

    public Pizza createPizza(String orderType){

        Pizza pizza = null;

        if (orderType.equals("greek")){
            pizza = new GreekPizza2();
        }else if (orderType.equals("cheese")){
            pizza = new CheesePizza2();
        }

        return pizza;
    }

}
  • OrderPizza2
//定义一个生成厂商,对传入的某种披萨进行prepare,bake,cut,box操作
public class orderPizza2 {

    SimpleFactory2 simpleFactory2;

    Pizza pizza = null;

    public orderPizza2(SimpleFactory2 simpleFactory2) {
        setSimpleFactory2(simpleFactory2);
    }

    public void  setSimpleFactory2(SimpleFactory2 simpleFactory2) {

        this.simpleFactory2 = simpleFactory2;

        //获取披萨的类型是什么
        String orderType = " ";
        orderType = getype();

        pizza = simpleFactory2.createPizza(orderType);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

    }

    //写一个方法,可以获取客户端希望订购的披萨种类
    private String getype(){
        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 "";
        }
    }
}
  • PizzaStore
public class PizzaStore {

    public static void main(String[] args) {

        new orderPizza2(new SimpleFactory2());
    }
}
  • 结果

在这里插入图片描述

  • 类图表示
    在这里插入图片描述

在实例化批萨时,我们使用了一个工厂来根据类型创建批萨,在OrderPizza2里面再来实现prepare,bake,cut,box操作,如果要增加一个新的种类的批萨,只需要在工厂类中加入方法,其他的代码都不用变动,这就实现了简化 代码的目的!

在本篇文章中,有关于UML类图的基本知识,如果有还不太清楚的可以参照:

UML的正确食用方式————正解!!

如果大家觉得写的有问题可以在评论区留言!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值