前言:
***工厂:将类的实例化与调用分离,调用者只不用关心如何去实例化类,实例化成什么样的类对象,只需调用即可
简单工厂不在23个gof设计模式之中
demo代码:
Pizza(具体产品的抽象父类):抽象方法会在不同子类中有不同的实现,方便扩展
public abstract class Pizza {
protected String name;
//准备原料,不同的披萨原料不同
public abstract void prepare();
public void bake() {
System.out.println("烘烤披萨");
}
public void cut() {
System.out.println("披萨切块");
}
public void box() {
System.out.println("打包披萨");
}
public void setName(String name) {
this.name = name;
}
}
Pizza的子类(具体产品):
public class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("给制作奶酪披萨准备原材料");
}
}
public class GreekPizza extends Pizza {
@Override
public void prepare() {
System.out.println("给制作希腊披萨准备原材料");
}
}
public class PepperPizza extends Pizza {
@Override
public void prepare() {
System.out.println("给制作胡椒披萨准备原材料");
}
}
SimpleFactory(简单工厂):
ps:此处可改写为读取配置文件方式获取orderType类型,从而在不改代码的前提下实现扩展,写法略
public class SimpleFactory {
//根据orderType返回对应的Pizza对象
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if (orderType.equals("greek")) {
pizza = new GreekPizza();
pizza.setName("希腊披萨");
} else if (orderType.equals("cheese")) {
pizza = new CheesePizza();
pizza.setName("奶酪披萨");
} else if (orderType.equals("pepper")) {
pizza = new PepperPizza();
pizza.setName("胡椒披萨");
}
return pizza;
}
}
OrderPizza(调用工厂生产产品,产品在此完成实例化):
public class OrderPizza {
SimpleFactory simpleFactory;
Pizza pizza = null;
public OrderPizza(SimpleFactory simpleFactory) {
setFactory(simpleFactory);
}
public void setFactory(SimpleFactory simpleFactory) {
String orderType = "";
this.simpleFactory = simpleFactory;
do {
orderType = getType();
//指定工厂进行确定类型的实例化
pizza = this.simpleFactory.createPizza(orderType);
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} else {
System.out.println("订购披萨失败");
break;
}
} while (true);
}
//获取客户希望订购的披萨种类
private String getType() {
try {
BufferedReader strin =
new BufferedReader(new InputStreamReader(System.in));
System.out.println("输入披萨口味:");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
客户端类:
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza(new SimpleFactory());
System.out.println("退出程序");
}
}
demo类图:
类图分析:
2为要实例化的产品,1为实例化产品的类(工厂),工厂根据需求来确定实例化哪个具体的产品(哪个就是一个的意思,换句话就是用的时候用具体产品中的一个)
如果要扩展产品的话在2处添加要扩展的类即可(当然,1如果是if else写法的话要在工厂加上新增的类)
既然类的实例化与调用相分离,那在调用之前是可以根据需求来增加类的描述的,如OrderPizza类中创建产品(具体Pizza)后要执行产品的一些方法,调用者只拿最终的产品,不用关心其他任务东西。此时代码的可维护性与松耦合性就太强了,就说香不香吧
不足之处:SimpleFactory是核心,一旦它出了问题整个体系会瘫痪
再来看“简单工厂”这个名字:工厂很简单,只能生产出一类对象(Pizza类)
适用场景:
当类具有一维属性且属性(口味)与类具有一对多的特性、目标类处于同级别、调用类要添加一些描述(setFactory方法中对pizza的其他使用或其他设置)时简单工厂可能是你想要的