设计模式之Factory深入研究

设计

今天我去市场,要决定是买水果等产品,还是选择种水果的产品。具体怎么操作自己选择。来到市场,我发现主要有一些水果:苹果(Apple),葡萄(Grape)和鸭梨(Pear)。到底买什么好呢?我一阵思量。俗话说:“饭后一只烟,赛过活神仙。饭后吃苹果,西施见我躲。”为了老婆的漂亮,我决定买苹果。

 

下面开始Factory模式研究,当然是用我上面举的例子来说明。

Simple Factory模式

专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类。 

Factory Method模式

将对象的创建交由父类中定义的一个标准方法来完成,而不是其构造函数,究竟应该创建何种对象由具体的子类负责决定。 

Abstract Factory模式

提供一个共同的接口来创建相互关联的多个对象。

 

一、Simple Factory模式:

1、  在这里,我们先定义水果(Fruit)接口:

public interface Fruit {

  void plant();  //水果是被种植的

  void enableEat();  //水果能吃

}

2、  苹果(Apple)是对水果(Fruit)接口的实现:

public class Apple implements Fruit{

  public void plant(){

    System.out.println("种苹果!");

  }

  public void enableEat(){

    System.out.println("苹果好吃!");

  }

}

3、  葡萄(Grape)是对水果(Fruit)接口的实现:

public class Grape implements Fruit{

  public void plant(){

    System.out.println("种葡萄!");

  }

  public void enableEat(){

    System.out.println("葡萄好吃!");

  }

}

4、  鸭梨(Pear)是对水果(Fruit)接口的实现:

public class Pear implements Fruit{

  public void plant(){

    System.out.println("种鸭梨!");

  }

  public void enableEat(){

    System.out.println("鸭梨好吃!");

  }

}

5、定义买水果(BuyFruit)这一过程类:

public class BuyFruit {

  /**

  简单工厂方法

  */

  public static Fruit buyFruit(String which){

    if (which.equalsIgnoreCase("apple")) {  //如果是苹果,则返回苹果实例

      return new Apple();

    }

    else if (which.equalsIgnoreCase("pear")){  //如果是鸭梨,则返回鸭梨实例

      return new Strawberry();

    }

    else if (which.equalsIgnoreCase("grape")) { //如果是葡萄,则返回葡萄实例

      return new Grape();

    }

    else{

      return null;

    }

  }

}

6、  编写测试类:

public class FruitTest {

  public static void  main(String args[]){

    BuyFruit buy = new BuyFruit();   //开始买水果这个过程

    buy.buyFruit("apple").enableEat(); //调用苹果的enableEat()方法

  }

}

7、  说明:

A:我要购买苹果,只需向工厂角色(BuyFruit)请求即可。而工厂角色在接到请求后,会自行判断创建和提供哪一个产品。

B:但是对于工厂角色(BuyFruit)来说,增加新的产品(比如说增加草莓)就是一个痛苦的过程。工厂角色必须知道每一种产品,如何创建它们,以及何时向客户端提供它们。换言之,接纳新的产品意味着修改这个工厂。

C:因此Simple Factory模式的开放性比较差。

有什么办法可以解决这个问题吗?那就需要Factory Method模式来为我们服务了。

二、Factory Method模式:

1、同样,我们先定义水果(Fruit)接口:

public interface Fruit {

  void plant();  //水果是被种植的

  void enableEat();  //水果能吃

}

2、苹果(Apple)是对水果(Fruit)接口的实现:

public class Apple implements Fruit{

  public void plant(){

    System.out.println("种苹果!");

  }

  public void enableEat(){

    System.out.println("苹果好吃!");

  }

}

3、葡萄(Grape)是对水果(Fruit)接口的实现:

public class Grape implements Fruit{

  public void plant(){

    System.out.println("种葡萄!");

  }

  public void enableEat(){

    System.out.println("葡萄好吃!");

  }

}

4、鸭梨(Pear)是对水果(Fruit)接口的实现:

public class Pear implements Fruit{

  public void plant(){

    System.out.println("种鸭梨!");

  }

  public void enableEat(){

    System.out.println("鸭梨好吃!");

  }

}

5、在这里我们将买水果(BuyFruit)定义为接口类:

public interface BuyFruit{

  /**

  工厂方法

  */

  public Fruit buyFruit();   //定义买水果这一过程

}

6、买苹果是(BuyApple)对买水果(BuyFruit)这个接口的实现

public class BuyApple implements BuyFruit{

  public Fruit buyFruit(){

    return new Apple();  //返回苹果实例

}

}

7、买鸭梨是(BuyPear)对买水果(BuyFruit)这个接口的实现

