`
chxiaowu
  • 浏览: 241869 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Head First 设计模式学习笔记(十一)组合模式

 
阅读更多

 

http://lavasoft.blog.51cto.com/62575/90824  转载

 

从原理图可见,File、Folder都可以同等看待苇IFile,为对象管理提供了极大的便利。
当然,树的概念不单单是文件文件夹的层次概念,只是因为这个很形象,实际中还有很多树的概念,比如组织机构,分类层次等等,都是逻辑上的概念,不管是物理上的还是逻辑上的,在Java里都是一样处理的。

 

 

二、实例
下面以一个逻辑树为例子,以上面的原理图为蓝本,看看如何实现并如何使用这个树,这个结构很简单,但是如何去使用树,遍历树、为我所用还是有一定难度的。
 
这里主要用到树的递归遍历,如何递归、如何控制遍历层级,如何将逻辑关系转换为(类似)物理关系,这些都是有相当难度的。
 
1、
/** 
* 抽象文件角色 
*/ 
public interface IFile { 

    //返回自己的实例 
    IFile getComposite(); 

    //某个商业方法 
    void sampleOperation(); 

    //获取深度 
    int getDeep(); 

    //设置深度 
    void setDeep(int x); 

}
 
2、
/** 
* 文件夹角色 
*/ 
public class Folder implements IFile { 

    private String name;    //文件名字 
   private int deep;       //层级深度,根深度为0 
    private Vector<IFile> componentVector = new Vector<IFile>(); 

    public Folder(String name) { 
        this.name = name; 
    } 

    //返回自己的实例 
    public IFile getComposite() { 
        return this; 
    } 

    //某个商业方法 
    public void sampleOperation() { 
        System.out.println("执行了某个商业方法!"); 
    } 

    //增加一个文件或文件夹 
    public void add(IFile IFile) { 
        componentVector.addElement(IFile); 
        IFile.setDeep(this.deep + 1); 

    } 

    //删除一个文件或文件夹 
    public void remove(IFile IFile) { 
        componentVector.removeElement(IFile); 
    } 

    //返回直接子文件(夹)集合 
    public Vector getAllComponent() { 
        return componentVector; 
    } 

    public String getName() { 
        return name; 
    } 

    public void setName(String name) { 
        this.name = name; 
    } 

    public int getDeep() { 
        return deep; 
    } 

    public void setDeep(int deep) { 
        this.deep = deep; 
    } 
}
 
3、
/** 
* 文件 
*/ 
public class File implements IFile { 
    private String name;    //文件名字 
    private int deep;       //层级深度 

    public File(String name) { 
        this.name = name; 
    } 

    //返回自己的实例 
    public IFile getComposite() { 
        return this; 
    } 

    //某个商业方法 
    public void sampleOperation() { 
        System.out.println("执行了某个商业方法!"); 
    } 

    public String getName() { 
        return name; 
    } 

    public void setName(String name) { 
        this.name = name; 
    } 

    public int getDeep() { 
        return deep; 
    } 

    public void setDeep(int deep) { 
        this.deep = deep; 
    } 
}
 
4、
/** 
* 遍历树的一个测试 
*/ 
public class Client { 
    public static String indentChar = "\t";       //文件层次缩进字符 

    public static void main(String args[]) { 
        new Client().test(); 
    } 

    /** 
     * 客户端测试方法 
     */ 
    public void test() { 
        //根下文件及文件夹 
        Folder root = new Folder("树根"); 

        Folder b1_1 = new Folder("1_枝1"); 
        Folder b1_2 = new Folder("1_枝2"); 
        Folder b1_3 = new Folder("1_枝3"); 
        File l1_1 = new File("1_叶1"); 
        File l1_2 = new File("1_叶2"); 
        File l1_3 = new File("1_叶3"); 

        //b1_2下的文件及文件夹 
        Folder b2_1 = new Folder("2_枝1"); 
        Folder b2_2 = new Folder("2_枝2"); 
        File l2_1 = new File("2_叶1"); 

        //缔造树的层次关系(简单测试,没有重复添加的控制) 
        root.add(b1_1); 
        root.add(b1_2); 
        root.add(l1_1); 
        root.add(l1_2); 

        b1_2.add(b2_1); 
        b1_2.add(b2_2); 
        b1_2.add(l2_1); 
        root.add(l1_3); 
        root.add(b1_3); 
        //控制台打印树的层次 
        outTree(root); 
    } 

    public void outTree(Folder folder) { 
        System.out.println(folder.getName()); 
        iterateTree(folder); 
    } 

    /** 
     * 遍历文件夹,输入文件树 
     * 
     * @param folder 
     */ 
    public void iterateTree(Folder folder) { 
        Vector<IFile> clist = folder.getAllComponent(); 
        //todo:遍历之前可以对clist进行排序,这些都不是重点 
        for (Iterator<IFile> it = clist.iterator(); it.hasNext();) { 
            IFile em = it.next(); 
            if (em instanceof Folder) { 
                Folder cm = (Folder) em; 
                System.out.println(getIndents(em.getDeep()) + cm.getName()); 
                iterateTree(cm); 
            } else { 
                System.out.println(getIndents(em.getDeep()) + ((File) em).getName()); 
            } 
        } 
    } 

    /** 
     * 文件层次缩进字符串 
     * 
       * @param x 缩进字符个数 
     * @return 缩进字符串 
     */ 
    public static String getIndents(int x) { 
        StringBuilder sb = new StringBuilder(); 
        for (int i = 0; i < x; i++) { 
            sb.append(indentChar); 
        } 
        return sb.toString(); 
    } 
}
 5、
上面所用的合成模式是安全合成模式,所谓的安全是指File与Folder中的方法不同。Folder有对聚集对象的管理,File没有。
 
合成模式在程序设计中有着广泛的应用,比如Dom4j、资源管理器、Java GUI容器层次图等等都是合成模式应用的典范。
分享到:
评论

相关推荐

    HeadFirst设计模式学习笔记

    《HeadFirst设计模式学习笔记》是一份详尽的资料,旨在帮助读者深入理解并掌握设计模式这一编程领域的核心概念。设计模式是软件工程中的一种最佳实践,它在解决常见问题时提供了一种标准的解决方案,使得代码更易于...

    Head First 设计模式学习笔记

    通过上述对Head First设计模式学习笔记的解析,我们可以看到每种模式都在特定场景下发挥了重要作用,帮助开发者更好地组织代码,提高程序的可扩展性和可维护性。在实际项目中灵活运用这些设计模式,可以有效提升软件...

    HeadFirst 设计模式学习笔记1--策略模式Demo

    《HeadFirst设计模式学习笔记1--策略模式Demo》 在软件工程中,设计模式是一种解决常见问题的标准方案,它提供了一种在特定情况下组织代码的模板。策略模式是设计模式中的一种行为模式,它允许在运行时选择算法或...

    HeadFirst 设计模式学习笔记3--装饰模式 Demo

    在“HeadFirst 设计模式学习笔记3--装饰模式 Demo”中,作者通过实例讲解了装饰模式的基本概念、结构和应用场景。这篇文章可能是从CSDN博客平台上的一个链接访问的,遗憾的是,由于我们当前无法直接访问该链接,所以...

    HeadFirst 设计模式学习笔记2--观察者模式 demo

    总的来说,HeadFirst设计模式的学习笔记2关于观察者模式的演示,旨在帮助开发者理解如何使用观察者模式来构建可扩展的系统。通过实际的代码示例,我们可以更深入地掌握这一模式,并将其应用到日常开发中,提升代码的...

    Head First 设计模式学习笔记(十四)模式的组合使用

    在《Head First 设计模式学习笔记(十四)模式的组合使用》中,作者探讨了如何在实际编程中灵活地组合多种设计模式以解决复杂问题。这篇文章可能是基于《Head First 设计模式》这本书的一个章节,该书是设计模式领域...

    Head.First 设计模式学习笔记.pdf

    ### Head.First 设计模式学习笔记知识点总结 #### 一、设计模式概述 设计模式是一种用于解决软件设计中常见问题的标准化方法。通过采用设计模式,开发者可以提高代码的复用性、灵活性和可维护性。《Head First 设计...

    Head First 设计模式 扫描版

    《Head First 设计模式》是软件开发领域内一本广受欢迎的书籍,由Eric Freeman、Elisabeth Robson、Bert Bates和Kathy Sierra四位作者共同撰写。这本书以其独特的视觉风格和易于理解的教学方法,深入浅出地介绍了...

    读书笔记:设计模式学习笔记和代码。《图解设计模式》《Head First 设计模式》.zip

    读书笔记:设计模式学习笔记和代码。《图解设计模式》《Head First 设计模式》

    HeadFirst设计模式笔记

    《HeadFirst设计模式笔记》是深入理解软件设计思想的一份宝贵资料,主要涵盖了设计模式的基础理论和实际应用。设计模式是软件开发中的经验总结,它为解决常见的编程问题提供了标准的解决方案,使得代码更具可读性、...

    基于Java语言的《Head First 设计模式》学习笔记及实战练习源码

    本项目为《Head First 设计模式》的Java语言学习笔记与实战练习源码集合,包含104个文件,主要包括88个Java源文件、12个Markdown文档、3个XML配置文件及少量其他辅助文件。内容涵盖设计模式的学习笔记以及相应的代码...

    Head First设计模式读书笔记-DesignPatterns.zip

    《Head First设计模式》是一本深受开发者喜爱的设计模式学习书籍,它以易懂且生动的方式介绍了23种经典设计模式。这些模式是软件工程中经过实践验证的最佳实践,旨在提高代码的可重用性、可读性和可维护性。下面,...

    Head First Design Pattern 学习笔记

    著名的《Head First Design Pattern》学习笔记,摘要这本书中的设计思路。由于书本过长,整理出笔记帮助回想起设计模式。文件是docx格式,只能由OFFICE Word 2007之后的版本打开,内附Visio类图文件。本文由个人整理...

    Head First Servlets & JSP 学习笔记

    以上只是《Head First Servlets & JSP》一书中的部分核心知识点,实际内容还包括过滤器、监听器、MVC设计模式、JSTL等更广泛的主题,旨在帮助读者全面理解和掌握Servlet和JSP技术。通过深入学习,开发者能够构建高效...

    head first 设计模式

    通过以上对“Head First设计模式”书中可能涉及的设计模式的介绍,我们可以看出这本书是学习面向对象设计模式的绝佳资源。无论是初学者还是有一定经验的开发人员,都能从中受益匪浅。理解并熟练运用这些模式能够帮助...

    head first C#学习笔记:如何创建事件

    本学习笔记将深入探讨如何在C#中创建事件,以实现一个棒球模拟系统的例子。在这个系统中,我们将关注投球手、观众和裁判的交互,当输入棒球的轨迹和距离时,这些对象会根据模拟结果做出相应的反应。 首先,理解事件...

    head_first_servlet&jsp学习笔记

    【Servlet&JSP基础知识】 ...以上是`head_first_servlet&jsp`学习笔记的主要知识点,涵盖了Servlet和JSP的基础、Web应用架构、MVC模式、会话管理和JSP编程等多个方面,为深入理解和实践Servlet与JSP开发奠定了基础。

    设计模式笔记及其源代码(java版)

    设计模式Head First学习笔记,以及使用java编写的设计模式源码,Java原生sdk实现23种设计模式

    head first策略者模式

    《Head First 策略者模式》学习笔记 策略者模式是一种行为设计模式,它使你能在运行时改变对象的行为。在软件开发中,我们常常遇到需要根据不同的情况执行不同算法的问题。策略者模式就是为了解决这类问题而生,它...

Global site tag (gtag.js) - Google Analytics