1 抽象工厂模式
1.1 概述
-
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
-
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
1.2 意图
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
1.3 主要解决
主要解决接口选择的问题。
1.4 何时使用
系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
1.5 如何解决
在一个产品族里面,定义多个产品。
1.6 关键代码
在一个工厂里聚合多个同类产品。
1.7 应用实例
BJFactory是一个工厂,LDFactory也是一个工厂,他们数据同一个产品族类,可以把他们抽象出一个父接口工厂 也就是AbsFactory。这样订单OrderPizza只和AbsFactory交互。保证客户端始终只使用同一个产品族中的对象。
1.8 优点
当一个产品族中的多个对象被设计成一起工作时,
它能保证客户端始终只使用同一个产品族中的对象。
1.9 缺点
产品族扩展非常困难,要增加一个系列的某一产品,
既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
1.10 使用场景
1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。
1.11 注意事项
产品族难扩展,产品等级易扩展。
1.12 代码示例(一)
package com.xql.designpattern.controller.factory;
public class PizzaStore {
public static void main(String[] args) {
// new OrderPizza(new BJFactory());
new OrderPizza(new LDFactory());
// TODO Auto-generated method stub
}
}
package com.xql.designpattern.controller.factory;
/**
* 抽象工厂
*
* @author 许清磊
* @date 2022/08/18 18:32
**/
public interface AbsFactory {
//抽象工厂 让下面的工厂子类来 具体实现
Pizza createPizza(String orderType);
}
package com.xql.designpattern.controller.factory;
/**
* 子工厂1
* @date 2022/08/18 18:33
**/
public class BJFactory implements AbsFactory{
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new BJCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new BJPepperPizza();
}
// TODO Auto-generated method stub
return pizza;
}
}
package com.xql.designpattern.controller.factory;
/**
* 子工厂2
*
* @author 许清磊
* @date 2022/08/18 18:34
**/
public class LDFactory implements AbsFactory {
@Override
public Pizza createPizza(String orderType) {
Pizza pizza = null;
if(orderType.equals("cheese")) {
pizza = new LDCheesePizza();
} else if (orderType.equals("pepper")) {
pizza = new LDPepperPizza();
}
// TODO Auto-generated method stub
return pizza;
}
}
package com.xql.designpattern.controller.factory;
//将Pizza 类做成抽象
public abstract class Pizza {
protected String name; //名字
//准备原材料, 不同的披萨不一样,因此,我们做成抽象方法
public abstract void prepare();
public void bake() {
System.out.println(name + " baking;");
}
public void cut() {
System.out.println(name + " cutting;");
}
//打包
public void box() {
System.out.println(name + " boxing;");
}
public void setName(String name) {
this.name = name;
}
}
package com.xql.designpattern.controller.factory;
public class LDPepperPizza extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("伦敦的奶酪pizza");
System.out.println(" 伦敦的奶酪pizza 准备原材料");
}
}
package com.xql.designpattern.controller.factory;
public class BJPepperPizza extends Pizza {
@Override
public void prepare() {
setName("北京的奶酪pizza");
System.out.println(" 北京的奶酪pizza 准备原材料");
}
}
package com.xql.designpattern.controller.factory;
public class LDCheesePizza extends Pizza{
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("伦敦的胡椒pizza");
System.out.println(" 伦敦的胡椒pizza 准备原材料");
}
}
package com.xql.designpattern.controller.factory;
public class BJCheesePizza extends Pizza {
@Override
public void prepare() {
// TODO Auto-generated method stub
setName("北京的胡椒pizza");
System.out.println(" 北京的胡椒pizza 准备原材料");
}
}
1.12 代码示例(二)
小结
- 工厂模式的意义.
将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。 - 三种工厂模式(简单工厂模式、工厂方法模式、抽象工厂模式)
- 设计模式的依赖抽象原则
➢创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中,并返回。有的书上说,变量不要直接持有具体类的引用。
➢不要让类继承具体类,而是继承抽象类或者是实现interface(接口)
➢不要覆盖基类中已经实现的方法。