工厂模式的uml类图
- 工厂方法类图
- 抽象工厂类图
工厂方法一是为了创建多个对象是不用繁琐的去new对象,二是当有新的对象要增加时,可以便捷的修改少量代码实现。但是工厂方法相对抽象工厂,当新类增加时,每个creator中都需要增加对应创建该类的代码,而抽象工厂只需要在concreteFactory中修改就行。
因为工厂方法存在局限性,简单实现了下抽象工厂
抽象工厂
以披萨为例,分解各个角色实现抽象工厂
- 客户端client
public class PizzaStore{
public static void main(String[] args) {
// 此处指明哪个二级工厂
OrderPizza orderPizza = new OrderPizza(new BJFactory());
orderPizza.setFactory();
}
}
- 披萨工厂
public class OrderPizza {
AbsFactory factory;
public OrderPizza(AbsFactory absFactory){ // 客户端指定二级工厂(也能使用参数控制)
factory = absFactory;
}
public void setFactory() {
String orderType = ""; // 用户输入
do {
orderType = getType();
Pizza pizza =factory.createPizza(orderType);
if (pizza == null){
System.out.println("点餐结束,没有"+orderType+"类型的披萨");
return;
}
pizza.preparing();
} while (true);
}
// 获取参数指定工厂
private String getType() {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入需要的披萨:");
try {
return strin.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
- 披萨工厂顶层接口
public interface AbsFactory {
Pizza createPizza(String type);
}
- 二级抽象工厂,主要用于类的生成
public class BJFactory implements AbsFactory{
@Override
public Pizza createPizza(String type) {
if (type.equals("cheese")){
return new BJCheessPizza();
}else if (type.equals("gk")){
return new BJGreekPizza();
}
return null;
}
}
- 披萨抽象类,定义产品的行为
public abstract class Pizza {
private String name;
// 需要的原材料不一样,准备的材料不一样
public abstract void preparing();
public void setName(String name) {
this.name = name;
}
}
- 具体产品实现类,北京芝士披萨
public class BJCheessPizza extends Pizza {
@Override
public void preparing() {
System.out.println("老北京芝士原材料");
}
}
以上就是一个最基础的抽象工厂模式了,当我们想生成一个披萨就可以实例化OrderPizza根据地域传入不同的抽象工厂,然后再调用orderPizza.setFactory();就能生成想要的产品。当我们想拓展一个北京其他的披萨,那我们只需要在定义一个类继承pizza,然后在北京工厂中产生对象返回即可。
总结
工厂模式需要我们对每个角色进行把控好,外界只能调用我们的抽象类,即依赖于稳定抽象,所以在我们设计的时候考虑将具体产品的访问模式设置为protected或者默认。工厂模式分为客户端、工厂(顶层接口、二级抽象工厂类)、产品(抽象产品类、具体产品),工厂永远返回的是抽象产品类,客户端永远依赖的是抽象工厂,我们将具体产品的生产在二级抽象工厂中完成。