有一個(gè)連鎖披薩店要在湖南和廣東兩個(gè)地方開店,但是湖南人喜歡辣句柠,廣東人喜歡清淡
需求故事
- 1.作為一個(gè)披薩店P(guān)izzaStore,可以根據(jù)客人要求orderPizza提供湖南口味的Pizza,口味是peppery+cheese;
- 2.作為一個(gè)披薩店P(guān)izzaStore, 還可以根據(jù)客人要求orderPizza提供廣東口味Pizza勺爱,口味是seafood+cheese;
- 3.作為一個(gè)披薩店P(guān)izzaStore讯检,還可以根據(jù)客人要求orderChicken生產(chǎn)廣東口味的FriedChicken琐鲁,口味是peppery+chicken卫旱,而作為一個(gè)廣東的披薩店GDPizzaStore,可以生產(chǎn)FriedChicken围段,口味是light+chicken
Story1
作為一個(gè)披薩店P(guān)izzaStore誊涯,可以根據(jù)客人要求orderPizza提供湖南口味的Pizza,口味是peppery+cheese蒜撮;
Story1 Test Case
由于Story1的需求都很具體,所以都是使用具體類來(lái)實(shí)現(xiàn)的
public class PizzaStoreTest {
@Test
public void testOrderPizzaStory1(){
HNPizzaStore hnPizzaStore = new HNPizzaStore();
HNStylePizza hnStylePizza = hnPizzaStore.orderPizza();
assertEquals("peppery+cheese",hnStylePizza.taste());
assertTrue(hnStylePizza.isBaked());
}
}
Story1 Implementation
public class HNStylePizza {
private boolean baked=false;
public String taste() {
return "peppery+cheese";
}
public void baking() {
baked = true;
}
public boolean isBaked() {
return baked;
}
}
public class HNPizzaStore {
public HNStylePizza orderPizza() {
HNStylePizza pizza = new HNStylePizza();
pizza.baking();
return pizza;
}
}
Story2
作為一個(gè)新的連鎖廣東披薩店P(guān)izzaStore, 還可以根據(jù)客人要求orderPizza提供廣東口味Pizza跪呈,口味是seafood+cheese段磨;
Story2 Test Case
增加的一個(gè)連鎖披薩店,所以可以對(duì)披薩店進(jìn)行抽象PizzaStore耗绿。廣東風(fēng)味的披薩和湖南風(fēng)味的披薩口味也不通苹支,但都是披薩,所以對(duì)披薩也要進(jìn)行抽象Pizza來(lái)準(zhǔn)備testcase
@Test
public void testOrderPizzaStory2(){
PizzaStore hnPizzaStore = new HNPizzaStore();
Pizza hnStyledPizza = hnPizzaStore.orderPizza();
assertEquals("peppery+cheese",hnStyledPizza.taste());
assertTrue(hnStyledPizza.isBaked());
PizzaStore gdPizzaStore = new GDPizzaStore();
Pizza gdStyledPizza = gdPizzaStore.orderPizza();
assertEquals("seafood+cheese",gdStyledPizza.taste());
assertTrue(gdStyledPizza.isBaked());
}
Story2 Implemetation
public abstract class Pizza {
private boolean baked=false;
public void baking() {
baked = true;
}
public boolean isBaked() {
return baked;
}
public abstract String taste();
}
public class HNStylePizza extends Pizza {
public String taste() {
return "peppery+cheese";
}
}
public class HNPizzaStore extends PizzaStore {
public Pizza prepareUnbakedPizza() {
HNStylePizza pizza = new HNStylePizza();
pizza.baking();
return pizza;
}
}
public abstract class PizzaStore {
public Pizza orderPizza() {
Pizza pizza = prepareUnbakedPizza();
pizza.baking();
return pizza;
}
protected abstract Pizza prepareUnbakedPizza();
}
public class GDPizzaStore extends PizzaStore {
@Override
protected Pizza prepareUnbakedPizza() {
Pizza pizza = new GDStylePizza();
return pizza;
}
}
public class HNPizzaStore extends PizzaStore {
@Override
public Pizza prepareUnbakedPizza() {
Pizza pizza = new HNStylePizza();
return pizza;
}
}
上面的實(shí)現(xiàn)就是一個(gè)標(biāo)準(zhǔn)的Factory模式實(shí)現(xiàn)了误阻,所以Factory模式就是把生產(chǎn)的對(duì)象债蜜,和生產(chǎn)的工廠進(jìn)行抽象,從而達(dá)到了把實(shí)現(xiàn)產(chǎn)品的細(xì)節(jié)放到了工廠的子類中實(shí)現(xiàn)究反。
Factory模式的使用場(chǎng)景是使用不同的工廠來(lái)創(chuàng)建對(duì)象寻定,以及要對(duì)創(chuàng)建的對(duì)象進(jìn)行一些初始化操作,所以Factory模式里面通常都包含了Template方法模式
Story3
作為一個(gè)披薩店P(guān)izzaStore精耐,還可以根據(jù)客人要求orderChicken生產(chǎn)廣東口味的Chicken狼速,口味是peppery+chicken,而作為一個(gè)廣東的披薩店GDPizzaStore卦停,可以生產(chǎn)Chicken向胡,口味是light+chicken
Story3 Test Case
public void testOrderChickenStory3(){
PizzaStore pizzaStore = new HNPizzaStore();
Chicken chicken = pizzaStore.orderChicken();
assertEquals("peppery+chicken",chicken.taste());
pizzaStore = new GDPizzaStore();
chicken = pizzaStore.orderChicken();
assertEquals("light+chicken",chicken.taste());
}
Story3 Implementation
public abstract class Chicken {
public abstract String taste();
}
public class PeppyChicken extends Chicken {
@Override
public String taste() {
return "peppery+chicken";
}
}
public class LightChicken extends Chicken {
@Override
public String taste() {
return "light+chicken";
}
}
public abstract class PizzaStore {
public Pizza orderPizza() {
Pizza pizza = prepareUnbakedPizza();
pizza.baking();
return pizza;
}
protected abstract Pizza prepareUnbakedPizza();
public abstract Chicken orderChicken();
}
public class HNPizzaStore extends PizzaStore {
public Pizza prepareUnbakedPizza() {
HNStylePizza pizza = new HNStylePizza();
return pizza;
}
@Override
public Chicken orderChicken() {
return new PeppyChicken();
}
}
public class GDPizzaStore extends PizzaStore {
@Override
protected Pizza prepareUnbakedPizza() {
Pizza gdStylePizza = new GDStylePizza();
return gdStylePizza;
}
@Override
public Chicken orderChicken() {
return new LightChicken();
}
}
這就是Abstract Factory模式的實(shí)現(xiàn)了,你沒(méi)有看錯(cuò)惊完,Abstract Factory比Factory最大的區(qū)別就是多了生產(chǎn)其他產(chǎn)品的方法僵芹,所以如果Factory就是只生產(chǎn)1個(gè)產(chǎn)品的Abstract Factory。
和堅(jiān)思辨
Factory模式系列其實(shí)是要解決創(chuàng)建對(duì)象的問(wèn)題小槐,應(yīng)用的場(chǎng)景是當(dāng)創(chuàng)建一個(gè)對(duì)象比較復(fù)雜拇派,使用構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象無(wú)法滿足需求的情況。所以是否使用Factory系列相關(guān)模式的主要問(wèn)題就是當(dāng)你需要一個(gè)對(duì)象凿跳,但是使用構(gòu)造函數(shù)還需要再做其他的額外準(zhǔn)備時(shí)攀痊,就應(yīng)該考慮Factory系列模式。
Factory系列其實(shí)一套一共有3個(gè):
Simple Factory模式
Factory模式
Abstract Factory模式
其中Simple Factory就是根據(jù)傳遞的參數(shù)拄显,用IF來(lái)判斷創(chuàng)建對(duì)象苟径,由于我個(gè)人不是很喜歡這種很多if的嵌套結(jié)構(gòu),所以我就沒(méi)有進(jìn)行介紹了躬审。