简单工厂模式

150 阅读4分钟

程序员必备小知识

我们通过一个具体的需求来说明工厂模式——披萨订购

要便于披萨种类的扩展,要便于维护

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

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

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

同需求分析,我们需要做许多不同的披萨,所以在准备时,我们需要用不同的方法去制作,我们将最初的披萨类做成抽象类 ,中包含准备原材料的抽象方法

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

我们通过抽象类来生成新的披萨,我们需要重写准备原材料方法

//第一种披萨
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 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 {
				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 "";
		}
	}

}

最后我们作为客户去订购披萨

//相当于一个客户端,发出订购
public class PizzaStore {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//new OrderPizza();
		
		//使用简单工厂模式
		//new OrderPizza(new SimpleFactory());
		//System.out.println("~~退出程序~~");
		
		new OrderPizza2();
	}

}

以上就是我们用传统的方法实现了披萨订购的一个实现,整个代码看起来理解容易,简单易操作,问题就是他违反了开闭原则,当我们要给类添加增加新功能的时候,尽量不修改代码,或者尽可能少修改代码。

如果我们现在要添加一个新的披萨种类,我们需要修改以下的代码。

//添加新披萨类,继承原披萨抽象类
public class  PepperPizza extends Pizza {

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		System.out.println(" 给胡椒披萨准备原材料 ");
	}

}

在OrderPizza中添加逻辑代码

else if (orderType.equals("pepper")) {
				pizza = new PepperPizza();
				pizza.setName("胡椒披萨");

我们可以修改代码,但是往往在实际的开发当中,我们可能多出都用到此代码时,那就意味着要修改多处,我们就有可能忘记修改某一处。

如果 把创建Pizza对象封装到一个类中,这样我们有新的Pizza种类时,只需要修改该 类就可,其它有创建到Pizza对象的代码就不需要修改了.-> 简单工厂模式

简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一 个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族 中最简单实用的模式

简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行 为(代码)

在软件开发中,当我们会用到大量的创建某种、某类或者某批对象时,就会使用到工厂模式.。

首先我们定一个披萨的工厂类,输入一种订购类型,工厂返回相应的对象

//简单工厂类
public class SimpleFactory {

	//更加orderType 返回对应的Pizza 对象
	public Pizza createPizza(String orderType) {

		Pizza pizza = null;

		System.out.println("使用简单工厂模式");
		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;
	}

我们修改OrderPizza类中代码,通过调用工厂对象,获取披萨对象

public class OrderPizza {

	//定义一个简单工厂对象
	SimpleFactory simpleFactory;
	Pizza pizza = null;
	
	//构造器
	public OrderPizza(SimpleFactory simpleFactory) {
		setFactory(simpleFactory);
	}
	
	public void setFactory(SimpleFactory simpleFactory) {
		String orderType = ""; //用户输入的
		
		this.simpleFactory = simpleFactory; //设置简单工厂对象
		
		do {
			orderType = getType(); 
			pizza = this.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 "";
		}
	}

}

客户端调用

//相当于一个客户端,发出订购
public class PizzaStore {

	public static void main(String[] args) {	
        //使用简单工厂模式
		new OrderPizza(new SimpleFactory());
		System.out.println("~~退出程序~~");
	}

}

此时我们用以上代码完成需求,当有新的披萨需要加进来的时候,我们只需要添加新的披萨类继承抽象披萨类,在修改工厂内的代码就可以。