C++設計形式之裝潢形式。本站提示廣大學習愛好者:(C++設計形式之裝潢形式)文章只能為提供參考,不一定能成為您想要的結果。以下是C++設計形式之裝潢形式正文
媒介
在現實開辟時,你有無碰著過這類成績;開辟一個類,封裝了一個對象的焦點操作,而這些操作就是客戶應用該類時都邑去挪用的操作;而有一些非焦點的操作,能夠會應用,也能夠不會應用;如今該怎樣辦呢?
1.將這些非焦點的操作全體放到類中,如許,一個類就包括了許多焦點的操作和一些看似有關,然則又有關的操作;這就會使焦點類產生“爆炸”的景象,從而使焦點類掉去了必定的價值,也使應用焦點類的客戶在焦點操作和非焦點操作中掙扎;
2.應用繼續來擴大焦點類,須要應用焦點類時,直接樹立焦點類對象;當須要應用焦點類擴大類時,就樹立焦點類擴大類對象;如許貌似是一種很有用的辦法;然則因為繼續為類型引入的靜態特質,使得這類擴大方法缺少靈巧性;同時,又失落入了另外一個圈套,跟著擴大功效的增多,子類也會增多,各類子類的組合,就會招致類的收縮,最初,就會被吞沒在類的陸地;此時,也不消我多說,你是否是想起了橋接形式,橋接形式就是為了順應多個維度的變更而產生子類“爆炸”的情形,然則,橋接形式是為了順應籠統和完成的分歧變更,其實不實用於我這裡說的。那若何是好,這就要說到明天總結的裝潢形式了。
甚麼是裝潢形式?
在GOF的《設計形式:可復用面向對象軟件的基本》一書中對裝潢形式是如許說的:靜態地給一個對象添加一些額定的職責。就增長功效來講,Decorator形式比擬生成子類更加靈巧。
裝潢形式可以或許完成靜態的為對象添加功效,是從一個對象內部來給對象添加功效。平日給對象添加功效,要末直接修正對象添加響應的功效,要末派生對應的子類來擴大,抑或是應用對象組合的方法。明顯,直接修正對應的類這類方法其實不可取。在面向對象的設計中,而我們也應當盡可能應用對象組合,而不是對象繼續來擴大和復用功效。裝潢器形式就是基於對象組合的方法,可以很靈巧的給對象添加所須要的功效。裝潢器形式的實質就是靜態組合。靜態是手腕,組合才是目標。總之,裝潢形式是經由過程把龐雜的功效簡略化,疏散化,然後再運轉時代,依據須要來靜態組合的如許一個形式。它使得我們可以給某個對象而不是全部類添加一些功效。
UML類圖
Component:界說一個對象接口,可以給這些對象靜態地添加職責;
ConcreteComponent:界說一個詳細的Component,繼續自ConcreateComponent,重寫了Component類的虛函數;
Decorator:保持一個指向Component對象的指針,該指針指向須要被裝潢的對象;並界說一個與Component接口分歧的接口;
ConcreteDecorator:向組件添加職責。
代碼完成:
/*
** FileName : DecoratorPatternDemo
** Author : Jelly Young
** Date : 2013/12/19
** Description : More information, please go to http://www.jb51.net
*/
#include <iostream>
using namespace std;
class Component
{
public:
virtual void Operation() = 0;
};
class ConcreteComponent : public Component
{
public:
void Operation()
{
cout<<"I am no decoratored ConcreteComponent"<<endl;
}
};
class Decorator : public Component
{
public:
Decorator(Component *pComponent) : m_pComponentObj(pComponent) {}
void Operation()
{
if (m_pComponentObj != NULL)
{
m_pComponentObj->Operation();
}
}
protected:
Component *m_pComponentObj;
};
class ConcreteDecoratorA : public Decorator
{
public:
ConcreteDecoratorA(Component *pDecorator) : Decorator(pDecorator){}
void Operation()
{
AddedBehavior();
Decorator::Operation();
}
void AddedBehavior()
{
cout<<"This is added behavior A."<<endl;
}
};
class ConcreteDecoratorB : public Decorator
{
public:
ConcreteDecoratorB(Component *pDecorator) : Decorator(pDecorator){}
void Operation()
{
AddedBehavior();
Decorator::Operation();
}
void AddedBehavior()
{
cout<<"This is added behavior B."<<endl;
}
};
int main()
{
Component *pComponentObj = new ConcreteComponent();
Decorator *pDecoratorAOjb = new ConcreteDecoratorA(pComponentObj);
pDecoratorAOjb->Operation();
cout<<"============================================="<<endl;
Decorator *pDecoratorBOjb = new ConcreteDecoratorB(pComponentObj);
pDecoratorBOjb->Operation();
cout<<"============================================="<<endl;
Decorator *pDecoratorBAOjb = new ConcreteDecoratorB(pDecoratorAOjb);
pDecoratorBAOjb->Operation();
cout<<"============================================="<<endl;
delete pDecoratorBAOjb;
pDecoratorBAOjb = NULL;
delete pDecoratorBOjb;
pDecoratorBOjb = NULL;
delete pDecoratorAOjb;
pDecoratorAOjb = NULL;
delete pComponentObj;
pComponentObj = NULL;
}
應用場所
1.在不影響其他對象的情形下,以靜態的,通明的方法給單個對象添加職責;
2.處置那些可以撤消的職責;
3.當不克不及采取生成子類的辦法停止擴大時。一種情形是,能夠存在年夜量自力的擴大,為支撐每種組合將發生年夜量的子類,使得子類數量呈爆炸性增加。另外一種情形能夠是由於類界說被隱蔽,或類界說不克不及用於生成子類。
留意事項
1.接口的分歧性;裝潢對象的接口必需與它所裝潢的Component的接口是分歧的,是以,一切的ConcreteDecorator類必需有一個公共的父類;如許關於用戶來講,就是同一的接口;
2.省略籠統的Decorator類;當僅須要添加一個職責時,沒有需要界說籠統Decorator類。由於我們經常要處置,現存的類條理構造而不是設計一個新體系,這時候可以把Decorator向Component轉發要求的職責歸並到ConcreteDecorator中;
3.堅持Component類的簡略性;為了包管接口的分歧性,組件和裝潢必需要有一個公共的Component類,所以堅持這個Component類的簡略性長短常主要的,所以,這個Component類應當集中於界說接口而不是存儲數據。對數據表現的界說應延遲到子類中,不然Component類會變得過於龐雜和癡肥,因此難以年夜量應用。付與Component類太多的功效,也使得詳細的子類有一些它們它們不須要的功效年夜年夜增年夜;
完成要點
1.Component類在Decorator形式中充任籠統接口的腳色,不該該去完成詳細的行動。並且Decorator類關於Component類應當通明,換言之Component類無需曉得Decorator類,Decorator類是從內部來擴大Component類的功效;
2.Decorator類在接口上表示為“is-a”Component的繼續關系,即Decorator類繼續了Component類所具有的接口。但在完成上又表示為“has-a”Component的組合關系,即Decorator類又應用了別的一個Component類。我們可使用一個或許多個Decorator對象來“裝潢”一個Component對象,且裝潢後的對象依然是一個Component對象;
3.Decortor形式並不是處理“多子類衍生的多繼續”成績,Decorator形式的運用要點在於處理“主體類在多個偏向上的擴大功效”——是為“裝潢”的寄義;
4.關於Decorator形式在現實中的應用可以很靈巧。假如只要一個ConcreteComponent類而沒有籠統的Component類,那末Decorator類可所以ConcreteComponent的一個子類。假如只要一個ConcreteDecorator類,那末就沒有需要樹立一個零丁的Decorator類,而可以把Decorator和ConcreteDecorator的義務歸並成一個類。
5.Decorator形式的長處是供給了比繼續加倍靈巧的擴大,經由過程應用分歧的詳細裝潢類和這些裝潢類的分列組合,可以發明出許多分歧行動的組合;
6.因為應用裝潢形式,可以比應用繼續關系須要較多數目標類。應用較少的類,固然使設計比擬易於停止。然則,在另外一方面,應用裝潢形式會發生比應用繼續關系更多的對象。更多的對象會使得查錯變得艱苦,特殊是這些對象看上去都很相像。
與橋接形式的差別
之前總結了C++設計形式——橋接形式;你會發明,兩者都是為了避免過度的繼續,從而形成子類眾多的情形。那末兩者之間的重要差別是甚麼呢?橋接形式的界說是將籠統化與完成化分別(用組合的方法而不是繼續的方法),使得二者可以自力變更。可以削減派生類的增加。假如光從這一點來看的話,和裝潢者差不多,但二者照樣有一些比擬主要的差別:
1.橋接形式中所說的分別,實際上是指將構造與完成分別(當構造和完成有能夠產生變更時)或屬性與基於屬性的行動停止分別;而裝潢者只是對基於屬性的行動停止關閉成自力的類,從而到達對其停止裝潢,也就是擴大。好比:異常類和異常處置類之間便可以應用橋接形式來完成完成,而不克不及應用裝潢形式來停止設計;假如關於異常的處置須要停止擴大時,我們又可以對異常處置類添加Decorator,從而添加處置的裝潢,到達異常處置的擴大,這就是一個橋接形式與裝潢形式的搭配;
2.橋接中的行動是橫向的行動,行動彼此之間有關聯,留意這裡的行動之間是沒有聯系關系的,就好比異常和異常處置之間是沒有行動聯系關系的一樣;而裝潢者形式中的行動具有可疊加性,其表示出來的成果是一個全體,一個各個行動組合後的一個成果。
總結
裝潢形式重點在裝潢,對焦點功效的裝潢感化;將繼續中對子類的擴大轉化為功效類的組合,從而將須要對子類的擴大轉嫁給用戶去停止挪用組合,用戶若何組合由用戶去決議。我在進修裝潢形式時,就是重點剖析了“裝潢”這個詞,我們都曉得,裝潢是在一個焦點功效上添加一些從屬功效,從而讓焦點功效施展更年夜的感化,然則終究它的焦點功效是不克不及喪失的。這就比如我們停止windows shell開辟時,我們是對windows的這層殼停止了功效的裝潢,從而完成了我們須要的一些裝潢功效,然則終究的功效照樣由windows shell去完成。這就比如,我們的裝潢就是給焦點功效添加了一層外套,讓它看起來更英俊和完善。