pizza种类 ——客户端——pizza店
传统解决方案类图为
可以看到OrderPizza (客户端)依赖了每一种pizza 这样造成了 如果添加一种或者修改一种pizza那就会造成每个客户端需要修改,如果客户端特比多那就是灾难了。
package Factory.Pizza;
//披萨抽象类
public abstract class Pizza
{
protected String name; //pizza名字
//准备pizza 不同的pizza 准备的不同
public abstract void prepare();
public void bake()
{
System.out.println("正在烘烤"+name);
}
public void cut()
{
System.out.println("正在切割"+name);
}
public void box()
{
System.out.println("正在打包"+name);
}
public void setName(String name)
{
this.name = name;
}
}
package Factory.Pizza;
//定义奶酪披萨
public class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("准备奶酪");
}
}
package Factory.Order;
import Factory.Pizza.CheesePizza;
import Factory.Pizza.GreekPizza;
import Factory.Pizza.PepperPizza;
import Factory.Pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza
{
Pizza pizza =null;
String PizzaType;//说明订购Pizza类型
//检测订购类型
public OrderPizza()
{
do {
PizzaType=getPizzaType();
if(PizzaType.equals("greek"))
{
pizza = new GreekPizza();
pizza.setName("greekpizza");
}
else if(PizzaType.equals("cheese"))
{
pizza = new CheesePizza();
pizza.setName("cheesepizza");
}
else if(PizzaType.equals("pepper"))
{
pizza = new PepperPizza();
pizza.setName("pepperpizza");
}
else {
break;
}
System.out.println("已接单");
pizza.prepare();
pizza.cut();
pizza.bake();
pizza.box();
} while(true);
}
//模拟客户端选择pizza
private String getPizzaType()
{
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("输入pizza类型");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
package Factory.Store;
import Factory.Order.OrderPizza;
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza();
}
}
使用简单工厂。那么我们需要把创建pIzza对象封装成一个类,只需要对其修改就可以了。
首先创建一个工厂 用来创造对象
package Factory.Order;
import Factory.Pizza.CheesePizza;
import Factory.Pizza.GreekPizza;
import Factory.Pizza.PepperPizza;
import Factory.Pizza.Pizza;
public class SimpleFactory
{
public Pizza createPizza(String PizzaType){
System.out.println("简单工厂造出");
Pizza pizza =null;
System.out.println("正在启动工厂");
if(PizzaType.equals("greek"))
{
pizza = new GreekPizza();
pizza.setName("greekpizza");
}
else if(PizzaType.equals("cheese"))
{
pizza = new CheesePizza();
pizza.setName("cheesepizza");
}
else if(PizzaType.equals("pepper"))
{
pizza = new PepperPizza();
pizza.setName("pepperpizza");
}
return pizza;
}
}
修改客户端的类
package Factory.Order;
import Factory.Pizza.CheesePizza;
import Factory.Pizza.GreekPizza;
import Factory.Pizza.PepperPizza;
import Factory.Pizza.Pizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class OrderPizza
{
Pizza pizza =null;
String PizzaType;//说明订购Pizza类型
//引用简单工厂对象
SimpleFactory simpleFactory;
public OrderPizza(SimpleFactory simpleFactory){
setFactory(simpleFactory);
}
//获取工厂的创造的对象
public void setFactory(SimpleFactory simpleFactory){
this.simpleFactory=simpleFactory;
do {
PizzaType = getPizzaType();
pizza=this.simpleFactory.createPizza(PizzaType);
if(pizza !=null){
System.out.println("订单成功");
pizza.prepare();
pizza.cut();
pizza.bake();
pizza.box();
}
else {
System.out.println("订单失败");
break;
}
}while (true);
}
//模拟客户端选择pizza
private String getPizzaType()
{
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("输入pizza类型");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
商店重新调用
package Factory.Store;
import Factory.Order.OrderPizza;
import Factory.Order.SimpleFactory;
public class PizzaStore {
public static void main(String[] args) {
new OrderPizza(new SimpleFactory());
System.out.println("---------程序退出---------");
}
}
小结:如果需要静态工厂 需要把工厂里的创建对象的方法设置成静态的,这样其他类可以直接可以通过类名.方法名进行调用,不需要引用成员等操作。
故简单工厂也为静态工厂。
因为客户需求,现在要求 增加不同的工厂,有北京有工厂,伦敦也要有工厂,如果继续按简单工厂持续创作工厂,那样会使得工厂创建过于多。
从而引出升级模式——工厂方法模式
具体类图如下。
抽象工厂模式
如图所示就是把工厂定义为接口,然后定义两个工厂去实现。在最后,使用OrderPizza将其聚合即可
抽象工厂与方法工厂代码样式差不错。这里举例抽象工厂。
**pizza 的实现类分为北京胡椒、天津胡椒。**如下图。
定义个工厂接口
package Factory.AbsFactory.Order;
import Factory.AbsFactory.AbsPizza.AbsPizza;
public interface AbsFactory
{
public AbsPizza creatPizza(String pizzaType);
}
不同的工厂来实现 并创建不同的pizza对象
package Factory.AbsFactory.Order;
import Factory.AbsFactory.AbsPizza.AbsPizza;
import Factory.AbsFactory.AbsPizza.BJCheesePizza;
public class BJFactory implements AbsFactory
{
@Override
public AbsPizza creatPizza(String pizzaType) {
System.out.println("北京工厂启动ing");
AbsPizza absPizza = null;
if (pizzaType.equals("cheese")){
absPizza=new BJCheesePizza();
}
else if(pizzaType.equals("pepper")){
absPizza=new BJCheesePizza();
}
return absPizza;
}
}
在客户端上选择工厂、Pizza
package Factory.AbsFactory.Order;
import Factory.AbsFactory.AbsPizza.AbsPizza;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ChoiseFactory
{
public ChoiseFactory(AbsFactory factory){
setFactory(factory);
}
AbsFactory factory;
public void setFactory(AbsFactory factory){
this.factory=factory;
AbsPizza absPizza = null;
String pizzaType = "";
do {
pizzaType = getPizzaType();
//由于factory 为接口类,所以factory可以是子类工厂任何一个
absPizza= factory.creatPizza(pizzaType);
if(absPizza !=null){
System.out.println("订单成功");
absPizza.prepare();
absPizza.cut();
absPizza.bake();
absPizza.box();
}
else {
System.out.println("订单失败");
break;
}
}while (true);
}
private String getPizzaType()
{
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("输入pizza类型");
String str = strin.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
最后在商店里调用具体哪个工厂的接口即可
package Factory.AbsFactory.Order;
public class PizzaStore {
public static void main(String[] args) {
new ChoiseFactory(new BJFactory());
}
}