废话不多说,直接上代码。
Pizza orderPizza(String type){
Pizza pizza;
if("chesse".equals(type)){
pizza = new ChessePizza();
}else if("clam".equals(type)){
pizza = new ClamPizza();
}else if("veggle".equals(type)){
pizza = new VegglePizza();
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
假设上面就是orderPizza()方法就是根据不同type生产不同pizza(或者说处理订单), 这样的代码很不好,当加入新的pizza类型后,又要修改上面的if else代码,就是没有对修改关闭,这也是变化的地方,我们可以把它们提前出来。
public class SimplePizzaFactory{
public Pizza createPizza(String type){
Pizza pizza;
if("chesse".equals(type)){
pizza = new ChessePizza();
}else if("clam".equals(type)){
pizza = new ClamPizza();
}else if("veggle".equals(type)){
pizza = new VegglePizza();
}
return pizza;
}
}
这个SimplePizzaFactory类就是一个简单比萨工厂,负责生产pizza.这和上面比较适合只是把问题搬到另一个类而已,也要修改if else,其实这个类目前看来只能提供pizza,但它可以扩展,不同用户可以通过这个类获取pizza,而且以后添加新pizza类修改时只要修改这个类而已。
这样修改过后的代码是这样
public class PizzaStore(){
SimplePizzaStroreFactory factory;
public PizzaStore(SimplePizzaStroreFactory factory){
this.factory = factory;
}
Pizza orderPizza(String type){
Pizza pizza;
pizza = factory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
//上面就展示了简单工厂模式。(也有人说这不算真正工厂模式,更像是一种编程习惯)
简单工厂类图假设现在有很多加盟商,他们利用SimplePizzaFactory,写出了三种不同的工厂,分别是NYPizzaFactory,ChicagoPizzaFactory,CaliforniaPizzaFactory.
现在代码就变成下面
NYPizzaFactoty nyFactory = new NyPizzaFactory();
PizzaStore nyStory = new PizzaStory(nyFactory);
nyStory.orderPizza("veggie");
//别的省略了
如果你希望pizza做法都相同,或者使用统一的包装,那么该什么办呢,
public abstract class PizzaStore(){//抽象类
Pizza orderPizza(String type){
Pizza pizza;
pizza = createPizza(type);//createPizza()从工厂对象中移回PizzaStore
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type);//现在把工厂对象移到这个方法中。
}
现在PizzaStore 作为超类,让每个地域store继承PizzaStore,每个子类决定如何制造pizza.
现在就是我们开的一家pizza店
public class NYPizzaStore extends PizzaStore{
Pizza createPizza(String item){
if("chesse".equals(type)){
return new NYChessePizza();
}else if("clam".equals(type)){
return new NYClamPizza();
}else if("veggle".equals(type)){
return new NYVegglePizza();
}else{
return null;
}
}
}
//注意超类OrderPizza()方法,并不知道正在创建的比萨是哪一种,它只知道比萨可以被preapare(),bake(),box()等处理
这里是Pizza类
public abstract class Pizza(){
String name;
String dough;
String sauce;
ArrayList toppings = new ArrayList();
}
void prepare(){
System.out.println("------prepare----);
}
void bake(){
System.out.println("------bake----);
}
void box(){
System.out.println("------box----);
}
//省略getSet方法
}
//纽约风味的比萨
public class NYStylePizza extends Pizza{
public NYStylePizza(){
name = "NYStylePizza";
dough = "thin crus dough";
sauce = "sauce";
toppings.add(“chesse”)
}
}
//测试类
public class PizzaTestDrive(){
public static void main(String[] args){
PizzaStore nyStore= new NYPizzaStore();
PizzaStore chicagoStore= new ChicagoPizzaStore();
Pizza pizza = nyStore.oderPizza("chesse");
Pizza pizza = chicagoStore.oderPizza("chesse");
}
}
工厂方法模式抽象工厂方法模式
ps:设计原则 要依赖抽象,不要依赖具体类(依赖倒置原则Depemdency Inversion Principle)
回到比萨店,每个加盟店可能会对原料进行偷工减料,或者使用低价原料,我们如何保证他们用高质量原料?
我们可以建立原料工厂,不同区域有不同原料厂。原料家族包过面团、酱料、香料等,下面就是定于原料工厂
public interface PizzaIngredientFactory{
public Dough createDough();
public Sauce createSauce();
public Chesse createChesse();
public Clams createClams();
}
现在不同区域建立不同的原料工厂,比如纽约原料工厂
public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
public Dough createDough(){
return new ThinCrustDough();
}
public Sauce createSauce(){
return new MarinaraSauce();
}
public Clams createClams(){
return new FreshClams();
}
}
现在的pizza抽象类如下
public abstract class Pizza{
String name;
Dough dough;
Sauce sauce;
Clams clams;
abstract void prepare();//这个方法声明为抽象类在这个方法中,我们要收集比萨所需原料,这些原料来源于原料工厂。
void bake(){
System.out.println("bake");
}
//其它方法也是一样就省略了。
}
直接来看比萨店吧
public class NYPizzaStore extends PizzaStore(){
protected Pizza createPizza(String item){
Pizza pizza = null;
PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
if(item.equals("chessse")){
pizza = new CheesePizza(ingreduentFactory);
pizza.setName("new york style cheesse Pizza")
}else if(item.equals("vegglie")){
pizza = new VeggliePizza(ingreduentFactory);
pizza.setName("new york style vegglie Pizza")
}else if(item.equals("clam")){
pizza = new ClamPizza(ingreduentFactory);
pizza.setName("new york style clam Pizza")
}
return pizza;
}
下面是抽象工厂类图
网友评论