前言
在前面一章博主介绍了简单工厂模式(Simple Factory),接着上面的章节,今天博主就来介绍下工厂方法模式(Factory Method)。
思考题
首先,让我们来思考下面的问题:
在上一章的内容中我们提到了,博主开了一家饭店,那么,因为经营有方,博主准备在四川和上海开饭店了,也还是那两个菜,大家都知道上海和四川的口味差距非常的大,上海口味偏甜,那么四川口味偏辣。所以为了迎合当地人的口味,我们需要做不同口味的菜。那么你们会怎么做呢?
这时我们如果在原有的简单工厂上添加不同口味的菜,就会违背‘开放-关闭’原则,那么接下来就让我来隆重介绍工厂方法模式。
工厂方法模式
定义:定义一个创建产品的工厂的接口,将具体的产品的创建推迟到工厂子类中,符合‘开发-关闭’原则。
类图:
上面的类图,设计以下的几个角色:
- 抽象产品:为一类产品定义了统一接口。将具体实现与用户解耦。
- 具体产品:实现了抽象产品定义的接口,不同的产品有不同的实现。
- 抽象工厂:为一类工厂定义了统一接口。
- 具体工厂:实现了抽象工厂定义的方法,用来创建具体的产品。
思考题实现
首先,定义一个抽象产品类:
Food.java:
public interface Food { void fry(); void putSeasoning(); void eat(); }
然后,实现具体的产品:
ShangHaiKungPaoChicken.java:
public class ShangHaiKungPaoChicken implements Food { @Override public void fry() { System.out.println("上海,炒宫保鸡丁!!!"); } @Override public void putSeasoning() { System.out.println("上海,加入宫保鸡丁作料!!!"); } @Override public void eat() { System.out.println("上海,吃宫保鸡丁!!!"); } }
ShanghaiTomatoEgg.java:
public class ShangHaiTomatoEgg implements Food { @Override public void fry() { System.out.println("上海,炒西红柿炒蛋!!!"); } @Override public void putSeasoning() { System.out.println("上海,放入西红柿炒蛋作料!!!"); } @Override public void eat() { System.out.println("上海,吃西红柿炒蛋!!!"); } }
SiCHuanKungPaoChicken.java:
public class SiChuanKungPaoChicken implements Food { @Override public void fry() { System.out.println("四川,炒宫保鸡丁!!!"); } @Override public void putSeasoning() { System.out.println("四川,加入宫保鸡丁作料!!!"); } @Override public void eat() { System.out.println("四川,吃宫保鸡丁!!!"); } }
SiChuanTomatoEgg.java:
public class SiChuanTomatoEgg implements Food { @Override public void fry() { System.out.println("四川,炒西红柿炒蛋!!!"); } @Override public void putSeasoning() { System.out.println("四川,放入西红柿炒蛋作料!!!"); } @Override public void eat() { System.out.println("四川,吃西红柿炒蛋!!!"); } }
再然后,定义一个抽象工厂接口:
AbstractHotal.java:
public abstract class AbstractHotal { public Food saleFood(String foodName) { Food food = createFood(foodName); food.putSeasoning(); food.fry(); return food; } public abstract Food createFood(String foodName); }
再然后,实现抽象工厂:
ShangHaiHotal.java:
public class ShangHaiHotal extends AbstractHotal { @Override public Food createFood(String foodName) { switch(foodName) { case "KungPaoChicken": return new ShangHaiKungPaoChicken(); case "TomatoEgg": return new ShangHaiTomatoEgg(); default: return null; } } }
SiChuanHotal.java:
public class SiChuanHotal extends AbstractHotal { @Override public Food createFood(String foodName) { switch(foodName) { case "KungPaoChicken": return new SiChuanKungPaoChicken(); case "TomatoEgg": return new SiChuanTomatoEgg(); default: return null; } } }
下面是我的测试类:
Custom.java:
public class Custom { public static void main(String ...args) { ShangHaiHotal shangHaiHotal = new ShangHaiHotal(); SiChuanHotal siChuanHotal = new SiChuanHotal(); Food shangHaiKungPaoChicken = shangHaiHotal.saleFood("KungPaoChicken"); Food shangHaiTomatoEgg = shangHaiHotal.saleFood("TomatoEgg"); shangHaiKungPaoChicken.eat(); shangHaiTomatoEgg.eat(); Food siChuanKungPaoChicken = siChuanHotal.saleFood("KungPaoChicken"); Food siChuanTomatoEgg = siChuanHotal.saleFood("TomatoEgg"); siChuanKungPaoChicken.eat(); siChuanTomatoEgg.eat(); } }