设计模式——三工厂模式

    三个工程都是创建型的模式,主要是为了用来解决对象的实例化问题,但是针对的问题不同。

        首先看一个最原始的没有工厂,就是家庭作坊,自给自足,如下的代码,每个披萨定都自己根据参数决定实例化那个披萨。

public class PizzaStore {
	//根据传来的参数决定实例化那个对象
	public Pizza orderPizza(String type) {
		if (type.equals("cheese")) {
			pizza = new CheesePizza();
		} else if (type.equals("pepperoni")) {
			pizza = new PepperoniPizza();
		} else if (type.equals("clam")) {
			pizza = new ClamPizza();
		} else if (type.equals("veggie")) {
			pizza = new VeggiePizza();
		}
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}

}

    如果有多家披萨店,这样就会有代码冗余,当增加披萨种类的时候每个披萨店类都需要修改,违反开闭原则,复用性也不好。

 

        随着时代的发展人们开始意识到这一的效率比较低,开始出现早期的工厂——简单工厂,看看能解决什么问题,首先看一下简单工厂的类图,在披萨店和披萨之间多了一个简单工厂。


对应的代码如下:

//披萨店,可以有多个,每个都使用简单工厂
public class PizzaStore {
	SimplePizzaFactory factory;  //关联的体现,定义一个简单工厂类型的成员变量 
	public PizzaStore(SimplePizzaFactory factory) { //进行初始化
		this.factory = factory;
	}
	public Pizza orderPizza(String type) {
		Pizza pizza;
		pizza = factory.createPizza(type);   //调用简单工厂的方法,实现披萨的实例化 
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}

}
//简单工厂类
public class SimplePizzaFactory {

	public Pizza createPizza(String type) {   //实例化披萨的方法,根据传来的字符进行实例化
		Pizza pizza = null;
		//里面实例化的类都是继承了Pizza类的子类
		if (type.equals("cheese")) {
			pizza = new CheesePizza();
		} else if (type.equals("pepperoni")) {
			pizza = new PepperoniPizza();
		} else if (type.equals("clam")) {
			pizza = new ClamPizza();
		} else if (type.equals("veggie")) {
			pizza = new VeggiePizza();
		}
		return pizza;
	}
}

改进:将实例化披萨那一部分容易变化的代码提取出来,放在简单工厂类中。

作用解决了“家庭作坊”的问题,将类的实例化过程抽象出来放在简单工厂中如上图的SimplePizzaFactory中,可以供多个披萨店使用,在没有这个工厂之前每家PizzaStore都需要自己制作披萨,现在所有的都只需要调用简单工厂就可以了。提高代码复用性。

缺点:并没有解决违反开闭原则的问题,如果披萨种类增加还是需要修改简单工厂类。

 

        简单工厂能够解决一些问题,当披萨的子类比较确定的时候使用也是很不错的,但是人们的需求总是在随着时代变化的,所以简单工厂还是不能满足人们的需求,就开始出现另外一种解决办法——工厂方法


对应的代码如下:

//抽象的披萨店
public abstract class PizzaStore {
 
	abstract Pizza createPizza(String item);
 
	public Pizza orderPizza(String type) {
		Pizza pizza = createPizza(type);
		System.out.println("--- Making a " + pizza.getName() + " ---");
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza;
	}
}
//纽约店
public class NYPizzaStore extends PizzaStore {

	Pizza createPizza(String item) {
		if (item.equals("cheese")) {
			return new NYStyleCheesePizza();
		} else if (item.equals("clam")) {
			return new NYStyleClamPizza();
		}  else return null;
	}
}
//芝加哥店
public class ChicagoPizzaStore extends PizzaStore {

	Pizza createPizza(String item) {
        	if (item.equals("cheese")) {
            		return new ChicagoStyleCheesePizza();
        	} lse if (item.equals("clam")) {
        	    	return new ChicagoStyleClamPizza();
        	}else return null;
	}
}

    工厂方法定义一个抽象的披萨店,由一个抽象的方法createPizza()在子类继承后进行实现,每个子类的具体实现不同,这样讲类的实例化推迟到子类。

        需要注意的是,这里的例子在子类店进行实例化的时候还是用的if语句,这和简单工厂是一样的,当披萨增加种类的时候还是需要修改子类店,这里其实是工厂方法和简单工厂的结合使用,在子类店中可以不使用if语句进行实例化,而是对每种披萨都专门建立一个子店类进行实例化。结合使用可以避免产生太多类。


      随着工业化的发展,工厂就会愈来愈全面化不仅仅有生产披萨的工厂,开始有生产披萨原材料的工厂,但是这就会有地域差距,例如同时成产面饼,在纽约要薄一些在芝加哥要厚一些的,还有酱料的差别等。


   抽象工厂:解决的是不同“品牌”的一组相同类的实例化问题。

         就如上图有一个抽象的原料工厂,在子类中有一个是生成NY(纽约)风味的,还有一个子类是生产Chicago(芝加哥)风味的,相同都是生产奶酪和面团,NY的可能是薄的面团和NY味的奶酪,而芝加哥是自己的风味的。

 

小结

简单工厂放在增加产品种类的时候需要修改简单工厂的代码,违反开闭原则

工厂方法将每个类的实例化放在子类里,当增加对应的产品种类时,只需增加对应的工厂方法的子类即可。当二者可以结合使用,极少工厂方法子类的数量。

抽象工厂解决的是一组类的实例化问题而且还是不同“品牌”的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 31
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值