Java设计模式之java组合模式详解

目录
  • 引言
  • 组合模式介绍
  • 角色
  • 模式结构
  • 示例代码
  • 水果盘
  • 文件浏览
  • 更复杂的组合模式
    • 透明与安全
    • 透明组合模式
  • 安全组合模式
  • 组合模式总结
    • 优点
    • 缺点
  • 适用场景
  • 应用
    • XML文档解析
    • 文件
    • HashMap
  • Mybatis SqlNode中的组合模式
  • 参考文章
  • 总结

引言

树形结构不论在生活中或者是开发中都是一种非常常见的结构,一个容器对象(如文件夹)下可以存放多种不同的叶子对象或者容器对象,容器对象与叶子对象之间属性差别可能非常大。

由于容器对象和叶子对象在功能上的区别,在使用这些对象的代码中必须有区别地对待容器对象和叶子对象,而实际上大多数情况下我们希望一致地处理它们,因为对于这些对象的区别对待将会使得程序非常复杂。

组合模式为解决此类问题而诞生,它可以让叶子对象和容器对象的使用具有一致性。

组合模式介绍

组合多个对象形成树形结构以表示具有 “整体—部分” 关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为 “整体—部分”(Part-Whole) 模式,它是一种对象结构型模式。

由于在软件开发中存在大量的树形结构,因此组合模式是一种使用频率较高的结构型设计模式,

在XML解析、组织结构树处理、文件系统设计等领域,组合模式都得到了广泛应用。

角色

  • Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。
  • Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。
  • Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

组合模式的关键是定义了一个抽象构件类,它既可以代表叶子,又可以代表容器,而客户端针对该抽象构件类进行编程,无须知道它到底表示的是叶子还是容器,可以对其进行统一处理。同时容器对象与抽象构件类之间还建立一个聚合关联关系,在容器对象中既可以包含叶子,也可以包含容器,以此实现递归组合,形成一个树形结构。

模式结构

示例代码

典型的抽象构件角色代码:

 public abstract class Component
 {
     public abstract void add(Component c);
     public abstract void remove(Component c);
     public abstract Component getChild(int i);
     public abstract void operation();
 }

