首页 > 代码库 > 设计模式(4)--工厂模式
设计模式(4)--工厂模式
能解决什么样的问题
假设一种这样的情形,先有个披萨店,里面有各种各样的披萨,每种披萨当然会加不同的调料。当客人来点餐时,直接就会跟服务员说来个xx披萨,或许他还会说少点番茄酱。把这个写成一个java程序,测试时main函数里创建一个披萨,最后打印出披萨信息,你会如何解决呢?
如果你碰到类似于这样的问题,那么使用工厂模式是一个不错的选择。
如何解决问题
根据前面所介绍的模式,相信你已经发现了我们应该尽量针对接口编程,而不是针对实现进行编程。
1.定义一个调料接口Ingredient,所有的调料都实现这个接口,该接口包含一个getName方法
2.定义一个披萨抽象类Pizza,当然也可以定义成接口,但是定义成接口那么就不能包含属性了,这个选择哪种根据自己的实际需求。所有的具体披萨类都需要实现这个抽象类,这个抽象类中包含属性有String类型的name和List<Ingredient>类型的ingredient,方法有抽象方法add(添加调料)和以实现的方法display(主要是打印出该披萨的名称和调料)。
3.定义一个工厂接口Factory,其方法有getIngredient,有个参数为name,即为调料名称,主要就是用来添加调料。这里定义一个接口是为了以后便于扩展,如果直接定义一个工厂具体类,以后要是有其他的调料工厂(不同地区所使用的调料可能不一,尽管可能名字一样),那么这时候你就需要修改披萨类中包含了工厂类型了,这样就针对实现进行编程了,极大降低了扩展性。
4.定义一些具体的工厂类,这里就只定义一个具体工厂类IngredientFactory,实现接口中的方法,根据调料名称生产出不同的调料。
5.定义一些具体的调料类,如Cheese、Clam、Sauce、Dough等,这些调料都实现Ingredient接口
6.定义一些具体的Pizza类,如CheesePizza、ClamPizza等,这些类需要继承Pizza这个抽象类,实现其中为实现的方法,当然也需要有个工厂类的属性,这个用来生产调料。
7.测试这样设计是否可以解决问题
示例代码如下:
注意以下代码不是一个文件
//Ingredient.java public interface Ingredient { public String getName(); } //Cheese.java public class Cheese implements Ingredient { private String name; public Cheese() { name = "Chess"; } @Override public String getName() { return name; } } //Clam.java public class Clam implements Ingredient { private String name; public Clam() { name = "Clam"; } @Override public String getName() { return name; } } //Sauce.java public class Sauce implements Ingredient { private String name; public Sauce() { name = "Sauce"; } @Override public String getName() { return name; } } //Factory public interface Factory { public Ingredient getIngredient(String name); } //IngredientFactory.java public class IngredientFactory implements Factory { @Override public Ingredient getIngredient(String name) { if ("cheese".equals(name)) { return new Cheese(); } else if ("clam".equals(name)) { return new Clam(); } else if ("sauce".equals(name)) { return new Sauce(); } else { return null; } } } //Pizza.java import java.util.List; public abstract class Pizza { protected String name; protected List<Ingredient> ingredients; public void display() { System.out.println("pizza name:" + name); if (ingredients.size() > 0) { System.out.print("ingredients:"); for (Ingredient ingredient : ingredients) { System.out.print(ingredient.getName() + " "); } } } public abstract void addIngredient(); } //CheesePizza.java import java.util.ArrayList; public class CheesePizza extends Pizza { private Factory ingredientFactory; public CheesePizza(Factory factory) { this.ingredientFactory = factory; name = "CheesePizza"; ingredients = new ArrayList<Ingredient>(); addIngredient(); } @Override public void addIngredient() { ingredients.add(ingredientFactory.getIngredient("sauce")); ingredients.add(ingredientFactory.getIngredient("cheese")); } } //ClamPizza.java import java.util.ArrayList; public class ClamPizza extends Pizza { private Factory ingredientFactory; public ClamPizza(Factory factory) { name = "ClamPizza"; this.ingredientFactory = factory; ingredients = new ArrayList<Ingredient>(); addIngredient(); } @Override public void addIngredient() { ingredients.add(ingredientFactory.getIngredient("sauce")); ingredients.add(ingredientFactory.getIngredient("clam")); } } //测试类 Test.java public class Test { public static void main(String[] args) { Pizza pizza = new CheesePizza(new IngredientFactory()); pizza.display(); } }
自己动手试试吧,我觉你的猜测肯定是对的。
下一篇将介绍单例模式,如果大家对我的博客有什么见解或疑问可以留言
设计模式(4)--工厂模式