设计模式之抽象工厂模式
设计模式中抽象工厂模式有三类,分别为简单工厂模式,抽象工厂模式,工厂方法模式, 但是常用的是抽象工厂模式,所以这里就着重将抽象工厂模式
- 抽象工厂将工厂抽象成两层,一个抽象工厂的接口,和具体实现的工厂子类。当需要增加新的
类
的时候只需要实现该种类的工厂即可 - 从设计层面看,抽象工厂模式就是对简单工厂模式的改进或者称为进一步的抽象
- 抽象工厂利于代码的维护和扩展.
这里我们模拟一个pisa工厂进行生产不同的pisa为例进行说明.
先定义一个抽象Pizza类, 该Pizza是某一个物体的抽象,具体的实现可以由实现该类的类来进行确定.
// 抽象Pizza类
package com.mzx.factory.abstract0.pizza;
/**
* @author ZhenXinMa
* @date 2020/1/26 14:25
*/
public abstract class Pizza {
private String name;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public abstract void prepare();
public void bake(){
System.out.println(name+" bake");
}
public void box(){
System.out.println(name+" box");
}
public void cut(){
System.out.println(name+" cut");
}
}
// 各个具体Pizza实现
package com.mzx.factory.abstract0.pizza;
/**
* @author ZhenXinMa
* @date 2020/1/26 14:25
*/
public class GreekPizza extends Pizza {
@Override
public void prepare() {
System.out.println("为"+getName()+"准备原材料");
}
}
package com.mzx.factory.abstract0.pizza;
/**
* @author ZhenXinMa
* @date 2020/1/26 14:26
*/
public class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("为"+getName()+"准备原材料");
}
}
创建工厂的抽象
// 抽象工厂
package com.mzx.factory.abstract0.factory;
import com.mzx.factory.abstract0.pizza.Pizza;
/**
BeanFactory----Bean
* @author ZhenXinMa
* @date 2020/1/26 14:27
*/
public interface PizzaFactory {
Pizza createPizza(String type);
}
// 各个种类工厂的实现类
package com.mzx.factory.abstract0.factory;
import com.mzx.factory.abstract0.pizza.CheesePizza;
import com.mzx.factory.abstract0.pizza.GreekPizza;
import com.mzx.factory.abstract0.pizza.Pizza;
/**
* @author ZhenXinMa
* @date 2020/1/26 14:27
*/
public class BJFactory implements PizzaFactory {
@Override
public Pizza createPizza(String type) {
Pizza pizza = null;
if(type.equals("cheese")){
pizza = new CheesePizza();
pizza.setName("北京口味的CheesePizza");
}else if(type.equals("greek")){
pizza = new GreekPizza();
pizza.setName("北京口味的GreekPizza");
}
return pizza;
}
}
package com.mzx.factory.abstract0.factory;
import com.mzx.factory.abstract0.pizza.CheesePizza;
import com.mzx.factory.abstract0.pizza.GreekPizza;
import com.mzx.factory.abstract0.pizza.Pizza;
/**
* @author ZhenXinMa
* @date 2020/1/26 14:35
*/
public class LDFactory implements PizzaFactory {
@Override
public Pizza createPizza(String type) {
Pizza pizza = null;
if(type.equals("cheese")){
pizza = new CheesePizza();
pizza.setName("伦敦口味的CheesePizza");
}else if(type.equals("greek")){
pizza = new GreekPizza();
pizza.setName("伦敦口味的GreekPizza");
}
return pizza;
}
}
使用抽象工厂的Order
package com.mzx.factory.abstract0.order;
import com.mzx.factory.abstract0.factory.PizzaFactory;
import com.mzx.factory.abstract0.pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author ZhenXinMa
* @date 2020/1/26 14:30
*
* 使用方
*
*/
public class OrderPizza {
private PizzaFactory factory;
public OrderPizza(PizzaFactory factory){
this.setFactory(factory);
}
private void setFactory(PizzaFactory factory){
this.factory = factory;
String type = "" ;
Pizza pizza = null;
while(true){
type = getType();
pizza = factory.createPizza(type);
if(pizza != null){
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}else{
System.out.println("订购Pizza失败");
break;
}
}
}
private String getType(){
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入订购披萨的类型");
String str = "";
try {
str = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
当我们在使用写Order代码的时候就没有必要给其指定一个必须确定的Factory,而是在其内部维护了一个该工厂的接口,这样遵循了OCP原则,对扩展开放,对修改关闭的原则.
以上的代码虽然精简,但是能掌握到精髓的却少之又少!
如果有哪里理解的不到位,还请指出!