23种设计模式之工厂模式

披萨项目为例,使用工厂模式设计

需求:方便披萨品种扩展,便于维护,要能运行时扩展

披萨族(组)设计类图

假设只有原料不同,其他操作如烘焙、切割、打包相同,就把prepare方法设置为抽象方法

一般设计如下

//披萨族抽象类
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族抽象类

public class CheesePizza extends Pizza {
    public void prepare() {
        super.setName("CheesePizza");
        System.out.println(name + " preparing;");
    }
}

CheesePizza extends Pizza

public class GreekPizza extends Pizza {
    public void prepare() {
        super.setName("GreekPizza");
        System.out.println(name + " preparing;");
    }
}

GreekPizza extends Pizza

public class PepperPizza extends Pizza {
    public void prepare() {
        super.setName("PepperPizza");
        System.out.println(name + " preparing;");
    }
}

PepperPizza extends Pizza

public class OrderPizza {

    public OrderPizza() {
        Pizza pizza = null;
        String orderType;
        do {
            orderType = getType();
            if (orderType.equals("cheese")) {
                pizza = new CheesePizza();
            } else if (orderType.equals("greek")) {
                pizza = new GreekPizza();
            } else if (orderType.equals("pepper")) {
                pizza = new PepperPizza();
            } else {
                break;
            }
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        } while (true);
    }

    private String getType() {
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type:");
            String pizzaType = bufferedReader.readLine();
            return pizzaType;
        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
    }

}

OrderPizza 用户通过输入pizza类型来点pizza

public class PizzaStore {

    public static void main(String[] args){
        OrderPizza orderPizza;
        orderPizza=new OrderPizza();
    }

}

pizza商店应用PizzaStore

这种设计有个问题就是,如果有新品种,那就要在披萨族中添加(即实现Pizza抽象类),再在OrderPizza类中添加else if判断,同样如果删除披萨品种也要修改这两个地方

简单工厂模式就可以把OrderPizza中创建Pizza部分(if else 变化 部分)抽出来

1、简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为

public class SimplePizzaFactory {

    public Pizza createPizza(String orderType){
        Pizza pizza=null;
        if (orderType.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (orderType.equals("greek")) {
            pizza = new GreekPizza();
        } else if (orderType.equals("pepper")) {
            pizza = new PepperPizza();
        }
        return pizza;
    }

}

在OrderPizza中抽取出来的方法封装成简单工厂SimplePizzaFactory

public class OrderPizza {

    SimplePizzaFactory simplePizzaFactory;

    public OrderPizza(SimplePizzaFactory simplePizzaFactory) {
        setFactory(simplePizzaFactory);
    }

    public void setFactory(SimplePizzaFactory simplePizzaFactory) {
        this.simplePizzaFactory = simplePizzaFactory;
        Pizza pizza = null;
        String orderType;
        do {
            orderType = getType();
            pizza = simplePizzaFactory.createPizza(orderType);
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        } while (true);
    }

    private String getType() {
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type:");
            String pizzaType = bufferedReader.readLine();
            return pizzaType;
        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
    }
}

OrderPizza 改造后,就要使用简单工厂创建披萨实例

OrderPizza 改造后,就要使用简单工厂创建披萨实例

public class PizzaStore {

    public static void main(String[] args){
        OrderPizza orderPizza;
        orderPizza=new OrderPizza(new SimplePizzaFactory());
    }

}

PizzaStore 传入简单工厂实例对象

这样的简单工厂设计,增删披萨品种时只需在披萨族中增删披萨种类,和修改披萨工厂中方法,不需要改OrderPizza类

2、工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类

假如要在伦敦和纽约开披萨分店,地域特色不同,披萨工厂也就不同了,也就是工厂是可变的了,那么为了不让OrderPizza类依赖于工厂,就把制作pizza方法变为抽象方法,OrderPizza类也就是抽象类了,也就是把工厂的实现放到子类去实现,伦敦工厂实现伦敦工厂方法,纽约工厂实现纽约工厂方法

开始有个Pizza族,现在又有个Pizza工厂族,即OrderPizza

工厂方法模式设计方案:将披萨项目里的披萨对象实例化功能抽象成抽象方法,在不同加盟店具体实现功能

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);
    }

    public abstract Pizza createPizza(String orderType);

    private String getType() {
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type:");
            String orderType = bufferedReader.readLine();
            return orderType;
        } catch (Exception ex) {
            ex.printStackTrace();
            return "";
        }
    }
}

