欢迎访问 生活随笔!

尊龙游戏旗舰厅官网

当前位置: 尊龙游戏旗舰厅官网 > 编程资源 > 编程问答 >内容正文

编程问答

工厂与抽象工厂 -尊龙游戏旗舰厅官网

发布时间:2024/10/14 编程问答 13 豆豆
尊龙游戏旗舰厅官网 收集整理的这篇文章主要介绍了 工厂与抽象工厂 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

本篇文章代码:https://gitee.com/bithachi_admin_admin/mycode/tree/master/设计模式/factory

1. 什么是工厂模式?

  • 工厂模式(factory pattern)提供了一种创建对象的最佳方式,是 java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式。
  • 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

**意图:**定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。(依赖倒置原则)

**主要解决:**主要解决接口选择的问题。

**何时使用:**我们明确地计划不同条件下创建不同实例时。

**如何解决:**让其子类实现工厂接口,返回的也是一个抽象的产品。

**关键代码:**创建过程在其子类执行。

应用实例:

  • 您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
  • mybatis换数据库只需换方言和驱动就可以。

优点:

  • 一个调用者想创建一个对象,只要知道其名称就可以了。
  • 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  • 屏蔽产品的具体实现,调用者只关心产品的接口。

**缺点:**每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

使用场景:

  • 日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
  • 数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
  • 设计一个连接服务器的框架,需要三个协议,“pop3”、“imap”、“http”,可以把这三个作为产品类,共同实现一个接口。

**注意事项:**作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

2. 加盟披萨店案例

案例描述:你有一家披萨店,经营有成,击败了许多的竞争者,现在你想开扩大市场,建立加盟店。因为区域的差异,每家加盟店都可能想要提供不同风味的比萨(比方说纽约、芝加哥、加州),这受到了开店地点及该地区比萨美食家口味的影响。那么如何设计呢?

下面是案例的uml模型设计图:

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;} }

nypizzastore:

public class nypizzastore extends pizzastore {@overridepizza createpizza(string item) {if (item.equals("cheese")) {return new nystylecheesepizza();} else if (item.equals("veggie")) {return new nystyleveggiepizza();} else if (item.equals("clam")) {return new nystyleclampizza();} else if (item.equals("pepperoni")) {return new nystylepepperonipizza();} else {return null;}} }

pizza:

import java.util.arraylist; public abstract class pizza {string name;string dough;string sauce;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;}@overridepublic 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();} }

nystylecheesepizza**:**

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");} }

披萨店测试:

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("clam");system.out.println("ethan ordered a " pizza.getname() "\n");pizza = chicagostore.orderpizza("clam");system.out.println("joel ordered a " pizza.getname() "\n");pizza = nystore.orderpizza("pepperoni");system.out.println("ethan ordered a " pizza.getname() "\n");pizza = chicagostore.orderpizza("pepperoni");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");} }

运行结果:

--- making a ny style sauce and cheese pizza --- prepare ny style sauce and cheese pizza tossing dough... adding sauce... adding toppings: grated reggiano cheese bake for 25 minutes at 350 cut the pizza into diagonal slices place pizza in official pizzastore box ethan ordered a ny style sauce and cheese pizza--- making a chicago style deep dish cheese pizza --- prepare chicago style deep dish cheese pizza tossing dough... adding sauce... adding toppings: shredded mozzarella cheese bake for 25 minutes at 350 cutting the pizza into square slices place pizza in official pizzastore box joel ordered a chicago style deep dish cheese pizza--- making a ny style clam pizza --- prepare ny style clam pizza tossing dough... adding sauce... adding toppings: grated reggiano cheesefresh clams from long island sound bake for 25 minutes at 350 cut the pizza into diagonal slices place pizza in official pizzastore box ethan ordered a ny style clam pizza--- making a chicago style clam pizza --- prepare chicago style clam pizza tossing dough... adding sauce... adding toppings: shredded mozzarella cheesefrozen clams from chesapeake bay bake for 25 minutes at 350 cutting the pizza into square slices place pizza in official pizzastore box joel ordered a chicago style clam pizza--- making a ny style pepperoni pizza --- prepare ny style pepperoni pizza tossing dough... adding sauce... adding toppings: grated reggiano cheesesliced pepperonigarliconionmushroomsred pepper bake for 25 minutes at 350 cut the pizza into diagonal slices place pizza in official pizzastore box ethan ordered a ny style pepperoni pizza--- making a chicago style pepperoni pizza --- prepare chicago style pepperoni pizza tossing dough... adding sauce... adding toppings: shredded mozzarella cheeseblack olivesspinacheggplantsliced pepperoni bake for 25 minutes at 350 cutting the pizza into square slices place pizza in official pizzastore box joel ordered a chicago style pepperoni pizza--- making a ny style veggie pizza --- prepare ny style veggie pizza tossing dough... adding sauce... adding toppings: grated reggiano cheesegarliconionmushroomsred pepper bake for 25 minutes at 350 cut the pizza into diagonal slices place pizza in official pizzastore box ethan ordered a ny style veggie pizza--- making a chicago deep dish veggie pizza --- prepare chicago deep dish veggie pizza tossing dough... adding sauce... adding toppings: shredded mozzarella cheeseblack olivesspinacheggplant bake for 25 minutes at 350 cutting the pizza into square slices place pizza in official pizzastore box joel ordered a chicago deep dish veggie pizza进程已结束,退出代码0