public class BuyPear implements BuyFruit{

  public Fruit BuyPear (){

    return new Pear();  //返回鸭梨实例

}

}

8、买葡萄是(BuyGrape)对买水果(BuyFruit)这个接口的实现

public class BuyGrape implements BuyFruit{

  public Fruit BuyGrape (){

    return new Grape ();  //返回葡萄实例

}

}

9、编写测试类:

public class FruitTest {

  public static void  main(String args[]){

    BuyApple buy = new BuyApple(); //开始买水果这个过程

    buy.buyFruit().enableEat();      //调用苹果的enableEat()方法

  }

}

10、说明:

A:工厂方法模式和简单工厂模式在结构上的不同是很明显的。工厂方法模式的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。工厂方法模式可以允许很多具体工厂类从抽象工厂类中将创建行为继承下来,从而可以成为多个简单工厂模式的综合,进而推广了简单工厂模式。

B:工厂方法模式退化后可以变得很像简单工厂模式。设想如果非常确定一个系统只需要一个具体工厂类,那么就不妨把抽象工厂类合并到具体的工厂类中去。由于反正只有一个具体工厂类,所以不妨将工厂方法改成为静态方法,这时候就得到了简单工厂模式。

C:如果需要加入一个新的水果,那么只需要加入一个新的水果类以及它所对应的工厂类。没有必要修改客户端,也没有必要修改抽象工厂角色或者其他已有的具体工厂角色。对于增加新的水果类而言,这个系统完全支持“开-闭”原则。

D:对Factory Method模式而言,它只是针对一种类别(如本例中的水果类Fruit),但如果我们还想买肉,那就不行了,这是就必须要Abstract Factory Method模式帮忙了。

三、Abstract Factory模式

1、同样,我们先定义水果(Fruit)接口:

public interface Fruit {

  void plant();  //水果是被种植的

  void enableEat();  //水果能吃

}

2、苹果(Apple)是对水果(Fruit)接口的实现:

public class Apple implements Fruit{

  public void plant(){

    System.out.println("种苹果!");

  }

  public void enableEat(){

    System.out.println("苹果好吃!");

  }

}

3、葡萄(Grape)是对水果(Fruit)接口的实现:

public class Grape implements Fruit{

  public void plant(){

    System.out.println("种葡萄!");

  }

  public void enableEat(){

    System.out.println("葡萄好吃!");

  }

}

4、鸭梨(Pear)是对水果(Fruit)接口的实现:

public class Pear implements Fruit{

  public void plant(){

    System.out.println("种鸭梨!");

  }

  public void enableEat(){

    System.out.println("鸭梨好吃!");

  }

}

5、  定义肉(Meat)接口:

public interface Meat {

  void feed();  //肉是喂养的

  void enableEat();  //肉能吃

}

6、  猪肉(BigMeat)是对肉(Meat)接口的实现:

public class BigMeat implements Meat{

  public void feed(){

    System.out.println("养猪!");

  }

  public void enableEat(){

    System.out.println("猪肉好吃!");

  }

}

7、  牛肉(CowMeat)是对肉(Meat)接口的实现:

public class CowMeat implements Meat {

  public void feed(){

    System.out.println("养牛!");

  }

  public void enableEat(){

    System.out.println("牛肉好吃!");

  }

}

8、  我们可以定义买货人(Buyer)接口:

public interface Buyer {

  /**

   买水果工厂方法

   */

  public Fruit buyFruit(Fruit whichFruit);

  /**

   买肉的工厂方法

   */

  public Meat buyMeat(Meat whichMeat);

}

9、  我(MyBuyer)是对买货人(Buyer)接口的实现:

public class MyBuyer implements Buyer{

  /**

   买水果工厂方法

   */

  public Fruit buyFruit(Fruit whichFruit){

     return whichFruit;

  }

  /**

   买肉的工厂方法

   */

  public Meat buyMeat(Meat whichMeat){

     return whichMeat;

  }

}

10、编写测试类:

public class MyBuyerAbstractTest {

  public static void  main(String args[]){

    Fruit apple = new Apple();   //苹果实例

    Meat big = new BigMeat();  //猪肉实例

    MyBuyer my = new MyBuyer();  //我是买者的实例

    my.buyFruit(apple).enableEat();  //我买苹果

    my.buyMeat(big).enableEat();    //我买猪肉

  }

}

11、说明:

A:抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。这就是抽象工厂模式的用意。

B:抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。

时间: 2024-10-27 05:16:59

设计模式之Factory深入研究的相关文章

设计模式[21]-Factory Method

