申请书范文网,分享全网优秀范文,学习好帮手!
申请书范文网 > 1-4 工厂模式(工厂方法模式/抽象工厂模式)

1-4 工厂模式(工厂方法模式/抽象工厂模式)

时间:2019-08-11 04:52:28

相关推荐

1-4 工厂模式(工厂方法模式/抽象工厂模式)

工厂模式

工厂模式 概念解释需求1 普通实现简单工厂产生具体披萨 披萨店调用工厂做出具体披萨工厂方法模式 简单工厂与工厂方法的区别 需求2 保证风味种类或者说原料都得是指定的 抽象工厂模式工厂方法和抽象工厂的区别

注意:接口:泛指狭义上的接口,也可以指抽象类

概念解释

工厂方法模式:

定义一个创建对象的接口,但由子类决定实例化的具体类型。即,将类的实例化推迟到了子类。抽象工厂模式

提供一个接口,用于创建相关或依赖对象的家族。也是吧类的实例推迟到了子类

具体区别下文会有介绍。

简单工厂的方式 不是设计模式,更多的是一种编码规范。

需求1

创建一个不同地区(纽约、芝加哥)风味的披萨点 生产的不同种类( chessse veggie)披萨

1 普通实现

// 披萨店直接做具体类型的披萨 耦合性极大public class DependentPizzaStore {public Pizza createPizza(String style, String type) {Pizza pizza = null;if (style.equals("NY")) {if (type.equals("cheese")) {pizza = new NYStyleCheesePizza();} else if (type.equals("veggie")) {pizza = new NYStyleVeggiePizza();} } else if (style.equals("Chicago")) {if (type.equals("cheese")) {pizza = new ChicagoStyleCheesePizza();} else if (type.equals("veggie")) {pizza = new ChicagoStyleVeggiePizza();}} else {System.out.println("Error: invalid type of pizza");return null;}pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}}

2 简单工厂产生具体披萨 披萨店调用工厂做出具体披萨

简单工厂其实不是一个设计模式,更像是一种变成习惯

// 普通做法相比 只是将做披萨封装出去,有工厂提供。public class SimplePizzaFactory {public Pizza createPizza(String type) {// type 类型 即代表披萨店区域,又代表披萨的种类。两个维度 这样不好Pizza pizza = null;if (type.equals("NYcheese")) {pizza = new NYCheesePizza();} else if (type.equals("NYveggie")) {pizza = new NYVeggiePizza();}else if (type.equals("Chicagocheese")) {pizza = new ChicagoCheesePizza();} else if (type.equals("Chicagoveggie")) {pizza = new ChicagoVeggiePizza();}return pizza;}}public class PizzaStore {SimplePizzaFactory factory;public PizzaStore(SimplePizzaFactory factory) { this.factory = factory;}public Pizza orderPizza(String type) {Pizza pizza = factory.createPizza(type);pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}}

3 工厂方法模式

// 把做什么风味的决定权交给披萨店(PizzaStore) 把做披萨还得限制于具体PizzaStore类中public abstract class PizzaStore {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;}// 由子披萨店,即各地区披萨店自主决定(pizzaStore的类型)披萨风味和披萨种类(type)abstract Pizza createPizza(String type);}public class NYPizzaStore extends PizzaStore {Pizza createPizza(String item) {// 另外,靠字符串匹配,出错几率大些,可用代表参数类型的对象,静态变量、枚举代替if (item.equals("cheese")) {return new NYStyleCheesePizza();} else if (item.equals("veggie")) {return new NYStyleVeggiePizza();} else return null;}}public class ChicagoPizzaStore extends PizzaStore {Pizza createPizza(String item) {if (item.equals("cheese")) {return new ChicagoStyleCheesePizza();} else if (item.equals("veggie")) {return new ChicagoStyleVeggiePizza();} else return null;}}// 测试public class PizzaTestDrive {public static void main(String[] args) {PizzaStore nyStore = new NYPizzaStore();PizzaStore chicagoStore = new ChicagoPizzaStore();Pizza pizza = nyStore.orderPizza("cheese");System.out.println("Ethan ordered a " + pizza.getName() + "\n");pizza = chicagoStore.orderPizza("cheese");System.out.println("Joel ordered a " + pizza.getName() + "\n");pizza = nyStore.orderPizza("veggie");System.out.println("Ethan ordered a " + pizza.getName() + "\n");pizza = chicagoStore.orderPizza("veggie");System.out.println("Joel ordered a " + pizza.getName() + "\n");}}// 公共代码public abstract class Pizza {//原料 下边会有对原料的变体String name;String dough;String sauce;String veggie;String clam;String perpersoni;ArrayList<String> toppings = new ArrayList<String>();void prepare() {// 对基本披萨的处理System.out.println("Prepare " + name);System.out.println("Tossing dough...");System.out.println("Adding sauce...");System.out.println("Adding toppings: ");for (String topping : toppings) {System.out.println(" " + topping);}}void bake() {System.out.println("Bake for 25 minutes at 350");}void cut() {System.out.println("Cut the pizza into diagonal slices");}void box() {System.out.println("Place pizza in official PizzaStore box");}public String getName() {return name;}public String toString() {StringBuffer display = new StringBuffer();display.append("---- " + name + " ----\n");display.append(dough + "\n");display.append(sauce + "\n");for (String topping : toppings) {display.append(topping + "\n");}return display.toString();}}public class ChicagoStyleCheesePizza extends Pizza {public ChicagoStyleCheesePizza() { name = "Chicago Style Deep Dish Cheese Pizza";dough = "Extra Thick Crust Dough";sauce = "Plum Tomato Sauce";toppings.add("Shredded Mozzarella Cheese");}void cut() {System.out.println("Cutting the pizza into square slices");}}public class NYStyleCheesePizza extends Pizza {public NYStyleCheesePizza() { name = "NY Style Sauce and Cheese Pizza";dough = "Thin Crust Dough";sauce = "Marinara Sauce";toppings.add("Grated Reggiano Cheese");}}

