设计模式之工厂模式---对象的实例化部分提取出来---三种不同的提取方法

一、不使用工厂

披萨项目:要方便披萨品种的扩展、要便于维护、要能运行时扩展

披萨族的设计:
抽象Pizza类,有四个方法:prepare()、bake(),cut(),box()

实际的披萨:GreekPizza和CheesePizza

披萨工厂设计:if…else … if …else

1、抽象Pizza类

package com.java.jikexueyuan.pizzastore.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;
	}
}

2、实际的披萨类

1)、CheesePizza

package com.java.jikexueyuan.pizzastore.pizza;

public class CheesePizza extends Pizza {

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		super.setname("CheesePizza");
		
		System.out.println(name+" preparing;");
	}

}

2)、GreekPizza

package com.java.jikexueyuan.pizzastore.pizza;

public class GreekPizza extends Pizza {

	@Override
	public void prepare() {
		// TODO Auto-generated method stub
		super.setname("GreekPizza");
		
		System.out.println(name+" preparing;");
	}

}

3、一般OrderPizza实现类

package com.java.jikexueyuan.pizzastore;

public class OrderPizza {

	public OrderPizza() {
		Pizza pizza = null;
		String ordertype;
		
		do {
			ordertype = gettype();   //控制台输入
			
			if (ordertype.equals("cheese")) {
				pizza = new CheesePizza();
			} else if (ordertype.equals("greek")) {
				pizza = new GreekPizza();
			} else if (ordertype.equals("pepper")) {
				pizza = new PepperPizza();
			} else if (ordertype.equals("chinese")) {
				pizza = new ChinesePizza();
			} else {
				break;
			}
			pizza.prepare();
			pizza.bake();
			pizza.cut();
			pizza.box();
		} while (true);
	}
}

简单工厂总结:如果要扩展新的pizza,就要将OrderPizza这个简单工厂停下来修改其中代码。

4、怎么改进呢?

将变化的地方抽取出来,使用简单工厂来封装,这样就不用停止orderPizza的运行,如下:

二、简单工厂(从主类提取实例化(变化)部分)

定义一个实例化披萨对象的类,封装创建对象的代码

1、SimplePizzaFactory类

public class SimplePizzaFactory {

	public Pizza CreatePizza(String ordertype) {
		Pizza pizza = null;

		if (ordertype.equals("cheese")) {
			pizza = new CheesePizza();
		} else if (ordertype.equals("greek")) {
			pizza = new GreekPizza();
		} else if (ordertype.equals("pepper")) {
			pizza = new PepperPizza();
		}
		return pizza;

	}

}

2、新的OrderPizza类

public class OrderPizza {
	SimplePizzaFactory mSimplePizzaFactory;

	public OrderPizza(SimplePizzaFactory mSimplePizzaFactory) {
		setFactory(mSimplePizzaFactory);
	}

	public void setFactory(SimplePizzaFactory mSimplePizzaFactory) {
		Pizza pizza = null;
		String ordertype;

		this.mSimplePizzaFactory = mSimplePizzaFactory;

		do {
			ordertype = gettype();
			pizza = mSimplePizzaFactory.CreatePizza(ordertype);
			if (pizza != null) {
				pizza.prepare();
				pizza.bake();
				pizza.cut();
				pizza.box();
			}

		} while (true);

	}

三、工厂方法模式

将对象的实例化推迟到子类

困惑:披萨项目加盟店
解决:将披萨对象实例化功能抽象成抽象方法,在不同加盟店具体实现功能;

扫描二维码关注公众号,回复: 3736352 查看本文章

1、抽象的OrderPizza

package com.java.jikexueyuan.pizzastore.method;

public abstract class OrderPizza {

	public OrderPizza() {
		Pizza pizza = null;
		String ordertype;

		do {
			ordertype = gettype();
			pizza = createPizza(ordertype);

			pizza.prepare();
			pizza.bake();
			pizza.cut();
			pizza.box();
		} while (true);
	}

    // 方法抽象出来
	abstract Pizza createPizza(String ordertype);
}

2、实际的OrderPizza

1)、纽约的NYOrderPizza

package com.java.jikexueyuan.pizzastore.method;

public class NYOrderPizza extends OrderPizza {

	@Override
	Pizza createPizza(String ordertype) {
		Pizza pizza = null;

		if (ordertype.equals("cheese")) {
			pizza = new NYCheesePizza();
		} else if (ordertype.equals("pepper")) {
			pizza = new NYPepperPizza();
		}
		return pizza;

	}

}

2)、伦敦的LDOrderPizza

public class LDOrderPizza extends OrderPizza {

	@Override
	Pizza createPizza(String ordertype) {
		Pizza pizza = null;

		if (ordertype.equals("cheese")) {
			pizza = new LDCheesePizza();
		} else if (ordertype.equals("pepper")) {
			pizza = new LDPepperPizza();
		}
		return pizza;

	}

}

四、抽象工厂模式

定义一个接口,用于创建相关或有依赖关系的对象族,而无需明确指定具体类。

1、抽象AbsFactory类

package com.java.jikexueyuan.pizzastore.absfactory;

public interface AbsFactory {
	public Pizza CreatePizza(String ordertype) ;
}

2、具体实现类

1)、伦敦LDFactory

package com.java.jikexueyuan.pizzastore.absfactory;

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();
		}
		return pizza;
	}
}

2)纽约NYFactory

package com.java.jikexueyuan.pizzastore.absfactory;

public class NYFactory implements AbsFactory {

	@Override
	public Pizza CreatePizza(String ordertype) {
		Pizza pizza = null;

		if (ordertype.equals("cheese")) {
			pizza = new NYCheesePizza();
		} else if (ordertype.equals("pepper")) {
			pizza = new NYPepperPizza();
		}
		return pizza;
	}
}

3、OrderPizza类(AbsFactory的具体工厂传进来创建pizza对象)

package com.java.jikexueyuan.pizzastore.absfactory;

public class OrderPizza {
	AbsFactory mFactory;

	public OrderPizza(AbsFactory mFactory) {
		setFactory(mFactory);
	}

	public void setFactory(AbsFactory mFactory) {
		Pizza pizza = null;
		String ordertype;

		this.mFactory = mFactory;

		do {
			ordertype = gettype();
			pizza = mFactory.CreatePizza(ordertype);
			if (pizza != null) {
				pizza.prepare();
				pizza.bake();
				pizza.cut();
				pizza.box();
			}
		} while (true);
	}
}

五、依赖抽象原则

1、变量不要持有具体类的引用

例如,OrderPizza类中创建披萨的变量;

2、不要让类继承自具体类,要继承自抽象类或接口

3、不要覆盖类中已实现的方法

猜你喜欢

转载自blog.csdn.net/shinecjj/article/details/83240476