Type: Creational Factory Method: 定义一个创建对象的接口,但是让子类决定实例化哪个类.新增加一个产品的时候,只需派生一个该类型的工厂而无需修改原来的代码.每个具体工厂只负责返回一种产品类.是最典型的模板方法模式(Templete Method pattern)应用. #include <iostream> using namespace std; class Product{}; class ConcreteProduct: public Product { p

设计模式--Simple Factory 模式

Simple Factory模式(又称Static Factory模式),一个Simple Factory生产成品,而对客户端隐藏产品产生的细节.实作时定义一个产品介面(interface),并透过特定静态方法来建立成品.  假设有一个音乐盒工厂,购买音乐盒的客人不用知道音乐盒是如何制作的,他只要知道如何播放音乐盒就可以了,以 UML 类别图来表示以上的概念: 如上图所示的,MusicBoxDemo代表了客户的角色,它只依赖于IMusicBox介面,而不关心特定的实作,实际如何产生IMusicB

在Java中应用设计模式--Factory Method

设计 在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子,它是最重要的模式之一.在很多地方我们都会看到xxxFactory这样命名的类,那么,什么是Factory Method,为什么要用这个模式,如何用Java语言来实现该模式,这就是本文想要带给大家的内容. 基本概念 Factory Method是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要

设计模式(Patterns in Java)

设计 板桥里人的设计模式讲解是国内媒体(包括书籍和网站)中最早的成体系介绍,本系列介绍纯为免费传播(转载本站文章,请保留作者和网址),尽量做到言简意赅,通俗易懂,但是难免有所疏漏敬请来信或论坛讨论,不断完善. 真正掌握设计模式需要在实践中不断研究和使用,关于设计模式在具体实例的应用,可以阅读板桥里人的书籍<Java实用系统开发指南>.书籍中8个实例都从设计模式.框架等高度对系统进行崭新的设计和实现,这种应用理念正是现在以及将来软件设计和编程的根本之道. 1:前言 学习GoF设计模式的重要性 建

ASP.NET的MVC设计模式

当开发者听到"设计模式"这个词时,他们通常联想到两个场景. 一组开发者正在讨论许多创造性意见,正在开会,但是却没有进行编码.另外一 组人能制定出正确的计划,保证系统能够开发成功,代码可以重用. 而现实一般都处于两者中间.在为他们的公司设计解决方案的时候,结构设计 者和系统设计者应该寻找重复的模式.但是模式只是开发健壮.可重用代码的一 个指导.结构设计者不能过多的去设计一个解决方案的结构,因为要定期交货. 过多的设计系统结构的主要受害者是Web应用程序.因为多数Web应用程序是用 来浏览

Java设计模式学习心得

整个设计模式贯穿一个原理:面对介面编程,而不是面对实现,(面向物件编程应该改爲面向介面编程).目标原则是:降低耦合,增强灵活性. 一.创建模式 1.设计模式之Factory(工厂方法和抽象工厂) 使用工厂模式就象使用new一样频繁. 2.设计模式之Prototype(原型) 用原型实例指定创建物件的种类,並且通过拷贝这些原型创建新的物件. 3.设计模式之Builder 汽车由车轮 方向盘 发动机很多部件组成,同时,将这些部件组装成汽车也是一件複杂的工作,Builder模式就是将这两种情况分开进行

[JAVA软件工程师-面试宝典-2013最新版]

[JAVA面试宝典-2013最新版] 一. Java基础部分......................................................................................................2 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?.....2 2.Java有没有goto?....................................................

我的Java开发学习之旅------&amp;gt;Java经典面试题

摘自张孝祥itcast 从享受生活的角度上来说:"程序员并不是一种最好的职业,我认为两种人可以做程序员,第一,你不做程序员,你就没有什么工作可做,或者说是即使有可以做的工作但是你非常不愿意去做:第二,你非常痴迷和爱好程序,并且在这方面有一些天赋和优势.程序员的结局也是有两种:第一,默默退休,第二以程序员为起点或跳板,注意积累,跟对了好的老板或团队,找到和很好的搭档自己创业,成为IT金领和富翁." 人们在时间面前是平等的,吾生也有涯,所以,你的经验更丰富点,那不算什么,经验是用时间积累的

036_《Inside 深入核心VCL架构剖析》

<Inside 深入核心VCL架构剖析> Delphi 教程 系列书籍 (036) <Inside 深入核心VCL架构剖析> 网友(邦)整理 EMail: shuaihj@163.com 下载地址: Part1 Part2 Part3 Part4 Part5 附书源码 作者: 李维 丛书名: 李维作品系列 出版社:电子工业出版社 ISBN:7505394894 上架时间:2003-12-30 出版日期:2003 年12月 开本:16开 页码:706 版次:1-1 内容简介 本书包括