1.什么是抽象工厂模式?
提供一个接口,用于创建相关对象或依赖对象的家族,而不需要明确指定具体类。 通过依赖注入来降低耦合。
2.结合工厂模式的披萨实例来理解抽象工厂模式
2.1 具体设计
尽管上一节的工厂模式设计已经好像看着可以,但是,我们好像也能明显的发觉到对于具体的PizzaStore的编写,我们好像违反了一个原则: 不要依赖具体,要依赖抽象。
例如我们看一下NYPizzaStore,它里面好像依赖了具体的Pizza对象,现在看来它就依赖了两个,但是如果长期以这样的方式来做的话,不难发现我们会进入一个依赖噩梦。
package factoryPattern.third.store;
import factoryPattern.third.PizzaStore;
import factoryPattern.third.pizza.NYPizza1;
import factoryPattern.third.pizza.NYPizza2;
import factoryPattern.third.pizza.Pizza;
public class NYPizzaStore extends PizzaStore {
@Override
protected Pizza createPizza(String type) {
Pizza pizza = null;
if(type.equals("NY1")){
pizza = new NYPizza1();
}else if(type.equals("NY2")){
pizza = new NYPizza2();
}
return pizza;
}
}
如何解决这个问题? 本届的抽象工厂模式也许会给你一些启发。
抽象工厂模式:提供一个接口用于创建相关或依赖对象的家族,而不需要明确指定具体类。
那么我们该如何让PizzaStore从依赖噩梦中解脱呢?员工A在原有的基础上,进行思考后,设计出下面的结构:
首先,他将Pizza抽象化了,并且新建立一个PizzaFactory接口用来将具体的PizzaStory和具体的Pizza实例解耦。
从图中我们可以看到,面向用户的具体的NYPizzaStore是通过依赖抽象的方式来满足需求的。
2.2 具体实现
Pizza.java
package AbstractFactoryPattern.base;
import java.util.Arrays;
public abstract class Pizza {
public String name;
public abstract void prepare();
protected void bake(){
System.out.println("准备烘烤 25 分钟...");
}
protected void cut(){
System.out.println("烘烤完成,进行切割");
}
protected void box(){
System.out.println("切割完毕,进行装盒");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
PizzaFactory.java
package AbstractFactoryPattern.base;
public interface PizzaFactory {
Pizza createPizza(String type);
}
PizzaStore.java
package AbstractFactoryPattern.base;
public abstract class PizzaStore {
public Pizza orderPizza(String type){
Pizza pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
/**
* 工厂方法
* @param type 披萨类型
* @return pizza实例
*/
protected abstract Pizza createPizza(String type);
}
CheesePizza.java
package AbstractFactoryPattern.pizza;
import AbstractFactoryPattern.base.Pizza;
/**
* Cheese披萨定义类
* 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
*/
public class CheesePizza extends Pizza {
public CheesePizza(){
}
@Override
public void prepare() {
System.out.println("Preparing "+name);
}
@Override
protected void bake(){
System.out.println("Cheese烘烤方式:。。。,,,。。。");
}
}
ClamPizza.java
package AbstractFactoryPattern.pizza;
import AbstractFactoryPattern.base.Pizza;
public class ClamPizza extends Pizza {
public ClamPizza(){ }
@Override
public void prepare() {
System.out.println("Preparing "+name);
}
@Override
protected void bake(){
System.out.println("ClamPizza烘烤方式------");
}
}
NYPizzaFactory.java
package AbstractFactoryPattern.factory;
import AbstractFactoryPattern.base.Pizza;
import AbstractFactoryPattern.base.PizzaFactory;
import AbstractFactoryPattern.pizza.CheesePizza;
import AbstractFactoryPattern.pizza.ClamPizza;
/**
* Pizza工厂
*/
public class NYPizzaFactory implements PizzaFactory {
@Override
public Pizza createPizza(String type) {
Pizza pizza = null;
if(type.equals("cheese")){
pizza = new CheesePizza();
pizza.setName("New York Style Cheese Pizza");
}else if(type.equals("clam")){
pizza = new ClamPizza();
pizza.setName("New York Style Clam Pizza");
}
return pizza;
}
}
NYPizzaStore.java
package AbstractFactoryPattern.pizzaStore;
import AbstractFactoryPattern.base.Pizza;
import AbstractFactoryPattern.base.PizzaFactory;
import AbstractFactoryPattern.base.PizzaStore;
import AbstractFactoryPattern.factory.NYPizzaFactory;
/**
* NY披萨工厂
*/
public class NYPizzaStore extends PizzaStore {
PizzaFactory pizzaFactory;
public NYPizzaStore(){
this.pizzaFactory = new NYPizzaFactory();
}
public NYPizzaStore(PizzaFactory pizzaFactory){
this.pizzaFactory = pizzaFactory;
}
@Override
protected Pizza createPizza(String type) {
return pizzaFactory.createPizza(type);
}
}
OK,构建完毕,下面进行测试一下:
package AbstractFactoryPattern;
import AbstractFactoryPattern.base.PizzaStore;
import AbstractFactoryPattern.pizzaStore.NYPizzaStore;
/**
* 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。 这种方式依赖注入
*/
public class MainTest {
public static void main(String[] args) {
PizzaStore nyPizzaStore = new NYPizzaStore();
nyPizzaStore.orderPizza("cheese");
}
}
完成!! 如果你成功重现出了上面的例子并理解了这种方式,可以将它和上一节的例子进行对比。