本篇文章如果不理解,可以查看我之前写的文章:浅析工厂模式之简单工厂模式
结合看一下就会理解。
1.新的需求:
奶茶项目新的需求:客户在点奶茶时,可以点不同口味的奶茶,比如北京的珍珠奶茶、北京的香草奶茶或者是伦敦的珍珠奶茶、伦敦的香草奶茶。
思路1
使用简单工厂模式,创建不同的简单工厂类,比如 BJMilkTeaSimpleFactory、LDMilkTeaSimpleFactory 等等.从当前这个案例来说,也是可以的,但是考虑到项目的规模,以及软件的可维护性、可扩展性并不是特别好
思路2
工厂方法模式
2.工厂方法模式介绍
I)工厂方法模式设计方案:将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现。
2)工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
2.1.UML类图:
2.2.具体代码:
BJPearMilkTea类
public class BJPearMilkTea extends MilkTea {
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("北京的珍珠奶茶");
System.out.println(" 北京的珍珠奶茶 准备原材料");
}
}
BJHerbalMilkTea类
public class BJHerbalMilkTea extends MilkTea {
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("北京的香草奶茶");
System.out.println(" 北京的香草奶茶 准备原材料");
}
}
LDPearMilkTea类
public class LDPearMilkTea extends MilkTea {
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("伦敦的珍珠奶茶");
System.out.println(" 伦敦的珍珠奶茶 准备原材料");
}
}
LDHerbalMilkTea类
public class LDHerbalMilkTea extends MilkTea {
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("伦敦的珍珠奶茶");
System.out.println(" 伦敦的珍珠奶茶 准备原材料");
}
}
MilkTea类:
public abstract class MilkTea {
protected String name; //名字
//准备原材料, 不同的奶茶不一样,因此,我们做成抽象方法
public abstract void prepare();
public void water() {
System.out.println(name + " water;");
}
public void sealTheCup() {
System.out.println(name + " sealTheCup;");
}
public void setName(String name) {
this.name = name;
}
}
BJOrderMilkTea类
public class BJOrderMilkTea extends OrderMilkTea {
@Override
MilkTea createMilkTea(String orderType) {
MilkTea MilkTea = null;
if(orderType.equals("Pear)) {
MilkTea = new BJPearMilkTea();
} else if (orderType.equals("Herbal")) {
MilkTea = new BJHerbalMilkTea();
}
// TODO Auto-generated method stub
return MilkTea;
}
}
LDOrderMilkTea类
public class LDOrderMilkTea extends OrderMilkTea {
@Override
MilkTea createPizza(String orderType) {
MilkTea MilkTea = null;
if(orderType.equals("Pear")) {
MilkTea = new LDPearMilkTea();
} else if (orderType.equals("Herbal")) {
MilkTea = new LDHerbalMilkTea();
}
// TODO Auto-generated method stub
return MilkTea;
}
}
OrderMilkTea类
public abstract class OrderMilkTea {
//定义一个抽象方法,createMilkTea , 让各个工厂子类自己实现
abstract MilkTea createMilkTea(String orderType);
// 构造器
public OrderMilkTea() {
MilkTea MilkTea = null;
String orderType; // 订购披萨的类型
do {
orderType = getType();
MilkTea = createMilkTea(orderType); //抽象方法,由工厂子类完成
//输出pizza 制作过程
MilkTea.prepare();
MilkTea.water();
MilkTea.sealTheCup();
} while (true);
}
// 写一个方法,可以获取客户希望订购的披萨种类
private String getType() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input MilkTea 种类:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
MilkTeaStore类
public class MilkTeaStore {
public static void main(String[] args) {
String loc = "bj";
if (loc.equals("bj")) {
//创建北京口味的各种MilkTea
new BJOrderMilkTea();
} else {
//创建伦敦口味的各种MilkTea
new LDOrderMilkTea();
}
// TODO Auto-generated method stub
}
}
3.总结:
这种方式解决了前面提到的问题,这种方式是诠释了可维护性与可拓展性,如果在加入一个上海珍珠奶茶,只需要创建一个上海珍珠奶茶的类,继承MilkTea,并创建一个对应地点的工厂子类,让其继承对应的 OrderMilkTea类并实现对应的方法,这种方式可维护性是很好的,所以建议使用。