`
sqe_james
  • 浏览: 264919 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

设计模式

    博客分类:
  • Java
阅读更多

1. 单态模式

单态模式限制了类实例的创建,但采用这种模式设计的类,可以保证仅有一个实例,并可提供访问该实例的全局访问点。J2EE应用的大量组件,都需要保证一个类只有一个实例。比如数据库引擎访问点只能有一个。

更多的时候,为了提高性能,程序应尽量减少Java对象的创建和销毁时的开销。使用单态模式可避免Java类被多次实例化,让相同类的全部实例共享同一内存区。

为了防止单态模式的类被多次实例化,应将类的构造器设成私有,这样就保证了只能通过静态方法获得类实例。而该静态方法则保证每次返回的实例都是同一个,这就需将该类的实例设置成类属性,由于该属性需要被静态方法访问,因此该属性应设成静态属性。

下面给出单态模式的示例代码:

package  janier.servlet;

  public class SingletonTest {
  private String value;
  private static SingletonTest instance;
  private SingletonTest() {
    System.out.println( "正在执行构造器..." );
    }
   
   public static SingletonTest getInstance() {
   if (instance == null ) {
     instance = new SingletonTest();
   }
   return instance;
   }
  
   public String getValue() {
     return value;
   }
  
   public void setValue(String value) {
     this .value = value;
   }
  
   public static void main(String[] args) {
     SingletonTest t1 = SingletonTest.getInstance();
     SingletonTest t2 = SingletonTest.getInstance();
     t2.setValue( "test" );
     System.out.println(t1 == t2);
    }
 }
 

运行实例,两个打印结果完全相同。这证明单态模式的类全部实例共享一个实例。对于单态模式的类,无论有多少次的创建实例请求,都只执行一次构造器。


2. 工厂模式

工厂模式是专门负责将大量有共同接口的类实例化,而不必事先知道每次是要实例化哪一个类的模式.

工厂模式有几种形态:

  • 简单工厂(Simple Factory)模式,又称静态工厂模式(Static Factory Method Pattern);
  • 工厂方法(Factory Method)模式,又称多态工厂(Polymorphic Factory)模式或虚拟构造子(Virtual Constructor)模式;
  • 抽象工厂(Abstract Factory)模式,又称工具箱(Kit或Tookit)模式。

1). 简单工厂模式

比如说,你有一个描述你的后花园的系统,在你的后花园里有各种的花,但还没有水果。你现在要往你的系统里引进一些新的类,用来描述下列的水果:

葡萄 Grapes 草莓Strawberry 苹果Apple

花和水果最大的不同,就是水果最终是可以采摘食用的。那么,很自然的作法就是建立一个各种水果都适用的接口,这样一来这些水果类作为相似的数据类型就可以和你的系统的其余部分,如各种的花有所不同,易于区分。

 

接口FruitIF的源代码。这个接口确定了水果类必备的方法:种植plant(). 生长grow(),以及收获harvest()。

java 代码
  1. package com.test.simplefactory;
  2. public interface FruitIF {
  3. void grow();
  4. void harvest();
  5. void plant();
  6. String color = null ;
  7. String name = null ;
  8. }

类Apple的源代友。苹果是多年生木本植物,因此具备树龄treeAge性质。

java 代码

  1. package com.test.simplefactory;
  2. public class Apple implements FruitIF {
  3. public void grow() {
  4. log("Apple is growing..." );
  5. }
  6. public void harvest() {
  7. log("Apple has heen harvested." );
  8. }
  9. public void plant() {
  10. log("Apple has been planted." );
  11. }
  12. public static void log(String msg) {
  13. System.out.println(msg);
  14. }
  15. public int getTreeAge() {
  16. return treeAge;
  17. }
  18. public void setTreeAge( int treeAge) {
  19. this .treeAge = treeAge;
  20. }
  21. private int treeAge;
  22. }

类Grape的源代码。葡萄分为有籽与无籽两种,因此具有seedful性质。

java 代码

  1. package com.test.simplefactory;
  2. public class Grape implements FruitIF {
  3. public void grow() {
  4. log("Grape is growing..." );
  5. }
  6. public void harvest() {
  7. log("Grape has heen harvested." );
  8. }
  9. public void plant() {
  10. log("Grape has been planted." );
  11. }
  12. public static void log(String msg) {
  13. System.out.println(msg);
  14. }
  15. public boolean getSeedful() {
  16. return seedful;
  17. }
  18. public void setSeedful( boolean seedful) {
  19. this .seedful = seedful;
  20. }
  21. private boolean seedful;
  22. }

类Strawberry的源代码。

java 代码

  1. package com.test.simplefactory;
  2. public class Strawberry implements FruitIF {
  3. public void grow() {
  4. log("Strawberry is growing..." );
  5. }
  6. public void harvest() {
  7. log("Strawberry has heen harvested." );
  8. }
  9. public void plant() {
  10. log("Strawberry has been planted." );
  11. }
  12. public static void log(String msg) {
  13. System.out.println(msg);
  14. }
  15. }

你作为小花果园的主人兼园丁,也是系统的一部分,自然要由一个合适的类来代表,这个类就是FruitGardener类。这个类的结构请见下面的UML类图。


FruitGardener类会根据要求,创立出不同的水果类,比如苹果APPle,葡萄Grape或草莓Strawberry的实例。而如果接到不合法的要求,FruitGardener类会给出例外BadFruitException。

FruitGardener类的源代码

java 代码

  1. package com.test.simplefactory;
  2. public class FruitGardener {
  3. public FruitIF factory(String which) throws BadFruitException {
  4. if (which.equalsIgnoreCase( "apple" )) {
  5. return new Apple();
  6. } else if (which.equalsIgnoreCase( "strawberry" )) {
  7. return new Strawberry();
  8. } else if (which.equalsIgnoreCase( "grape" )) {
  9. return new Grape();
  10. } else {
  11. throw new BadFruitException( "Bad Fruit request" );
  12. }
  13. }
  14. }

BadFruitException类的源代码

java 代码

  1. package com.test.simplefactory;
  2. public class BadFruitException extends Exception {
  3. public BadFruitException(String msg) {
  4. super (msg);
  5. }
  6. }

在使用时,只须呼叫FruitGardener的factory()方法即可

java 代码

  1. try {
  2. FruitGardener gardener = new FruitGardener();
  3. gardener.factory("grape" );
  4. gardener.factory("apple" );
  5. gardener.factory("strawberry" );
  6. ...}catch (BadFruitException e) {
  7. ...
  8. }

就这样你的小果园一定会有百果丰收啦!

简单工厂模式的定义 由一个工厂类根据参数来决定创立出那一种产品类的实例。下面的UML类图就精确定义了简单工厂模式的结构。

从上图可以看出, 客户只要面对Factory,客户依赖于产品介面,产品的具体实作是可以与客户隔开的,它们也是可以抽换的。

2). 工厂方法(Factory Method)模式

遇到下面情况时,使用工厂方法:

  • 当一个类不知道它所必须创建的对象的类的时候
  • 当一个类希望由它的子类来指定它所创建的对象的时候
  • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信 息局部化的时候

工厂方法(FactoryMethod)模式是类的创建模式,其用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。

在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不接触哪一个产品类被实例化这种细节。这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。

在Factory Method模式中,工厂类与产品类往往具有平行的等级结构,它们之间一一对应。

2.1>. 工厂方法模式角色与结构

  • 抽象工厂(Creator)角色: 是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
  • 具体工厂(Concrete Creator)角色: 这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。在上图中有两个这样的角色:BulbCreator与TubeCreator。
  • 抽象产品(Product)角色: 工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。
  • 具体产品(Concrete Product)角色: 这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

工厂方法的活动序列图


活动过程包括:
客户端创建BulbCreator对象,客户端持有此对象的类型是Creator,而实际类型是BulbCreator。然后客户端调用 BulbCreator的factory方法,之后BulbCreator调用BulbLight的构造函数创造出产品BulbLight对象。

2.2>. 一个简单的实例

java 代码

  1. // 产品 Plant接口
  2. public interface Plant { }
  3. //具体产品PlantA,PlantB
  4. public class PlantA implements Plant {
  5.  public PlantA () {
  6.   System.out.println("create PlantA !" );
  7.  }
  8.  public void doSomething() {
  9.   System.out.println(" PlantA do something ..." );
  10.  }
  11. }
  12. public class PlantB implements Plant {
  13.  public PlantB () {
  14.   System.out.println("create PlantB !" );
  15.  }
  16.  public void doSomething() {
  17.   System.out.println(" PlantB do something ..." );
  18.  }
  19. }
  20. // 产品 Fruit接口
  21. public interface Fruit { }
  22. //具体产品FruitA,FruitB
  23. public class FruitA implements Fruit {
  24.  public FruitA() {
  25.   System.out.println("create FruitA !" );
  26.  }
  27.  public void doSomething() {
  28.   System.out.println(" FruitA do something ..." );
  29.  }
  30. }
  31. public class FruitB implements Fruit {
  32.  public FruitB() {
  33.   System.out.println("create FruitB !" );
  34.  }
  35.  public void doSomething() {
  36.   System.out.println(" FruitB do something ..." );
  37.  }
  38. }
  39. // 抽象工厂方法
  40. public interface AbstractFactory {
  41.  public Plant createPlant();
  42.  public Fruit createFruit() ;
  43. }
  44. //具体工厂方法
  45. public class FactoryA implements AbstractFactory {
  46.  public Plant createPlant() {
  47.   return new PlantA();
  48.  }
  49.  public Fruit createFruit() {
  50.   return new FruitA();
  51.  }
  52. }
  53. public class FactoryB implements AbstractFactory {
  54.  public Plant createPlant() {
  55.   return new PlantB();
  56.  }
  57.  public Fruit createFruit() {
  58.   return new FruitB();
  59.  }
  60. }


2.3>. 工厂方法模式与简单工厂模式

工厂方法模式与简单工厂模式再结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。

工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。

当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了"开放-封闭"原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。

工厂方法模式退化后可以演变成简单工厂模式。

2.4>. 工厂方法模式演化

使用接口或抽象类
抽象工厂角色和抽象场频角色都可以选择由接口或抽象类实现。

使用多个工厂方法
抽象工厂角色可以规定出多于一个的工厂方法,从而使具体工厂角色实现这些不同的工厂方法,这些方法可以提供不同的商业逻辑,以满足提供不同的产品对象的任务。

产品的循环使用
工厂方法总是调用产品类的构造函数以创建一个新的产品实例,然后将这个实例提供给客户端。而在实际情形中,工厂方法所做的事情可以相当复杂。

一个常见的复杂逻辑就是循环使用产品对象。工厂对象将已经创建过的产品登记到一个聚集中,然后根据客户所请求的产品状态,向聚集查询。如果有满足要求的产品对象,就直接将产品返回客户端;如果聚集中没有这样的产品对象,那么就创建一个新的满足要求的产品对象,然后将这个对象登记到聚集中,再返还给客户端。"享元模式(Flyweight Pattern)"就是这样一个模式。


多态性的丧失和模式的退化
一个工厂方法模式的实现依赖于工厂角色和产品角色的多态性。在有些情况下,这个模式可以出现退化。

 

分享到:
评论

相关推荐

    人人都懂设计模式 人人都懂设计模式

    人人都懂设计模式 设计模式是软件开发中的一种解决方案,它提供了一种通用的设计思想和方法论,可以帮助开发者更好地设计和实现软件系统。设计模式可以分为三大类:创建型模式、结构型模式和行为型模式。 在本书中...

    二十三种设计模式【PDF版】

    主要是介绍各种格式流行的软件设计模式,对于程序员的进一步提升起推进作用,有时间可以随便翻翻~~ 23种设计模式汇集 如果你还不了解设计模式是什么的话? 那就先看设计模式引言 ! 学习 GoF 设计模式的重要性 ...

    GOF设计模式中英文+设计模式精解中英文

    GOF(Gang of Four)设计模式,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位专家在他们的著作《设计模式:可复用面向对象软件的基础》中提出,被誉为设计模式的经典之作。本资源包含了GOF设计...

    23种设计模式详解PDF

    设计模式 的分类 总体来说设计模式分为三大类: 创建型模式(5): 工厂方法模式 、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式(7): 适配器模式、装饰器模式、代理模式、外观模式、桥接模式、...

    Head First 设计模式 +Java设计模式(第2版)

    《Head First 设计模式》与《Java设计模式(第2版)》是两本非常重要的IT书籍,专注于软件开发中的设计模式。设计模式是解决软件设计中常见问题的经验总结,它们提供了一种标准的方法来处理特定场景下的问题,使得代码...

    C#设计模式.PDF

    根据提供的文档概览,我们可以对每个章节所涉及的设计模式进行详细的阐述和解释。下面将针对文档中提及的设计模式逐一展开,以便更好地理解这些模式的概念、结构、应用场景以及优缺点。 ### 1. 面向对象程序设计...

    设计模式之蝉

    在计算机科学领域,设计模式是软件工程中用于解决特定问题的一般性方案,它们是经过实践检验的最佳实践。这些模式被广泛应用于面向对象软件设计中,能够提高代码的可重用性、灵活性和可维护性。设计模式通常被划分为...

    设计模式(包含5个设计模式)含源代码报告.rar

    这个压缩包文件"设计模式(包含5个设计模式)含源代码报告.rar"显然是一份宝贵的资源,它涵盖了五个核心的设计模式,并附带了详细的类图、源代码以及文档报告,这对于学习和理解设计模式至关重要。 首先,我们要探讨...

    python设计模式第2版.pdf

    设计模式是构建大型软件系统zui强大的方法之一,优化软件架构和设计已经逐渐成为软件开发和维护过程中的一个重要课题。 Python设计模式(第2版)通过11章内容,全面揭示有关设计模式的内容,并结合Python语言进行示例...

    基于Java的设计模式大作业绘图系统【六种设计模式+文档】.zip

    本系统基于六种设计模式,运用到的设计模式有备忘录模式,简单工厂模式,迭代器模式,状态模式,模版方法模式,单例模式。 具体实现过程、UML类图以及实现效果详见如下项目说明地址: ... 该系统为绘图系统,该系统通过...

    新版设计模式手册 - C#设计模式(第二版)

    《新版设计模式手册 - C#设计模式(第二版)》是一部深入探讨C#编程中设计模式的权威指南,尤其适合已经有一定C#基础并希望提升软件设计能力的开发者阅读。设计模式是解决软件开发中常见问题的经验总结,是软件工程的...

    软件设计模式(java版)习题答案.pdf

    软件设计模式(Java版)习题答案 本资源为软件设计模式(Java版)习题答案,由程细柱编著,人民邮电出版社出版。该资源涵盖了软件设计模式的基础知识,包括软件设计模式的概述、UML中的类图、面向对象的设计原则、...

    设计模式精解- GoF 23种设计模式解析附C++实现源码

    设计模式精解- GoF 23种设计模式解析附C++实现源码 懂了设计模式,你就懂了面向对象分析和设计(OOA/D)的精要。反之好像也可能成立。道可道,非常道。道不远人,设计模式亦然如此。 一直想把自己的学习经验以及在...

    Head First设计模式.pdf

    全书用两章篇幅对设计模式和GRASP作了基本介绍,3种设计模式的讲解:对于每一种模式,先给出定义,接着通过类比方式用一个现实世界中的例子说明模式的应用,然后分别以C#和Java代码例述模式的架构实现。最后一章给出...

    MongoDB应用设计模式

    资源名称:MongoDB应用设计模式内容简介:无论是在构建社交媒体网站,还是在开发一个仅在内部使用的企业应用程序,《MongoDB应用设计模式》展示了MongoDB需要解决的商业问题之间的连接。你将学到如何把MongoDB设计...

    设计模式那点事

    设计模式是软件工程中的一种重要概念,它代表了在特定情境下解决问题的可重用解决方案。《设计模式那点事》这本书的PPT为我们提供了一种深入理解和学习设计模式的途径。在这里,我们将深入探讨设计模式的核心概念、...

    尚硅谷设计模式源码笔记课件.zip

    本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,...

    设计模式之美——教你写出高质量代码

    设计模式是软件工程中的一种最佳实践,它是在特定上下文中解决常见问题的经验总结。"设计模式之美——教你写出高质量代码"这个主题旨在帮助开发者更好地理解和应用设计模式,从而提升代码的质量和可维护性。设计模式...

    设计模式:可复用面向对象软件的基础--详细书签版

     “[设计模式]在实用环境下特别有用,因为它分类描述了一组设计良好,表达清楚的面向对象软件设计模式。整个设计模式领域还很新,本书的四位作者也许已占据了这个领域造诣最深的专家中的半数,因而他们定义模式的方法...

    软件设计模式期末作业

    在软件开发领域,设计模式是经过时间和实践验证的解决方案模板,用于解决常见问题。本作业以“软件设计模式”为主题,特别关注了装饰模式、工厂模式和适配器模式的运用。这三种模式都是面向对象设计的核心部分,它们...

Global site tag (gtag.js) - Google Analytics