典型的容器构件角色代码:

 public class Leaf extends Component
 {
     public void add(Component c)
     { //异常处理或错误提示 }
     public void remove(Component c)
     { //异常处理或错误提示 }
     public Component getChild(int i)
     { //异常处理或错误提示 }
     public void operation()
     {
         //实现代码
     }
 }

水果盘

在水果盘(Plate)中有一些水果,如苹果(Apple)、香蕉(Banana)、梨子(Pear),当然大水果盘中还可以有小水果盘,现需要对盘中的水果进行遍历(吃),当然如果对一个水果盘执行“吃”方法,实际上就是吃其中的水果。使用组合模式模拟该场景 。

 //抽象构建
 public abstract class MyElement
 {
     public abstract void eat();
 }
 //容器构建
 import java.util.*;
 public class Plate extends MyElement
 {
     private ArrayList list=new ArrayList();
     public void add(MyElement element)
     {
      list.add(element);
     }
     public void delete(MyElement element)
     {
         list.remove(element);
     }
     public void eat()
     {
         for(Object object:list)
         {
             ((MyElement)object).eat();    //递归
         }
     }
 }
 //叶子构建
 public class Apple extends MyElement
 {
     public void eat()
     {
         System.out.println("吃苹果!");
     }
 }
 //叶子构建
 public class Banana extends MyElement
 {
     public void eat()
     {
         System.out.println("吃香蕉!");
     }
 }
 //叶子构建
 public class Pear extends MyElement
 {
     public void eat()
     {
        System.out.println("吃梨子!");
     }
 }
 //客户端
 public class Client
 {
     public static void main(String a[])
     {
         MyElement obj1,obj2,obj3,obj4,obj5;
         Plate plate1,plate2,plate3;
         obj1=new Apple();
         obj2=new Pear();
         plate1=new Plate();
         plate1.add(obj1);
         plate1.add(obj2);
         obj3=new Banana();
         obj4=new Banana();
         plate2=new Plate();
         plate2.add(obj3);
         plate2.add(obj4);
         obj5=new Apple();
         plate3=new Plate();
         plate3.add(plate1);
        plate3.add(plate2);
         plate3.add(obj5);
         plate3.eat();
     }
 }

文件浏览

我们来实现一个简单的目录树,有文件夹和文件两种类型,首先需要一个抽象构件类,声明了文件夹类和文件类需要的方法

public abstract class Component {
    public String getName() {
        throw new UnsupportedOperationException("不支持获取名称操作");
    }
    public void add(Component component) {
        throw new UnsupportedOperationException("不支持添加操作");
    }
    public void remove(Component component) {
        throw new UnsupportedOperationException("不支持删除操作");
    }
    public void print() {
        throw new UnsupportedOperationException("不支持打印操作");
    }
    public String getContent() {
        throw new UnsupportedOperationException("不支持获取内容操作");
    }
}

实现一个文件夹类 Folder,继承 Component,定义一个 List<Component> 类型的componentList属性,用来存储该文件夹下的文件和子文件夹,并实现 getName、add、remove、print等方法

public class Folder extends Component {
    private String name;
    private List<Component> componentList = new ArrayList<Component>();
      public Integer level;
    public Folder(String name) {
        this.name = name;
    }
    @Override
    public String getName() {
        return this.name;
    }
    @Override
    public void add(Component component) {
        this.componentList.add(component);
    }
    @Override
    public void remove(Component component) {
        this.componentList.remove(component);
    }
     @Override
    public void print() {
        System.out.println(this.getName());
        if (this.level == null) {
            this.level = 1;
        }
        String prefix = "";
        for (int i = 0; i < this.level; i++) {
            prefix += "\t- ";
        }
        for (Component component : this.componentList) {
            if (component instanceof Folder){
                ((Folder)component).level = this.level + 1;
            }
            System.out.print(prefix);
            component.print();
        }
        this.level = null;
    }
}

文件类 File,继承Component父类,实现 getName、print、getContent等方法

public class File extends Component {
    private String name;
    private String content;
    public File(String name, String content) {
        this.name = name;
        this.content = content;
    }
    @Override
    public String getName() {
        return this.name;
    }
    @Override
    public void print() {
        System.out.println(this.getName());
    }
    @Override
    public String getContent() {
        return this.content;
    }
}

我们来测试一下

public class Test {
    public static void main(String[] args) {
        Folder DSFolder = new Folder("设计模式资料");
        File note1 = new File("组合模式笔记.md", "组合模式组合多个对象形成树形结构以表示具有 \"整体—部分\" 关系的层次结构");
        File note2 = new File("工厂方法模式.md", "工厂方法模式定义一个用于创建对象的接口,让子类决定将哪一个类实例化。");
        DSFolder.add(note1);
        DSFolder.add(note2);
        Folder codeFolder = new Folder("样例代码");
        File readme = new File("README.md", "# 设计模式示例代码项目");
        Folder srcFolder = new Folder("src");
        File code1 = new File("组合模式示例.java", "这是组合模式的示例代码");
        srcFolder.add(code1);
        codeFolder.add(readme);
        codeFolder.add(srcFolder);
        DSFolder.add(codeFolder);
        DSFolder.print();
    }
}

输出结果

设计模式资料
- 组合模式笔记.md
- 工厂方法模式.md
- 样例代码
- - README.md
- - src
- - - 组合模式示例.java

在这里父类 Component 是一个抽象构件类,Folder 类是一个容器构件类,File 是一个叶子构件类,Folder 和 File 继承了 ComponentFolder Component 又是聚合关系

更复杂的组合模式

透明与安全

在使用组合模式时,根据抽象构件类的定义形式,我们可将组合模式分为透明组合模式和安全组合模式两种形式。

透明组合模式

透明组合模式中,抽象构件角色中声明了所有用于管理成员对象的方法,譬如在示例中 Component 声明了 add、remove 方法,这样做的好处是确保所有的构件类都有相同的接口。透明组合模式也是组合模式的标准形式。

透明组合模式的缺点是不够安全,因为叶子对象和容器对象在本质上是有区别的,叶子对象不可能有下一个层次的对象,即不可能包含成员对象,因此为其提供 add()、remove() 等方法是没有意义的,这在编译阶段不会出错,但在运行阶段如果调用这些方法可能会出错(如果没有提供相应的错误处理代码)

安全组合模式

在安全组合模式中,在抽象构件角色中没有声明任何用于管理成员对象的方法,而是在容器构件 Composite 类中声明并实现这些方法

安全组合模式的缺点是不够透明,因为叶子构件和容器构件具有不同的方法,且容器构件中那些用于管理成员对象的方法没有在抽象构件类中定义,因此客户端不能完全针对抽象编程,必须有区别地对待叶子构件和容器构件。

在实际应用中 java.awt 和 swing 中的组合模式即为安全组合模式。

组合模式总结

优点

  • 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。
  • 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。
  • 在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合“开闭原则”。
  • 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。

缺点

  • 使得设计更加复杂,客户端需要花更多时间理清类之间的层次关系。
  • 在增加新构件时很难对容器中的构件类型进行限制。

适用场景

  • 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。
  • 在一个使用面向对象语言开发的系统中需要处理一个树形结构。
  • 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。

应用

XML文档解析

 1 <?xml version="1.0"?>
 2   <books>
 3     <book>
 4         <author>Carson</author>
 5         <price format="dollar">31.95</price>
 6         <pubdate>05/01/2001</pubdate>
 7     </book>
 8     <pubinfo>
 9         <publisher>MSPress</publisher>
10         <state>WA</state>
11     </pubinfo>
12   </books>

文件

操作系统中的目录结构是一个树形结构,因此在对文件和文件夹进行操作时可以应用组合模式,例如杀毒软件在查毒或杀毒时,既可以针对一个具体文件,也可以针对一个目录。如果是对目录查毒或杀毒,将递归处理目录中的每一个子目录和文件。

HashMap

HashMap 提供 putAll 的方法,可以将另一个 Map 对象放入自己的存储空间中,如果有相同的 key 值则会覆盖之前的 key 值所对应的 value 值

public class Test {
    public static void main(String[] args) {
        Map<String, Integer> map1 = new HashMap<String, Integer>();
        map1.put("aa", 1);
        map1.put("bb", 2);
        map1.put("cc", 3);
        System.out.println("map1: " + map1);
        Map<String, Integer> map2 = new LinkedMap();
        map2.put("cc", 4);
        map2.put("dd", 5);
        System.out.println("map2: " + map2);
        map1.putAll(map2);
        System.out.println("map1.putAll(map2): " + map1);
    }
}

输出结果

map1: {aa=1, bb=2, cc=3}
map2: {cc=4, dd=5}
map1.putAll(map2): {aa=1, bb=2, cc=4, dd=5}

查看 putAll 源码

public void putAll(Map<? extends K, ? extends V> m) {
        putMapEntries(m, true);
    }

putAll 接收的参数为父类 Map 类型,所以 HashMap 是一个容器类,Map 的子类为叶子类,当然如果 Map 的其他子类也实现了 putAll 方法,那么它们都既是容器类,又都是叶子类

Mybatis SqlNode中的组合模式

MyBatis 的强大特性之一便是它的动态SQL,其通过 if, choose, when, otherwise, trim, where, set, foreach 标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率。

<select id="findActiveBlogLike"  resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE'
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

Mybatis在处理动态SQL节点时,应用到了组合设计模式,Mybatis会将映射配置文件中定义的动态SQL节点、文本节点等解析成对应的 SqlNode 实现,并形成树形结构。

SQLNode 的类图如下所示:

需要先了解 DynamicContext 类的作用:主要用于记录解析动态SQL语句之后产生的SQL语句片段,可以认为它是一个用于记录动态SQL语句解析结果的容器

抽象构件为 SqlNode 接口,源码如下:

public interface SqlNode {
  boolean apply(DynamicContext context);
}

apply 是 SQLNode 接口中定义的唯一方法,该方法会根据用户传入的实参,参数解析该SQLNode所记录的动态SQL节点,并调用 DynamicContext.appendSql() 方法将解析后的SQL片段追加到 DynamicContext.sqlBuilder 中保存,当SQL节点下所有的 SqlNode 完成解析后,我们就可以从 DynamicContext 中获取一条动态生产的、完整的SQL语句

然后来看 MixedSqlNode 类的源码:

public class MixedSqlNode implements SqlNode {
  private List<SqlNode> contents;
  public MixedSqlNode(List<SqlNode> contents) {
    this.contents = contents;
  }
  @Override
  public boolean apply(DynamicContext context) {
    for (SqlNode sqlNode : contents) {
      sqlNode.apply(context);
    }
    return true;
  }
}

MixedSqlNode 维护了一个 List< SqlNode > 类型的列表,用于存储 SqlNode 对象,apply 方法通过 for循环 遍历 contents 并调用其中对象的 apply 方法,这里跟我们的示例中的 Folder 类中的 print 方法非常类似,很明显 MixedSqlNode 扮演了容器构件角色

对于其他SqlNode子类的功能,稍微概括如下:

  • TextSqlNode:表示包含 ${} 占位符的动态SQL节点,其 apply 方法会使用 GenericTokenParser解析 ${} 占位符,并直接替换成用户给定的实际参数值
  • IfSqlNode:对应的是动态SQL节点 < If > 节点,其 apply 方法首先通过ExpressionEvaluator.evaluateBoolean() 方法检测其 test 表达式是否为 true,然后根据test 表达式的结果,决定是否执行其子节点的 apply() 方法
  • TrimSqlNode :会根据子节点的解析结果,添加或删除相应的前缀或后缀。
  • WhereSqlNode 和 SetSqlNode 都继承了 TrimSqlNode
  • ForeachSqlNode:对应 < for each > 标签,对集合进行迭代
  • 动态SQL中的 < choose >、< when >、< otherwise > 分别解析成ChooseSqlNode、IfSqlNode、MixedSqlNode

综上,SqlNode 接口有多个实现类,每个实现类对应一个动态SQL节点,其中 SqlNode 扮演抽象构件角色,MixedSqlNode 扮演容器构件角色,其它一般是叶子构件角色

参考文章

组合模式

设计模式 | 组合模式及典型应用

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Java设计模式之装饰者模式详解

    目录 具体代码: Person: Student: Doctor: DecoratePerson: ShoeDecorate: DressDecorate: 总结 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 以一个Person对象为例.Person作为一个接口,Student(学生)和Doctor(医生)为Person接口的两个具体类,DecoratorPerson为Pers

  • Java设计模式之java外观模式详解

    目录 模式动机 模式定义 模式结构 角色 模式分析 典型的外观角色代码 外观模式实例与解析 实例一:电源总开关 实例二:文件加密 模式优缺点 优点 缺点 模式适用环境 源码分析外观模式的典型应用 (1) 外观模式应用于JDBC数据库操作 (2) Session外观模式是外观模式在Java EE框架中的应用 模式扩展 一个系统有多个外观类 不要试图通过外观类为子系统增加新行为 外观模式与迪米特法则 抽象外观类的引入 总结 参考文章 总结 模式动机 引入外观角色之后,用户只需要直接与外观角色交互,用

  • Java 代码实例解析设计模式之监听者模式

    代码展示 Main:测试类 ObServer:每个被监听的对象实现该接口,重写该方法,完成自己的业务 public interface ObServer { /** * 当某一个被监控的对象发生变化时 * 所有实现该方法处理方法 */ void exceptionHandler(); } Subject:监听者容器 public interface Subject { /** * 添加被观察对象 */ void add(ObServer obServer); /** * 通知所有被观察者完成自己

  • Java设计模式之java责任链模式详解

    目录 概述 结构 总结 在本讲,我们来学习一下行为型模式里面的第四个设计模式,即责任链模式. 概述 在学习责任链模式之前,我们先来看一下下面这段描述. 在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同.例如,公司员工请假,可批假的领导有部门负责人.副总经理.总经理等,但是每个领导能批准的天数不同,员工必须根据自己要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名.电话和地址等信息,这增加了员工请假的难度.因为领导有很多,员工到底找哪位

  • java设计模式理解依赖于抽象不依赖具体的分析

    在面向对象设计原则中,要求"要依赖于抽象,不要依赖于具体", 这句话有很多人搞不懂.在这里谈谈我自己的理解.首先看看以下代码 class A{ public void swim(){ Dog dog = new Dog(); dog.move(); } } swim方法中定义了一个Dog的对象,那么无论哪个对象调用这个方法时,一定是"狗爬",swim和Dog的对象是紧耦合的关系,我们想换成鸭子是不可能. 假如代码这样换一下,我们定义一个动物的接口,接口定义一个mov

  • Java设计模式之单例模式深入探索

    目录 什么是设计模式? 单例模式是什么? 单例模式设计的原则是什么? Java实现单例模式的5种方式? 懒汉 饿汉 静态内部类 双重校验锁DCL(Double Check Lock) 枚举(num) 小结 ❤️‍您好,我是贾斯汀,今天来聊一聊单例模式!❤️‍ 什么是设计模式? 百科: 设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 设计模式是软件行业的通用的设计标准,在Java同样通用,主要有23种设计模式如下: 有的小伙伴可能会问,这么多,学得完吗? 答:不好意思

  • Java设计模式之java桥接模式详解

    目录 一.什么是桥接模式: 二.UML结构图: 三.代码实现: 四.JDBC源码解析-桥接模式: 1.源码分析: 2.源码类图: 3.对 JDBC 的观点: 参考博客: 总结 一.什么是桥接模式: 桥接,顾名思义,就是用来连接两个部分,使得两个部分可以互相通讯,桥接模式的作用就是为被分离的抽象部分和实现部分搭桥.在现实生活中一个物品在搭配不同的配件时会产生不同的动作和结果,例如一辆赛车搭配的是硬胎或者是软胎就能够在干燥的马路上行驶,而如果要在下雨的路面行驶,就需要搭配雨胎了,这种根据行驶的路面不

  • JAVA设计模式零基础解析之单例模式的八种方式

    目录 单例模式简介: 单例模式优点: 应用场景: 单例设计模式的八种方式: 1.饿汉式(静态常量) 2.饿汉式(静态代码块) 3.懒汉式(线程不安全) 4.懒汉式(线程安全,同步方法) 5.懒汉式(线程安全,同步代码块) 6.双重检查(推荐使用) 7.静态内部类(推荐使用) 8.枚举(推荐使用) 单例模式在JDK应用的源码分析 单例模式注意事项和细节说明 单例模式简介: 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了

  • Java设计模式之职责链模式详解

    目录 前言 一.职责链模式的定义与特点 二.职责链模式的结构 三.职责链模式案例 前言 本文简单介绍了设计模式的一种--职责链模式  一.职责链模式的定义与特点 定义: 为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链:当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止. 比如我们的审批制度,低等级的审批不了的,交给上一级审批,依次类推,直到审批结束. 在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处

  • Java设计模式中责任链模式详解

    目录 1.责任链设计模式的定义 2.责任链设计模式的优点与不足 3.责任链设计模式的实现思路 4.责任链设计模式应用实例 5.责任链设计模式应用场景 编程是一门艺术,大批量的改动显然是非常丑陋的做法,用心的琢磨写的代码让它变的更美观. 在现实生活中,一个事件需要经过多个对象处理是很常见的场景.例如,采购审批流程.请假流程等.公司员工请假,可批假的领导有部门负责人.副总经理.总经理等,但每个领导能批准的天数不同,员工必须根据需要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名.电话

  • Java设计模式之抽象工厂模式详解

    一.什么是抽象工厂模式 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类,这称之为抽象工厂模式(Abstract Factory).我们并不关心零件的具体实现,而是只关心接口(API).我们仅使用该接口(API)将零件组装称为产品. 二.示例程序   1.抽象的零件:Item类 package com.as.module.abstractfactory; /** * 抽象的零件 * @author Andy * @date 2021/4/29 23:16 */ public

  • Java设计模式中的外观模式详解

    目录 模式介绍 UML类图 外观模式案例: 外观模式的注意事项和细节 模式介绍 外观模式(Facade) ,也叫“过程模式:外观模式为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式通过定义一个一致的接口,用以屏蔽内部子系统的细节,使得调用端只需跟这个接口发生调用,而无需关心这个子系统的内部细节. UML类图 类图解析: Facade:为调用端提供统一的调用接口,外观类知道哪些子系统负责处理请求,从而将调用端的请求代理给适当子系统对象

  • Java设计模式中的门面模式详解

    目录 门面模式 概述 应用场景 目的 优缺点 主要角色 门面模式的基本使用 创建子系统角色 创建外观角色 客户端调用 门面模式实现商城下单 库存系统 支付系统 物流系统 入口系统 客户端调用 门面模式 概述 门面模式(Facade Pattern)又叫外观模式,属于结构性模式. 它提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口.使得子系统更容易使用. 客户端不需要知道系统内部的复杂联系,只需定义系统的入口.即在客户端和复杂系统之间再加一层,这一层

  • Java设计模式之工厂方法模式详解

    目录 1.工厂方法是什么 2.如何实现 3.代码实现 4.工厂方法模式的优点 5.拓展 1.工厂方法是什么 众所周知,工厂是生产产品的,并且产品供消费者使用.消费者不必关心产品的生产过程,只需要关心用哪种产品就行. 在Java世界中,工厂方法模式和现实功能类似.工厂即一个工厂类,提供获得对象(产品)的方法(工厂方法).其他类(消费者)需要用到某个对象时,只需调用工厂方法就行,不必new这个对象. 2.如何实现 1)创建产品的抽象类或接口---抽象产品 2)创建具体产品的类---具体产品 3)创建

  • Java设计模式之静态工厂模式详解

    本文实例讲述了Java设计模式之静态工厂模式.分享给大家供大家参考,具体如下: 静态工厂模式(static factory)也叫简单工厂模式. 涉及到3个角色:工厂类角色,抽象产品类角色和具体产品类角色. 抽象产品类可以使用接口或者父类来描述产品对象的行为特征. 具体产品类就是某一具体的对象. 静态工厂类有一个静态的方法,含有判断逻辑,决定要创建哪一种具体的产品对象. 其设计模式如下: 抽象产品类  IProduct package org.test.design.sf; public inte

  • JAVA设计模式之责任链模式详解

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任. 从击鼓传花谈起 击鼓传花是一种热闹而又紧张的饮酒游戏.在酒宴上宾客依次坐定位置,由一人击鼓,击鼓

  • JAVA设计模式之调停者模式详解

    在阎宏博士的<JAVA与模式>一书中开头是这样描述调停者(Mediator)模式的: 调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从而使它们可以较松散地耦合.当这些对象中的某些对象之间的相互作用发生改变时,不会立即影响到其他的一些对象之间的相互作用.从而保证这些相互作用可以彼此独立地变化. 为什么需要调停者 如下图所示,这个示意图中有大量的对象,这些对象既会影响别的对象,又会被别的对象所影响,因此常常叫做同事(Colleague)对象.这

随机推荐