1. 程式人生 > >23種設計模式之(九)裝飾模式(python_c++實現)

23種設計模式之(九)裝飾模式(python_c++實現)

23種設計模式之(九)組合模式(Composite)

本文主要介紹23種設計模式之組合模式,附詳細python/c++示例程式碼。 - 概念 - 應用場景 - 注意事項 - 程式碼示例 - 總結 - 程式碼連結

組合模式(Composite)

概念

組合模式,是構造型的設計模式之一。通過遞迴手段依據樹形結構來組合物件,用來表示部分以及整體層次,並可以通過一個物件來訪問整個物件樹,把一組相似的物件當作一個單一的物件

這種模式建立了一個包含自己物件組的類。該類提供了修改相同物件組的方式。

GoF對原型模式的定義是:將物件組合成樹形結構以表示“部分-整體”的層次結構。Composite使得客戶對單個物件和複合物件的使用具有一致性。

應用場景

(1)客戶程式需要像處理簡單元素一樣來處理複雜元素,從而使得客戶程式與複雜元素的內部結構解耦。

(2)使用者需要忽略組合物件與單個物件的不同,使用者將統一地使用組合結構中的所有物件(如樹形選單,檔案、資料夾的管理。)。

程式碼示例

C++程式碼示例

/************************************************************************/
/* 設計模式專題
/*
/* 組合模式
/*
/* Author  : zzl
/*
/* 程式設計環境: window10 vs2010
/*
/* Date    : 20180916
/************************************************************************/
#include <iostream> #include "string" #include "list" class IFile { public: virtual void display() = 0; virtual int add(IFile *ifile) = 0; virtual int remove(IFile *ifile) = 0; virtual std::list<IFile *>* getChild() = 0; }; //檔案結點 class File : public IFile { public: File(std
::string name) { m_name = name; } virtual void display() { printf("%s\n",m_name.c_str()); } virtual int add(IFile *ifile) { return -1; } virtual int remove(IFile *ifile) { return -1; } virtual std::list<IFile *>* getChild() { return NULL; } private: std::string m_name; }; //目錄 結點 class Dir : public IFile { public: Dir(std::string name) { m_name = name; m_list = new std::list<IFile *>; m_list->clear(); } virtual void display() { printf("%s\n",m_name.c_str()); } virtual int add(IFile *ifile) { m_list->push_back(ifile); return 0; } virtual int remove(IFile *ifile) { m_list->remove(ifile); return 0; } virtual std::list<IFile *>* getChild() { return m_list; } private: std::string m_name; std::list<IFile *> *m_list; }; // 遞迴的顯示樹 void showTree(IFile *root, int level) { int i = 0; if (root == NULL) { return ; } for (i=0; i<level; i++) { printf("\t"); } //1 顯示根 結點 root->display(); //2 若根結點 有孩子 //判讀孩子是檔案,顯示名字 ) //判斷孩子是目錄,showTree(子目錄) std::list<IFile *> *mylist = root->getChild(); if (mylist != NULL) //說明是一個目錄 { for (std::list<IFile *>::iterator it=mylist->begin(); it!=mylist->end(); it++) { if ( (*it)->getChild() == NULL ) { for (i=0; i<=level; i++) //注意 <= { printf("\t"); } (*it)->display(); } else { showTree(*it, level+1); } } } } void main() { Dir *root = new Dir("C"); //root->display(); Dir *dir1 = new Dir("111dir"); File *aaafile = new File("aaa.txt"); //獲取root結點下的 孩子集合 std::list<IFile *> *mylist = root->getChild(); root->add(dir1); root->add(aaafile); for ( std::list<IFile *>::iterator it=mylist->begin(); it!=mylist->end(); it++ ) { (*it)->display(); } Dir *dir222 = new Dir("222dir"); File *bbbfile = new File("bbb.txt"); dir1->add(dir222); dir1->add(bbbfile); printf("--------showTree---------\n"); showTree(root, 0); }

python程式碼示例

# -*- coding: utf-8 -*-
###################################################################
# 設計模式專題
# 
# 組合模式
# 
# Author  : zzl
# 
# 程式設計環境: window10 python2.7
# 
# Date    : 20180916
##################################################################

class IFile(object):
    def display(self):
        pass

    def add(self, ifile):
        pass

    def remove(self, ifile):
        pass

    def get_child(self):
        pass


# 檔案結點
class File(IFile):
    def __init__(self, name):
        self.m_name = name

    def display(self):
        print(self.m_name)

    def add(self, ifile):
        return -1

    def remove(self, ifile):
        return -1

    def get_child(self):
        return None


# 目錄結點
class Dir(IFile):
    def __init__(self, name):
        self.m_name = name
        self.m_list = []
        m_name = name

    def display(self):
        print(self.m_name)

    def add(self, ifile):
        self.m_list.append(ifile)

    def remove(self, ifile):
        self.m_list.remove(ifile)

    def get_child(self):
        return self.m_list


def show_tree(root, level):
    if not root:
        return
    for i in range(level):
        print "\t",#python2.7 列印不換行
    # 1、顯示根結點
    root.display()
    # 2、若根結點有孩子
    # 判讀孩子是檔案, 顯示名字
    # 判斷孩子是目錄, showTree(子目錄)
    mylist = root.get_child()
    if mylist:  # 說明是一個目錄
        for child in mylist:
            if not child.get_child():
                for i in range(level + 1):
                    print "\t",   #python2.7 列印不換行
                child.display()
            else:
                show_tree(child, level + 1)


if __name__ == "__main__":
    root = Dir("C")
    dir1 = Dir("111dir")
    aaafile = File("aaa.txt")

    # 獲取root結點下的孩子集合
    mylist = root.get_child()
    root.add(dir1)
    root.add(aaafile)
    for child in mylist:
        child.display()

    dir222 = Dir("222dir")
    bbbfile = File("bbb.txt")
    dir1.add(dir222)
    dir1.add(bbbfile)

    print("--------showTree---------")
    show_tree(root, 0)


原始碼連結