1. 什么是抽象工厂模式?

  • 抽象工厂模式(abstract factory pattern)是围绕一个超级工厂创建其他工厂。该超级工厂为其他工厂的父工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
  • 在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

**意图:**提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

**主要解决:**主要解决接口选择的问题。

**何时使用:**系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

**如何解决:**在一个产品族里面,定义多个产品。

**关键代码:**在一个工厂里聚合多个同类产品。

**应用实例:**工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况,在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 oop 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

**优点:**当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

**缺点:**产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 creator 里加代码,又要在具体的里面加代码。

使用场景: 1、qq 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

**注意事项:**产品族难扩展,产品等级易扩展。

2. 给加盟披萨店新增原料工厂

案例描述:你有一家披萨店,经营有成,击败了许多的竞争者,现在你想开扩大市场,建立加盟店。因为区域的差异,每家加盟店都可能想要提供不同风味的比萨(比方说纽约、芝加哥、加州),这受到了开店地点及该地区比萨美食家口味的影响。那么如何设计呢?这是我们工厂模式的案例,现在我们在此案例上加点东西,我们希望所有的加盟店都使用统一的调料(原料):面团、酱料、腊肠、芝士、蔬菜、肉等。我们可以建造原料工厂来满足这种需求。

下面是uml设计模型:

下面给出核心实现代码;

**
**

披萨抽象类pizza:

public abstract class pizza {string name;dough dough;sauce sauce;veggies veggies[];cheese cheese;pepperoni pepperoni;clams clam;abstract void prepare();void bake() {system.out.println("bake for 25 minutes at 350");}void cut() {system.out.println("cutting the pizza into diagonal slices");}void box() {system.out.println("place pizza in official pizzastore box");}void setname(string name) {this.name = name;}string getname() {return name;}@overridepublic string tostring() {stringbuffer result = new stringbuffer();result.append("---- " name " ----\n");if (dough != null) {result.append(dough);result.append("\n");}if (sauce != null) {result.append(sauce);result.append("\n");}if (cheese != null) {result.append(cheese);result.append("\n");}if (veggies != null) {for (int i = 0; i < veggies.length; i) {result.append(veggies[i]);if (i < veggies.length-1) {result.append(", ");}}result.append("\n");}if (clam != null) {result.append(clam);result.append("\n");}if (pepperoni != null) {result.append(pepperoni);result.append("\n");}return result.tostring();} }

具体的某种披萨类cheesepizza:

public class cheesepizza extends pizza {//原料工厂pizzaingredientfactory ingredientfactory;public cheesepizza(pizzaingredientfactory ingredientfactory) {this.ingredientfactory = ingredientfactory;}@overridevoid prepare() {system.out.println("preparing " name);dough = ingredientfactory.createdough();sauce = ingredientfactory.createsauce();cheese = ingredientfactory.createcheese();} }

披萨店抽象类pizzastore:

public abstract class pizzastore {protected 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;} }

纽约披萨店nypizzastore:

**
**

public class nypizzastore extends pizzastore {@overrideprotected pizza createpizza(string item) {pizza pizza = null;pizzaingredientfactory ingredientfactory = new nypizzaingredientfactory();if (item.equals("cheese")) {pizza = new cheesepizza(ingredientfactory);pizza.setname("new york style cheese pizza");} else if (item.equals("veggie")) {pizza = new veggiepizza(ingredientfactory);pizza.setname("new york style veggie pizza");} else if (item.equals("clam")) {pizza = new clampizza(ingredientfactory);pizza.setname("new york style clam pizza");} else if (item.equals("pepperoni")) {pizza = new pepperonipizza(ingredientfactory);pizza.setname("new york style pepperoni pizza");} return pizza;} }

原料工厂抽象类****pizzaingredientfactory:

public interface pizzaingredientfactory {public dough createdough();public sauce createsauce();public cheese createcheese();public veggies[] createveggies();public pepperoni createpepperoni();public clams createclam(); }