简单工厂与工厂方法的区别

简单工厂把全部工作在一个地方都处理完了;它把创建产品的代码封装起来,但不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品

抽象工厂方法却是创建一个框架,让子类决定如何实现,即子类决定产品类型

需求2 保证风味种类或者说原料都得是指定的

用对象来限定种类

4 抽象工厂模式

//定义产生产品家族的接口-抽象工厂public interface PizzaIngredientFactory {//每种原料就是一种类public Dough createDough();public Sause createSause();public Cheese createCheese ();}// 具体工厂决定具体的产品public NYPizzaIngredientFactory implements PizzaIngredientFactory {public Dough createDough(){return ThinCrustDoough();}public Sause createSause(){return MarinaraSause();}}// 给披萨加上配料public abstract class Pizza{public Dough dough;public Sause sause;public Veggies veggies[];public Cheese cheese;public Peppersoni perppersoni;public Clams clams;abstract void prepare();// 声明称抽象,从原料工厂中获取pizza所需的具体风味原料void bake() {System.out.println("Bake for 25 minutes at 350");}void cut() {System.out.println("Cut the pizza into diagonal slices");}void box() {System.out.println("Place pizza in official PizzaStore box");}public String getName() {return name;}public String toString() {StringBuffer display = new StringBuffer();display.append("---- " + name + " ----\n");display.append(dough + "\n");display.append(sauce + "\n");for (String topping : toppings) {display.append(topping + "\n");}return display.toString();}}//具体类型的披萨public ChessPizza extends Pizza{PizzaIngredientFactory pizzaIngredientFactory; // 盛放具体类型的原料工厂public ChessPizza(PizzaIngredientFactory pizzaIngredientFactory){this.pizzaIngredientFactory = pizzaIngredientFactory;}@Overridepublic void prepare(){this.dough = pizzaIngredientFactory.getDough();this.sause= pizzaIngredientFactory.getSause();}}public Veggiesizza extends Pizza{PizzaIngredientFactory pizzaIngredientFactory; // 盛放具体类型的原料工厂public ChessPizza(PizzaIngredientFactory pizzaIngredientFactory){this.pizzaIngredientFactory = pizzaIngredientFactory;}@Overridepublic void prepare(){// 具体风味的不同,及配料的不同this.dough = pizzaIngredientFactory.getDough();this.sause= pizzaIngredientFactory.getSause();this.veggies= pizzaIngredientFactory.getVeggies();}}//纽约地区的披萨店public NYPizzaStore extends PizzaStore {Pizza pizza = null;PizzaIngredientFactory pizzaIngredientFactory = new NYPizzaIngredientFactory();//NYPizzaIngredientFactory是NYPizzaStore披萨店的配料@Overridepublic Pizza createPizza(String type){if("cheese".equals(type)){ pizza = new CheesePizza(pizzaIngredientFactory);}if("veggie".equals(type)){pizza = new Veggiesizza(pizzaIngredientFactory);}}} //测试public orderPizzaTest{main(String[] args){//由子类决定store 以及风味(配料)的类型PizzaStore nyStore = new NYPizzaStore();PizzaIngredientFactory nyPizzaIngredientFactory = new NYPizzaIngredientFactory();Pizza chessPizza = nyStore.orderPizza("cheese"); //完成了下边的工作 - //一旦确定了PizzaStore的类型,也就确定了原料工厂类型;设置"cheese"类型时,把原料工厂类型设置给了chessPizza;- // Pizza chessPizza = createPissa("cheese"); 完成了基本的创建- // chessPizza = chessPizza.prepare()//pizza的具体类型调用后续处理,将原料设置给了基本的披萨}}

工厂方法和抽象工厂的区别

类/对象

工厂方法使用的是类, 去继承一个类,并覆盖它的工厂方法;

抽象工厂使用的是对象, 去组合。

实例化一个产品/一群产品

这也说明了两者的使用场景;

抽象方法模式中的方法其实就是工厂模式实现的

脑袋有点蒙了 ,有时间再做更正

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。