abstract class OrderPizza里面有abstract Pizza createPizza(String orderType)

public class LDCheesePizza extends Pizza {
    public void prepare() {
        super.setName("LDCheesePizza");
        System.out.println(name+" preparing;");
    }
}

LDCheesePizza extends Pizza

public class LDPepperPizza extends Pizza {
    public void prepare() {
        super.setName("LDPepperPizza");
        System.out.println(name+"preparing;");
    }
}

LDPepperPizza extends Pizza

public class NYCheesePizza extends Pizza {
    public void prepare() {
        super.setName("NYCheesePizza");
        System.out.println(name+"preparing;");
    }
}

NYCheesePizza extends Pizza

public class NYPepperPizza extends Pizza {
    public void prepare() {
        super.setName("NYPepperPizza");
        System.out.println(name+"preparing;");
    }
}

NYPepperPizza extends Pizza

public class LDOrderPizza extends OrderPizza {
    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;
    }
}

LDOrderPizza extends OrderPizza

public class NYOrderPizza extends OrderPizza {
    public Pizza createPizza(String orderType) {
        Pizza pizza=null;

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

NYOrderPizza extends OrderPizza

public class PizzaStore {

    public static void main(String[] args){
        OrderPizza orderPizza;
//        orderPizza=new LDOrderPizza();
        orderPizza=new NYOrderPizza();
    }
}

PizzaStore

简单工厂和工厂方法模式,看上去没有大的区别,但是在大型项目中,工厂方法模式就比较好,灵活性比较好点

3、抽象工厂模式:定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类(简单工厂演化)

public interface AbsFactory {

    Pizza createPizza(String orderType);

}

interface AbsFactory工厂接口

public class LDFactory implements AbsFactory {
    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;
    }
}

LDFactory implements AbsFactory

public class NYFactory implements AbsFactory {
    public Pizza createPizza(String orderType) {
        Pizza pizza=null;

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

NYFactory implements AbsFactory

public class OrderPizza {

    private AbsFactory absFactory;

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

    public void setFactory(AbsFactory factory) {
        Pizza pizza = null;
        String orderType;

        this.absFactory = factory;

        do {
            orderType=getType();
            pizza=absFactory.createPizza(orderType);

            if(pizza!=null){
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }
        } while (true);
    }

    public String getType() {
        try {
            BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type:");
            String orderType=bufferedReader.readLine();
            return orderType;
        }catch (Exception ex){
            ex.printStackTrace();
            return "";
        }
    }
}

OrderPizza

public class PizzaStore {

    public static void main(String[] args){
        AbsFactory absFactory;
        OrderPizza orderPizza;
        absFactory=new LDFactory();
        orderPizza=new OrderPizza(absFactory);
    }

}

PizzaStore

4、依赖抽象原则

变量不要持有具体类的引用

不要让类继承自具体类,要继承自抽象类或接口

不要覆盖基类中已实现的方法

原文地址:https://www.cnblogs.com/hujiapeng/p/8075488.html

时间: 2024-11-09 05:57:23

23种设计模式之工厂模式的相关文章

Java经典23种设计模式之创造型模式(二)

本文记录5种创造型模式的剩下两种:建造者模式(Builder).原型模式(PROTOTYPE). 一.建造者模式(别名:生成者模式) 将复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示.一个完整的建造者模式包含以下几个概念: 1.产品类 Product public class Person { private String head; private String body; private String foot; public String getHead() { ret

Spring 实现两种设计模式:工厂模式和单态模式

在Spring 中大量使用的以下两种设计模式:工厂模式和单态模式. 工厂模式可将Java 对象的调用者从被调用者的实现逻辑中分离出来,调用者只需关心被调用者必须满足的规则(接口) ,而不必关心实例的具体实现过程.这是面向接口编程的优势,能提高程序的解耦,避免所有的类以硬编码方式耦合在一起. 如果所有的类直接耦合,极易形成"骨牌效应",假如B 类调用了A 类,一旦A 类需要修改,则B 类也需要修改:假如C 类调用了B 类,则C 类也需要修改......依次类推,从而导致整个系统都需要改写

JAVA开发的23种设计模式之 --- 桥接模式

桥接模式 概述:将抽象部分与他的实现部分分离,这样抽象化与实现化解耦,使他们可以独立的变化.如何实现解耦的呢,就是通过提供抽象化和实现化之间的桥接结构.    应用场景        实现系统可能有多个角度分类,每一种角度都可能变化.    解释:桥接模式将继承模式转化成关联关系,他降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量.    理解抽象化,实现化,解耦        抽象化:将复杂物体的一个或几个共同的特性抽出去而只注意其他特性的行动或过程.在java面向对象中抽象化就

23种设计模式(1) - 工厂方法模式

1.定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 2.举例 有一个Animal接口,有两个类Dog和Cat分别继承了该接口.我们通过一个叫AnimalDactory的工厂类接口,再定义DogFactory和CatFactory类来分别创建Dog和Cat实例,由调用端来决定使用哪个工厂来创建对象. 3.代码 // 创建 动物 接口 public interface Animal { void sayName(); } // 创建 猫和狗 类 p

Java经典23种设计模式之创造型模式(一)

设计模式被称为程序猿的内功,之前零零散散的看过一大部分,但自己么有总结过.故此次在这里总结下.值得一提的是,设计模式并不是Java所特有.由于一直搞Android.这里就用Java为载体.最经典的设计模式有23种,分三个大类型: 创建型模式(5) .结构型模式(7).行为型模式(11),5 + 7 +11 = 23.网上一搜也都是一大把了,这里不过个人作的记录.本文记录创造型模式里的工厂方法(Factory Method).抽象工厂(Abstract Factory).单例模式这三种.力求透彻.

24种设计模式--抽象工厂模式【Abstract Factory Pattern】

女娲造人,人是造出来了,世界是热闹了,可是低头一看,都是清一色的类型,缺少关爱.仇恨.喜怒哀乐等情绪,人类的生命太平淡了,女娲一想,猛然一拍脑袋,忘记给人类定义性别了,那怎么办?抹掉重来,然后就把人类重新洗牌,准备重新开始制造人类. 由于先前的工作已经花费了很大的精力做为铺垫,也不想从头开始了,那先说人类(Product 产品类)怎么改吧,好,有了,给每个人类都加一个性别,然后再重新制造,这个问题解决了,那八卦炉怎么办?只有一个呀,要么生产出全都是男性,要不都是女性,那不行呀,有了,把已经有了一

java23种设计模式之一: 工厂模式

工厂模式 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象. 介绍 意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行. 主要解决:主要解决接口选择的问题. 何时使用:我们明确地计划不同条件下创建不同实例时. 如何解决:让其子类实现工厂接口,返回的

23种设计模式之原型模式(Prototype)

在系统开发过程中,有时候有些对象需要被频繁创建,原型模式通过给出一个原型对象来指明所要创建的对象的类型,然后通过复制这个原型对象的办法,创建出更多同类型的对象.原型模式是一种对象创建型模式,用原型实例制定创建对象的种类,并且通过复制这些原型创建新的对象.原型模式又可分为两种:浅克隆和深克隆.浅克隆仅仅复制所考虑的对象,而不复制它所引用的对象,也就是其中的成员对象并不复制:深克隆除了对象本身被复制外,对象包含的引用也被复制,即成员对象也被复制. 优点: 1)可以在运行时添加或删除产品. 2)通过改

23种设计模式(19)---Command模式

命令(Command)模式属于对象的行为模式[GOF95].命令模式又称为行动(Action)模式或交易(Transaction)模式.命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 命令模式是对命令的封装.命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象. 每一个命令都是一个操作:请求的一方发出请求要求执行一个操作:接收的一方收到请求,并执行操作.命令模式允许请求的一方和接收的