熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

Java與模式:合成模式

2013-11-23 19:42:45  來源: Java高級技術 

    合成(Composite)模式是一種非常重要的設計模式合成模式將對象組織到樹中用來描述樹的關系
    一原理圖


 
    從原理圖可見FileFolder都可以同等看待葦IFile為對象管理提供了極大的便利
    當然樹的概念不單單是文件文件夾的層次概念只是因為這個很形象實際中還有很多樹的概念比如組織機構分類層次等等都是邏輯上的概念不管是物理上的還是邏輯上的在Java裡都是一樣處理的
    二實例下面以一個邏輯樹為例子以上面的原理圖為藍本看看如何實現並如何使用這個樹這個結構很簡單但是如何去使用樹遍歷樹為我所用還是有一定難度的
    這裡主要用到樹的遞歸遍歷如何遞歸如何控制遍歷層級如何將邏輯關系轉換為(類似)物理關系這些都是有相當難度的
    廢話就不說了看看便知

 


/**
* Created by IntelliJ IDEA
* User: leizhimin
* Date: ::
* 抽象文件角色
*/
public interface IFile {
    //返回自己的實例
    IFile getComposite();

    //某個商業方法
    void sampleOperation();

    //獲取深度
    int getDeep();

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

}
 


import javautilVector;

/**
* Created by IntelliJ IDEA
* User: leizhimin
* Date: ::
* 文件夾角色
*/
public class Folder implements IFile {
    private String name;    //文件名字
    private int deep;       //層級深度根深度為
    private Vector<IFile> componentVector = new Vector<IFile>();

    public Folder(String name) {
        thisname = name;
    }

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

    //某個商業方法
    public void sampleOperation() {
        Systemoutprintln(執行了某個商業方法!);
    }

    //增加一個文件或文件夾
    public void add(IFile IFile) {
        componentVectoraddElement(IFile);
        IFilesetDeep(thisdeep + );

    }

    //刪除一個文件或文件夾
    public void remove(IFile IFile) {
        componentVectorremoveElement(IFile);
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        thisname = name;
    }

    public int getDeep() {
        return deep;
    }

    public void setDeep(int deep) {
        thisdeep = deep;
    }
}
 


/**
* Created by IntelliJ IDEA
* User: leizhimin
* Date: ::
* 文件
*/
public class File implements IFile {
    private String name;    //文件名字
    private int deep;       //層級深度

    public File(String name) {
        thisname = name;
    }

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

    //某個商業方法
    public void sampleOperation() {
        Systemoutprintln(執行了某個商業方法!);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        thisname = name;
    }

    public int getDeep() {
        return deep;
    }

    public void setDeep(int deep) {
        thisdeep = deep;
    }
}
 


import javautilIterator;
import javautilVector;

/**
* Created by IntelliJ IDEA
* User: leizhimin
* Date: ::
* 遍歷樹的一個測試
*/
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 b_ = new Folder(_枝);
        Folder b_ = new Folder(_枝);
        Folder b_ = new Folder(_枝);
        File l_ = new File(_葉);
        File l_ = new File(_葉);
        File l_ = new File(_葉);

        //b_下的文件及文件夾
        Folder b_ = new Folder(_枝);
        Folder b_ = new Folder(_枝);
        File l_ = new File(_葉);

        //締造樹的層次關系(簡單測試沒有重復添加的控制)
        rootadd(b_);
        rootadd(b_);
        rootadd(l_);
        rootadd(l_);

        b_add(b_);
        b_add(b_);
        b_add(l_);
        rootadd(l_);
        rootadd(b_);
        //控制台打印樹的層次
        outTree(root);
    }

    public void outTree(Folder folder) {
        Systemoutprintln(foldergetName());
        iterateTree(folder);
    }

    /**
     * 遍歷文件夾輸入文件樹
     *
     * @param folder
     */
    public void iterateTree(Folder folder) {
        Vector<IFile> clist = foldergetAllComponent();
        //todo:遍歷之前可以對clist進行排序這些都不是重點
        for (Iterator<IFile> it = erator(); ithasNext();) {
            IFile em = itnext();
            if (em instanceof Folder) {
                Folder cm = (Folder) em;
                Systemoutprintln(getIndents(emgetDeep()) + cmgetName());
                iterateTree(cm);
            } else {
                Systemoutprintln(getIndents(emgetDeep()) + ((File) em)getName());
            }
        }
    }

    /**
     * 文件層次縮進字符串
     *
     * @param x 縮進字符個數
     * @return 縮進字符串
     */
    public static String getIndents(int x) {
        StringBuilder sb = new StringBuilder();
        for (int i = ; i < x; i++) {
            sbappend(indentChar);
        }
        return sbtoString();
    }
}
    三運行測試
    控制台輸出如下

 

  


 
 
    可見樹邏輯關系已經成功展示出來了
    四總結上面所用的合成模式是安全合成模式所謂的安全是指File與Folder中的方法不同Folder有對聚集對象的管理File沒有
    合成模式在程序設計中有著廣泛的應用比如Domj資源管理器Java GUI容器層次圖等等都是合成模式應用的典范
    合成模式很多都是需要分析思考才能鑒別出來的比如要做一個復雜的數學表達式計算器有四種運算符號分析發現運算量有兩種一種是數字一種是數字的表達式但是表達式也是由數字組成因此數字和表達式可以抽象為運算量然後去表達要運算的表達式問題迎刃而解
    原文出處

From:http://tw.wingwit.com/Article/program/Java/gj/201311/27351.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.