设计模式演练——工厂方法模式

1.小C的故事

       大家好,我叫张小C,我是一个厨师,专职烤面包。下面是我的工作。

public class World {

    public static void main(String[] args) {
        LittleC littleC = new LittleC();
        littleC.work();
    }
}

public class LittleC {
    public void work() {
           Bread bread = new Bread();
           System.out.print(bread.getName()+"做好了!");
           System.out.println(bread.getTaste());
         }
}

public class Bread {

    private String name = "面包";

    public String getName() {
        return name;
    }

    public String getTaste(){
        return "软软的,没什么味道";
    }
}
 

有一天,小明(老顾客)来到张小c的店中,以下是对话--- 
小明:我吃你家面包都吃腻了,有没有别的吃的,没有的话我以后就换地方了。 
小C:有有有,我马上做别的美味出来。

小C心想,我只会烤面包啊,该咋办,难不成再加个workForPizza,那要是这个也吃腻了总不能加到屎吧…况且我脑子笨,学得慢…好吧,爱吃不吃,你不吃自有人吃!(纯属意淫)

2.存在的问题

现在让我们来看一看小C现在面临的问题是什么,先看看work方法中直接new了一个Bread,把自己禁锢在了一种食物中。那有没有什么办法可以解决小c的当前困境呢?

3.工厂方法模式登场

小强:小C,我最近开了一个Pizza店,什么时候过来吃Pizza啊? 
小C:太好了,我正愁呢。这样咱们合作,顾客在我这里点Pizza的时候,你们店就给我做一个Pizza送过来。互利共赢嘛。 
小强:好,一言为定。 
也许最近流行开餐馆,小C的朋友小梅开了家饺子馆,小C用同样的方法让小梅加盟了。 而且为了专心运营,连自己的烤面包工作都外包给小红的面包店了。 
经过酝酿,新的设计出现了:下面是代码摘要:

public class World {

    public static void main(String[] args) {
        LittleC littleC = new LittleC();
        System.out.println("小明:我要吃面包!");
        littleC.setFoodShop(new BreadShop());
        littleC.work();

        System.out.println("小明:我要吃饺子!");
        littleC.setFoodShop(new DumplingShop());
        littleC.work();

        System.out.println("小明:我要吃披萨!");
        littleC.setFoodShop(new PizzaShop());
        littleC.work();
    }
}

/**
 * 小C
 * 
 * @author bob
 */
public class LittleC {

    private FoodShop foodShop;
    
    public void setFoodShop(FoodShop foodShop){
        this.foodShop = foodShop;
    }

    public void work() {
        Food food = foodShop.createFood();
        System.out.print(food.getName() + "做好了!");
        System.out.println(food.getTaste());
    }
} 

public abstract class Food {

    public abstract String getName();

    public abstract String getTaste();
}

public abstract class FoodShop {

    public abstract Food createFood();
}

public class Bread extends Food {

    public String getName() {
        return "面包";
    }

    public String getTaste() {
        return "软软的,很清淡";
    }
}

public class BreadShop extends FoodShop {

    @Override
    public Food createFood() {
        return new Bread();
    }

} 

4.解决了什么,失去了什么

通过引入工厂方法模式我们解决了,Bread硬编码到LittleC中导致的扩展受限问题。小C以后可以接入各种各样的菜色而不需要改动既有代码(world除外)。 
缺点也是很明显,我为了一个菜色还要加一个餐馆进来。这里可以通过带有参数到工厂方法来优化这种情况。创造一个什么菜都可以生产的餐馆,比如根据类型完整名称就可以得到具体的食物,那么只需要一个餐馆就可以了。

5.具体应用场景

所有需要new一个对象的地方,同时要求有足够的灵活性

原文地址:https://www.cnblogs.com/bobsha/p/5698082.html