具体的纽约原料工厂****nypizzaingredientfactory:

public class nypizzaingredientfactory implements pizzaingredientfactory {@overridepublic dough createdough() {return new thincrustdough();}@overridepublic sauce createsauce() {return new marinarasauce();}@overridepublic cheese createcheese() {return new reggianocheese();}@overridepublic veggies[] createveggies() {veggies veggies[] = { new garlic(), new onion(), new mushroom(), new redpepper() };return veggies;}@overridepublic pepperoni createpepperoni() {return new slicedpepperoni();}@overridepublic clams createclam() {return new freshclams();} }

某类型的具体原料产品****mushroom:

public class mushroom implements veggies {@overridepublic string tostring() {return "mushrooms";} }

测试运行pizzatestdrive

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 "\n");pizza = chicagostore.orderpizza("cheese");system.out.println("joel ordered a " pizza "\n");pizza = nystore.orderpizza("clam");system.out.println("ethan ordered a " pizza "\n");pizza = chicagostore.orderpizza("clam");system.out.println("joel ordered a " pizza "\n");pizza = nystore.orderpizza("pepperoni");system.out.println("ethan ordered a " pizza "\n");pizza = chicagostore.orderpizza("pepperoni");system.out.println("joel ordered a " pizza "\n");pizza = nystore.orderpizza("veggie");system.out.println("ethan ordered a " pizza "\n");pizza = chicagostore.orderpizza("veggie");system.out.println("joel ordered a " pizza "\n");} }

运行结果:

--- making a new york style cheese pizza --- preparing new york style cheese pizza bake for 25 minutes at 350 cutting the pizza into diagonal slices place pizza in official pizzastore box ethan ordered a ---- new york style cheese pizza ---- thin crust dough marinara sauce reggiano cheese--- making a chicago style cheese pizza --- preparing chicago style cheese pizza bake for 25 minutes at 350 cutting the pizza into diagonal slices place pizza in official pizzastore box joel ordered a ---- chicago style cheese pizza ---- thickcrust style extra thick crust dough tomato sauce with plum tomatoes shredded mozzarella--- making a new york style clam pizza --- preparing new york style clam pizza bake for 25 minutes at 350 cutting the pizza into diagonal slices place pizza in official pizzastore box ethan ordered a ---- new york style clam pizza ---- thin crust dough marinara sauce reggiano cheese fresh clams from long island sound--- making a chicago style clam pizza --- preparing chicago style clam pizza bake for 25 minutes at 350 cutting the pizza into diagonal slices place pizza in official pizzastore box joel ordered a ---- chicago style clam pizza ---- thickcrust style extra thick crust dough tomato sauce with plum tomatoes shredded mozzarella frozen clams from chesapeake bay--- making a new york style pepperoni pizza --- preparing new york style pepperoni pizza bake for 25 minutes at 350 cutting the pizza into diagonal slices place pizza in official pizzastore box ethan ordered a ---- new york style pepperoni pizza ---- thin crust dough marinara sauce reggiano cheese garlic, onion, mushrooms, red pepper sliced pepperoni--- making a chicago style pepperoni pizza --- preparing chicago style pepperoni pizza bake for 25 minutes at 350 cutting the pizza into diagonal slices place pizza in official pizzastore box joel ordered a ---- chicago style pepperoni pizza ---- thickcrust style extra thick crust dough tomato sauce with plum tomatoes shredded mozzarella black olives, spinach, eggplant sliced pepperoni--- making a new york style veggie pizza --- preparing new york style veggie pizza bake for 25 minutes at 350 cutting the pizza into diagonal slices place pizza in official pizzastore box ethan ordered a ---- new york style veggie pizza ---- thin crust dough marinara sauce reggiano cheese garlic, onion, mushrooms, red pepper--- making a chicago style veggie pizza --- preparing chicago style veggie pizza bake for 25 minutes at 350 cutting the pizza into diagonal slices place pizza in official pizzastore box joel ordered a ---- chicago style veggie pizza ---- thickcrust style extra thick crust dough tomato sauce with plum tomatoes shredded mozzarella black olives, spinach, eggplant进程已结束,退出代码0
  • 工厂方法使用继承: 把对象的创建委托给子类,子类实现工厂方法来创建对象。
  • 抽象工厂使用对象组合(在): 对象的创建被实现在工厂接口所暴露出来的方法中。

总结

以上是尊龙游戏旗舰厅官网为你收集整理的工厂与抽象工厂的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得尊龙游戏旗舰厅官网网站内容还不错,欢迎将尊龙游戏旗舰厅官网推荐给好友。

网站地图