• 简单工厂模式


    一、 项目背景

    看一个披萨的项目:要便于披萨种类的扩展,要便于维护

    1. 披萨的种类很多(比如 GreekPizz、CheesePizz 等)

    2. 披萨的制作有 prepare,bake, cut, box

    3. 完成披萨店订购功能。

    二、传统方式(if()..elseif()...else)

    这里假定制作披萨的过程是相似的,只有准备阶段prepare不同。

    首先准备一个抽象的pizza基类:

    //将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;
    	}
    }
    
    

    再来几种不同口味的Pizza

    public class CheesePizza extends Pizza {
    
    	@Override
    	public void prepare() {
    		// TODO Auto-generated method stub
    		System.out.println(" 给制作奶酪披萨 准备原材料 ");
    	}
    
    }
    
    public class GreekPizza extends Pizza {
    
    	@Override
    	public void prepare() {
    		// TODO Auto-generated method stub
    		System.out.println(" 给希腊披萨 准备原材料 ");
    	}
    
    }
    
    public class PepperPizza extends Pizza {
    
    	@Override
    	public void prepare() {
    		// TODO Auto-generated method stub
    		System.out.println(" 给胡椒披萨准备原材料 ");
    	}
    
    }
    

    现在我们需要订购pizza了,按照传统的方式

    public class OrderPizza {
    
    	// 构造器
    	public OrderPizza() {
    		Pizza pizza = null;
    		String orderType; // 订购披萨的类型
    		do {
    			orderType = getType();
    			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("胡椒披萨");
    			} else {
    				break;
    			}
    			//输出pizza 制作过程
    			pizza.prepare();
    			pizza.bake();
    			pizza.cut();
    			pizza.box();
    			
    		} while (true);
    	}
    	// 写一个方法,可以获取客户希望订购的披萨种类
    	private String getType() {
    		try {
    			BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
    			System.out.println("input pizza 种类:");
    			String str = strin.readLine();
    			return str;
    		} catch (IOException e) {
    			e.printStackTrace();
    			return "";
    		}
    	}
    
    }
    
    

    现在我们需要订购pizza了

    //相当于一个客户端,发出订购
    public class PizzaStore {
    
    	public static void main(String[] args) {		
    		new OrderPizza();
    	}
    
    }
    

    在控制台中输入相应的Pizza种类:

    input pizza 种类:
    greek
     给希腊披萨 准备原材料 
     希腊披萨  baking;
     希腊披萨  cutting;
     希腊披萨  boxing;
    input pizza 种类:
    cheese
     给制作奶酪披萨 准备原材料 
     奶酪披萨  baking;
     奶酪披萨  cutting;
     奶酪披萨  boxing;
    input pizza 种类:
    haha
    
    

    这是用我们传统的方式来解决这个问题,考虑一样一个需求,订购的方式或有多种,即我们也许会通过多种途径来订购披萨,所以类似还会有OrderPizza2、OrderPizza3等。这样当我们需要新增一个pizza种类时,需要修改的代码就非常多,且散落于各地。

    使用简单工厂模式可以解决这个问题。

    首先我们创建一个工厂类,这个类的作用就是用来生产不同类型的pizza,

    //简单工厂类
    public class SimpleFactory {
    	//更加orderType 返回对应的Pizza 对象
    	//简单工厂模式 也叫 静态工厂模式 
    	public static Pizza createPizza(String orderType) {
    
    		Pizza pizza = null;
    
    		System.out.println("使用简单工厂模式2");
    		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;
    	}
    
    }
    
    

    同样的我们也需要订购pizza

    public class OrderPizza {
    
    	Pizza pizza = null;
    	String orderType = "";
    	// 构造器
    	public OrderPizza2() {
    		
    		do {
    			orderType = getType();
    			pizza = SimpleFactory.createPizza(orderType);
    
    			// 输出pizza
    			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("input pizza 种类:");
    			String str = strin.readLine();
    			return str;
    		} catch (IOException e) {
    			e.printStackTrace();
    			return "";
    		}
    	}
    }
    
    

    同样的在PizzaStore进行调用

    控制台输出

    input pizza 种类:
    greek
    使用简单工厂模式2
     给希腊披萨 准备原材料 
     希腊披萨  baking;
     希腊披萨  cutting;
     希腊披萨  boxing;
    input pizza 种类:
    cheese
    使用简单工厂模式2
     给制作奶酪披萨 准备原材料 
     奶酪披萨  baking;
     奶酪披萨  cutting;
     奶酪披萨  boxing;
    input pizza 种类:
    haha
    使用简单工厂模式2
     订购披萨失败 
    

    这样写有什么好处呢?

    工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。

    你所看得到的天才不过是在你看不到的时候还在努力罢了!
  • 相关阅读:
    C#执行cmd命令
    mongodb 高级查询详解(2)
    mongodb-管道操作:常规查询
    python-pymongo高级查询
    traceback异常打印
    Sanic基础和测试
    Python网络爬虫实战:根据天猫胸罩销售数据分析中国女性胸部大小分布
    POST提交数据的四种方式
    pymongo基础:入门
    python中__name__的意义
  • 原文地址:https://www.cnblogs.com/heliusKing/p/11575504.html
Copyright © 2020-2023  润新知