您的位置:亚洲必赢 > 美食做法 > 简单工厂模式 (Simple Factory) ,但是说忙能有多忙

简单工厂模式 (Simple Factory) ,但是说忙能有多忙

2019-12-09 03:16

2,简洁

优点

简短工厂形式的工厂类是总人体模型式的重要。此中富含了必不可少的逻辑推断,依照外界消息,决定毕竟应该创造哪个具体类的指标。

因而运用简易工厂方式,顾客没有必要理解对象如何创立的,只要传入要求音讯就能够了。 

View Code

缺点

厂子类集中了富有实例的成立逻辑,违背了高内聚权利分配原则

乘势系统中具体产物类不断追加,势供给不断改善工厂类,不易维护和扩大。同一时间,那也背弃了开放密闭原则

参考:

轻易工厂形式 (Simple Factory卡塔尔国 又叫静态工厂方法(Static Factory Method)形式。 轻易工厂情势平时是...

View Code

[设计模式]轻易易行工厂方式,设计格局工厂格局

轻巧工厂格局 (Simple Factory卡塔尔国 又叫静态工厂方法(Static Factory Method)形式。

差相当的少工厂方式平常是概念一个工厂类,这么些类能够依靠分化变量重返区别类的产物实例

然则轻便工厂情势不属于23种Gof设计格局之后生可畏。  

View Code

3,分店披萨的花色与暂且与专营店保持意气风发致

 素食比萨:

披萨店更改:

/**
 * 素食比萨
 * @author skysea
 */
public class VeggiePizza extends Pizza {
    public VeggiePizza() {
        name = "素食比萨";
        dough = "素食比萨的面团";
        sauce = "素食比萨的酱料";
        toppings.add("素食比萨");
        toppings.add("素食比萨佐料1");
        toppings.add("素食比萨佐料2");
    }
}

粗略工厂方式

厂子方法情势

图片 1图片 2

/**
 * 蛤蜊披萨
 * @author skysea
 */
public class ClamPizza extends Pizza {
    public ClamPizza() {
        this.name = "蛤蜊披萨";
        this.dough = "蛤蜊披萨的面团";
        this.sauce = "蛤蜊披萨的酱料";
        this.toppings.add("蛤蜊");
    }
}

芝士披萨:

View Code

披萨店:

 

1,本人通晓了呢?

设计方式 阅世能够解决那么些标题,其余的自作者还不明白。未有资历咋做?八个要点:

1,能用

代码偷懒,前期返工多

披萨倒是列完了,不过在其实的支出进程中,业务逻辑这么轻便那是不容许的,想要改那怎样专卖店披萨的类名是很困难的

/**
 * pizza店
 * @author skysea
 */
public class PizzaStore {

    public Pizza orderPizza(String type) {
        Pizza pizza = null;
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("pepperoni")) {
            pizza = new PepperoniPizza();
        } else if (type.equals("clam")) {
            pizza = new ClamPizza();
        } else if (type.equals("veggie")) {
            pizza = new VeggiePizza();
        }

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

        return pizza;
    }

}

您知道您队友看见一群烂的看都看不懂,也一句注释都还没的代码的时候的理念阴影面积吗?

View Code

1,那么些地点为啥要弄个抽象类出来?

急需:你有八个披萨店,只卖风流倜傥种披萨,代码如下:

3,影响大非常的小

开了子集团,若是每一个子集团都以风度翩翩套完整的服务在玩,丢个string,要比枚举来得好。原因有2:传输进程中的连串化和反系列化、更灵敏(顾客端不用每趟都因为这一个原因要去升高对应的包,特别是多少个本子在跑得时候,进级了又会促成别的东西不能够玩)

Pizza类的改革

今天内需改的是多个地点,二个是工厂类,叁个是枚举,可是根本的流程是不要改了,假使你认为依旧很费劲在不寻思质量的处境下,你还是能用反射来玩,改动一下厂子类(落成通过class来成立对象卡塔尔国和枚举(增多四个字段来贮存type对应的class)就足以了,不赘述..

每趟想到写风度翩翩篇新的设计形式,小编总会问自个儿:

超负荷设计,中期返工多

/**
 * 披萨店抽象类
 * @author skysea
 */
public abstract class PizzaStore {

    abstract Pizza createPizza(String item);

    public Pizza orderPizza(String type) {
        Pizza pizza = createPizza(type);
        System.out.println("--- 制作 "   pizza.getName()   " ---");
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

/**
 * 芝加哥披萨店
 * @author skysea
 */
public class ChicagoPizzaStore extends PizzaStore {
    public static final String CHEESE = "cheese";
    public static final String VEGGIE = "veggie";
    public static final String CLAM = "clam";
    public static final String PEPPERONI = "pepperoni";
    Pizza createPizza(String item) {
        if (CHEESE.equals(item)) {
            return new ChicagoStyleCheesePizza();
        } else if (VEGGIE.equals(item)) {
            return new ChicagoStyleVeggiePizza();
        } else if (CLAM.equals(item)) {
            return new ChicagoStyleClamPizza();
        } else if (PEPPERONI.equals(item)) {
            return new ChicagoStylePepperoniPizza();
        } else {
            throw new NoSuchPizzaException(item);
        }
    }
}

假若照旧单机,用枚举当然会比直接扔个string来得稳妥。

2,你给自家新加二个xx披萨

全日逛微博,正是狠不下心来写篇博客,忙是一方面,可是说忙能有多忙吗,都临时光逛和讯,写篇博客的光阴都还未?(那还真倒霉说)

London披萨店(和洛杉矶披萨店大约一毛同样,这里就不进行了):

图片 3

SimplePizzaFactory:

import java.util.ArrayList;
import java.util.List;

/**
 * 披萨抽象类
 * 1,修改private -> protected(保证子类拥有这些属性)
 * 2,将Pizza定义为abstract类,防止被new,也是为后面的改造做准备
 * @author skysea
 */
public abstract class Pizza {

    protected String name;//披萨名称

    protected String dough;//面团

    protected String sauce;//酱料

    protected List<String> toppings = new ArrayList<>();//佐料

    void prepare() {
        System.out.println("开始准备披萨:"   name);

        System.out.print("开始处理面团:"   dough);

        System.out.println("添加酱料:"   sauce);

        System.out.println("添加佐料:");
        for(String t : toppings) {
            System.out.println(" "   t);
        }
    }

    void bake() {
        System.out.println("烘焙25分钟..");
    }

    void cut() {
        System.out.println("披萨切片..");
    }

    void box() {
        System.out.println("披萨打包..");
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Pizza [name="   name   ", dough="   dough   ", sauce="   sauce   ", toppings="   toppings   "]";
    }
}

 

测试类:

 

负有的设计方式对自个儿来讲都以为了减小工作量。关于收缩专门的学业量小编的明亮是:每一种供给,都应当在它适用的时候现身适当的代码!那么些太首要了

View Code

2,分店的披萨口味要依据本地的气味来实行调治,保证能够不失品牌特色的同有的时候候,也能满足本地极其的气韵

1,专卖店在布鲁塞尔,以后要在London开一家新的店

贴了如此多代码,先付给一波轻便的贯彻:

2,String类型的type太轻便出错了,个人以为对先后支付不本人,当然这么些也要分情形,灵活和严苛本来就很胎位非常生统筹

辅助类(枚举,异常):

意大利共和国烤肠披萨:

有关工厂形式的多少个难题

3,推荐取不到切合的type时抛非常,而不是回到空,便于逐个审查难点(此处的if里面只是一贯new再次来到的靶子,实际处境远比今后的复杂卡塔尔(英语:State of Qatar)

道理当然是那样的,笔者这里是随意造,你们呢,我就不精通了,嘿嘿嘿,所以遭遇这种境况,常常的话要悠着点,看时间,也要看影响,开荒正是这样,同二个功用,2天有2天的做法,5天有5天的做法,10天有10天的做法

View Code

这段代码有四个难点要掌握领会:

2,怎么用?

View Code

/**
 * pizza店
 * @author skysea
 */
public class PizzaStore {

    public Pizza orderPizza() {
        return orderPizza(PizzaTypeEnum.CHEESE);
    }

    public Pizza orderPizza(PizzaTypeEnum type) {
        Pizza pizza;

        pizza = SimplePizzaFactory.getPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }
}

London的披萨:

披萨:

那其实也没怎么,哪个人没填过别人的坑呢?关键是她了解你家在何地,并且还精通您时一时走夜路,就问您怕不怕?(卧槽,又跑题了。。)

/**
 * 简单工厂类
 * @author skysea
 */
public class SimplePizzaFactory {

    /**
     * 根据类型获取pizza
     * @param type
     * @return
     */
    public static final Pizza getPizza(PizzaTypeEnum type){
        switch (type) {
            case CHEESE: return new CheesePizza();
            case CLAM: return new ClamPizza();
            case PEPPERONI: return new PepperoniPizza();
            case VEGGIE: return new VeggiePizza();
            default: throw new NoSuchPizzaException(type.getCode());
        }
    }
}

1,未有宽容原本的意气风发种披萨方法 public Pizza orderPizza(卡塔尔(قطر‎,相信自身,每贰个public方法都是相当的重大的,因为您不知晓有稍许地点用到过。当然也不是不能够知道,只是你理解也不必然就能够改,纵然你能改,也不自然改对。

法兰克福的披萨:

3,不用行不行?

2,factory咋个不见了?

2,改造原本的代码有何利润,更便于精通吧?迭代了多少个版本之后垃圾代码太多了呢?

/**
 * pizza测试类
 * @author skysea
 */
public class PizzaTest {
    public static void main(String[] args) {
        PizzaStore pizzaStore = new PizzaStore();
        Pizza pizza = pizzaStore.orderPizza();
        System.out.println("当前预定的披萨:"   pizza.getName());
    }
}

付给第二版:

当今披萨店要拓宽职业了,因为卖生机勃勃种披萨顾客曾经吃腻了,今后要起来加多新的披萨类型

/**
 * 定义pizza类型枚举
 * @author skysea
 *
 */
public enum PizzaTypeEnum{
    /**
     * 芝士披萨
     */
    CHEESE("cheese"),
    /**
     * 意大利烤肠披萨
     */
    PEPPERONI("pepperoni"),
    /**
     * 蛤蜊披萨
     */
    CLAM("clam"),
    /**
     * 素食比萨
     */
    VEGGIE("veggie");
    private final String code;
    PizzaTypeEnum(String code) {
        this.code = code;
    }
    public String getCode() {
        return code;
    }
}
/**
 * 芝士披萨
 * @author skysea
 */
public class CheesePizza extends Pizza{
    public CheesePizza() {
        this.name = "芝士披萨";
        this.dough = "芝士披萨的面团";
        this.sauce = "芝士披萨的酱料";
        this.toppings.add("很多芝士....");
    }
}

View Code

1,是还是不是单机,有没有任何外界系统在调用

先把具有的披萨列出来

其大器晚成将在结合实际来精晓了,分店与分店之间,需无需统生机勃勃规范化处理?需没有要求有限援助本身的性状?答案自然,都以内需的

/**
 * pizza测试类
 * @author skysea
 */
public class PizzaTest {

    public static void main(String[] args) {
        PizzaStore store = new PizzaStore();

        Pizza pizza = store.orderPizza(PizzaTypeEnum.CHEESE);
        System.out.println(pizza);

        pizza = store.orderPizza(PizzaTypeEnum.VEGGIE);
        System.out.println(pizza);
    }
}

图片 4图片 5

图片 6 

先交给新扩大的披萨

背着做到量入为出,可是道貌岸然的放屁依旧要有吗,最少要忽悠得有层有次嘛(手动斜眼笑)

新的主题素材(开分店):

第一要达标能用,然后就是尽大概简单,那样代码就不会太差。首先你要和睦看得懂,然后是让队友看得懂。

率先波需要就基本上能够如此收手了,随着事情的演化,披萨店那叫多少个极富啊,就算中间也对代码做了成千上万新的披萨,不过出于PizzaStore特别稳固,也没出什么大主题材料。

率先个和首个难题,笔者以往就能够告知您答案:早点收工,能够

图片 7

/**
 * 纽约披萨店
 * @author skysea
 */
public class NYPizzaStore extends PizzaStore {

    public static final String CHEESE = "cheese";
    public static final String VEGGIE = "veggie";
    public static final String CLAM = "clam";
    public static final String PEPPERONI = "pepperoni";
    Pizza createPizza(String item) {
        if (CHEESE.equals(item)) {
            return new NYStyleCheesePizza();
        } else if (VEGGIE.equals(item)) {
            return new NYStyleVeggiePizza();
        } else if (CLAM.equals(item)) {
            return new NYStyleClamPizza();
        } else if (PEPPERONI.equals(item)) {
            return new NYStylePepperoniPizza();
        } else {
            throw new NoSuchPizzaException(item);
        }
    }
}

好了,代码写到这里,其实对于:新添披萨类型的那几个需要的贯彻其实早就很好了。最少来说现阶段的必要落成了,其次正是对调用方友好,最少队友不会跑过来问您类型传啥,不会告诉你他string字符串传错了,不会在您改个项目标时候,还要公告她(当然这些也足以透过常量来管理)。

测试类:

/**
 * 没有匹配的pizza异常
 * @author skysea
 */
public class NoSuchPizzaException extends RuntimeException{
    private static final long serialVersionUID = 6831396172306375611L;
    public NoSuchPizzaException(String message) {
        super(message);
    }
}

蛤蜊披萨:

图片 8图片 9

图片 10图片 11

吹了半天,来讲说这段代码的主题素材,平常意况下,须求会是如此变:

1,这些是拿来干什么的?

图片 12图片 13

/**
 * 披萨测试类
 * @author skysea
 */
public class PizzaTest {

    public static void main(String[] args) {
        PizzaStore nyStore = new NYPizzaStore();
        PizzaStore chicagoStore = new ChicagoPizzaStore();

        Pizza pizza = nyStore.orderPizza(NYPizzaStore.CHEESE);
        System.out.println("Ethan ordered a "   pizza.getName()   "n");

        pizza = chicagoStore.orderPizza(ChicagoPizzaStore.CHEESE);
        System.out.println("Joel ordered a "   pizza.getName()   "n");

        pizza = nyStore.orderPizza(NYPizzaStore.CLAM);
        System.out.println("Ethan ordered a "   pizza.getName()   "n");

        pizza = chicagoStore.orderPizza(ChicagoPizzaStore.CLAM);
        System.out.println("Joel ordered a "   pizza.getName()   "n");

        pizza = nyStore.orderPizza(NYPizzaStore.PEPPERONI);
        System.out.println("Ethan ordered a "   pizza.getName()   "n");

        pizza = chicagoStore.orderPizza(ChicagoPizzaStore.PEPPERONI);
        System.out.println("Joel ordered a "   pizza.getName()   "n");

        pizza = nyStore.orderPizza(NYPizzaStore.VEGGIE);
        System.out.println("Ethan ordered a "   pizza.getName()   "n");

        pizza = chicagoStore.orderPizza(ChicagoPizzaStore.VEGGIE);
        System.out.println("Joel ordered a "   pizza.getName()   "n");
    }
}

 测试类:

1,PepperoniPizza权且不用了,日常的话,你问他要不要,他会说,那么些要看后边的运营意况(作者:...)

开篇

图片 14图片 15

import java.util.ArrayList;
import java.util.List;

/**
 * 披萨类
 * @author skysea
 */
public class Pizza {

    private String name;//披萨名称

    private String dough;//面团

    private String sauce;//酱料

    private List<String> toppings = new ArrayList<>();//佐料

    public Pizza() {
            this.name = "原味披萨";
            this.dough = "原味面团";
            this.sauce = "原味酱料";
    }

    void prepare() {
        System.out.println("开始准备披萨:"   name);

        System.out.println("开始处理面团:"   dough);

        System.out.println("添加酱料:"   sauce);

        System.out.println("添加佐料:");
        if(toppings.size() > 0) {
            for(String t : toppings) {
                System.out.println(" "   t);
            }
        }
    }

    void bake() {
        System.out.println("烘焙25分钟..");
    }

    void cut() {
        System.out.println("披萨切片..");
    }

    void box() {
        System.out.println("披萨打包..");
    }

    public String getName() {
        return name;
    }
}

2,小编能以生龙活虎种简易且有逻辑的法子把它说出来吗?

结果(结果太多了,就不全体截图出来了):

/**
 * 只卖一种披萨的披萨店
 * @author skysea
 */
public class PizzaStore {

    public Pizza orderPizza() {
        Pizza pizza = new Pizza();
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

因为把它和切实的store归并在合作了,那样又引申出其它二个标题:为何要统后生可畏?因为store以往当作的剧中人物正是facotry,刚才说过的炮制进度已经停放父类中贯彻了,今后只须要在现实的store中去化解披萨的创导难题

3,为何又不用枚举了,弄个String来创制pizza?

图片 16图片 17

貌似要构思:

 

/**
 * 纽约芝士披萨
 * @author skysea
 */
public class NYStyleCheesePizza extends Pizza {

    public NYStyleCheesePizza() { 
        name = "纽约芝士披萨";
        dough = "纽约芝士披萨面团";
        sauce = "纽约芝士披萨酱料";

        toppings.add("纽约芝士披萨调料1");
        toppings.add("纽约芝士披萨调料2");
    }

    @Override
    void cut() {
        System.out.println("纽约芝士披萨版切片...");
    }
}
/**
 * 纽约蛤蜊披萨
 * @author skysea
 */
public class NYStyleClamPizza extends Pizza {
    public NYStyleClamPizza() {
        name = "纽约蛤蜊披萨";
        dough = "纽约蛤蜊披萨面团";
        sauce = "纽约蛤蜊披萨酱料";

        toppings.add("纽约蛤蜊披萨佐料1");
        toppings.add("纽约蛤蜊披萨佐料2");
    }

    @Override
    void cut() {
        System.out.println("纽约蛤蜊披萨版切片...");
    }
}
/**
 * 纽约意大利烤肠披萨
 * @author skysea
 */
public class NYStylePepperoniPizza extends Pizza {
    public NYStylePepperoniPizza() {
        name = "纽约意大利烤肠披萨";
        dough = "纽约意大利烤肠披萨面团";
        sauce = "纽约意大利烤肠披萨酱料";

        toppings.add("纽约意大利烤肠披萨调料1");
        toppings.add("纽约意大利烤肠披萨调料2");
        toppings.add("纽约意大利烤肠披萨调料3");
        toppings.add("纽约意大利烤肠披萨调料4");
    }

    @Override
    void cut() {
        System.out.println("纽约意大利烤肠披萨版切片...");
    }
}
/**
 * 纽约素食比萨
 * @author skysea
 */
public class NYStyleVeggiePizza extends Pizza {
    public NYStyleVeggiePizza() {
        name = "纽约素食比萨";
        dough = "纽约素食比萨的面团";
        sauce = "纽约素食比萨的酱料";

        toppings.add("纽约素食比萨调料1");
        toppings.add("纽约素食比萨调料2");
        toppings.add("纽约素食比萨调料3");
    }

    void cut() {
        System.out.println("纽约素食比萨版切片...");
    }
}

图片 18图片 19

以此地点创设披萨的历程,不容置疑是断定要长期以来的。犹如外卖同样,下单,炒菜,配送。整套流程都以这么,不能说您出去就从头炒菜了啊,那不科学。不相像之处正是,你炒的怎么着菜,好不可口。配送得快异常的慢,稳不稳,服务好倒霉。

图片 20图片 21

进而,抽象类的意思就是:规范、特色

/**
 * 芝加哥芝士披萨
 * @author skysea
 */
public class ChicagoStyleCheesePizza extends Pizza {

    public ChicagoStyleCheesePizza() { 
        name = "芝加哥芝士披萨";
        dough = "芝加哥芝士披萨面团";
        sauce = "芝加哥芝士披萨酱料";

        toppings.add("芝加哥芝士披萨调料1");
        toppings.add("芝加哥芝士披萨调料2");
    }

    @Override
    void cut() {
        System.out.println("芝加哥芝士披萨版切片...");
    }
}
/**
 * 芝加哥蛤蜊披萨
 * @author skysea
 */
public class ChicagoStyleClamPizza extends Pizza {
    public ChicagoStyleClamPizza() {
        name = "芝加哥蛤蜊披萨";
        dough = "芝加哥蛤蜊披萨面团";
        sauce = "芝加哥蛤蜊披萨酱料";

        toppings.add("芝加哥蛤蜊披萨佐料1");
        toppings.add("芝加哥蛤蜊披萨佐料2");
    }

    @Override
    void cut() {
        System.out.println("芝加哥蛤蜊披萨版切片...");
    }
}
/**
 * 芝加哥意大利烤肠披萨
 * @author skysea
 */
public class ChicagoStylePepperoniPizza extends Pizza {
    public ChicagoStylePepperoniPizza() {
        name = "芝加哥意大利烤肠披萨";
        dough = "芝加哥意大利烤肠披萨面团";
        sauce = "芝加哥意大利烤肠披萨酱料";

        toppings.add("芝加哥意大利烤肠披萨调料1");
        toppings.add("芝加哥意大利烤肠披萨调料2");
        toppings.add("芝加哥意大利烤肠披萨调料3");
        toppings.add("芝加哥意大利烤肠披萨调料4");
    }

    @Override
    void cut() {
        System.out.println("芝加哥意大利烤肠披萨版切片...");
    }
}
/**
 * 芝加哥素食比萨
 * @author skysea
 */
public class ChicagoStyleVeggiePizza extends Pizza {
    public ChicagoStyleVeggiePizza() {
        name = "芝加哥素食比萨";
        dough = "芝加哥素食比萨的面团";
        sauce = "芝加哥素食比萨的酱料";

        toppings.add("芝加哥素食比萨调料1");
        toppings.add("芝加哥素食比萨调料2");
        toppings.add("芝加哥素食比萨调料3");
    }

    void cut() {
        System.out.println("芝加哥素食比萨版切片...");
    }
}
/**
 * 意大利烤肠披萨
 * @author skysea
 */
public class PepperoniPizza extends Pizza{

    public PepperoniPizza() {
        this.name = "意大利烤肠披萨";
        this.dough = "意大利烤肠披萨的面团";
        this.sauce = "意大利烤肠披萨的酱料";
        this.toppings.add("一大波意大利烤肠...");
    }
}

在不思忖继续强盛披萨连串的时候,那样的落到实处有没有标题,日常的话,到达了足以用的正式,然则不好用,难点如下:

本文由亚洲必赢发布于美食做法,转载请注明出处:简单工厂模式 (Simple Factory) ,但是说忙能有多忙

关键词: 56net必赢 所有随笔 软件设计 b