ראשי > decorator pattern > חלק שלישי
The Decorator

כמה נקודות בקשר למימוש:
למעלה
קוד לדוגמה:
הקוד הבא מדגים כיצד לממש decorator ים עבור ממשק משתמש. אנו נניח שיש Component שנקרא VisualComponent:

class VisualComponent {
public:
     visualComponent();

     virtual void Draw();
     virtual void Resize();
     // ...
};

נגדיר subclass של VisualComponent שנקרא Decorator , ולו נבצע subclassing על מנת לקבל דקורציות שונות:

class Decorator : public VisualComponent {
public:
     Decorator(VisualComponent*);

     virtual void Draw();
     virtual void Resize();
     //...
private:
     VisualComponent* _component;
};

Decorator מבצע דקורציה ל VisualComponent שמוחזק במשתנה _component שמאותחל ב constructor. לכל פעולה בממשק של VisualComponentDecorator מגדיר מימוש ברירת מחדל שפשוט מעביר את הבקשה ישירות ל _component:

void Decorator::Draw() {
     _component->Draw();
}

void Decorator::Resize() {
     _component->Resize();
}

subclass ים של Decorator מגדירים דקורציות ספציפיות. לדוגמה, BorderDecorator מוסיף גבול ל component שלו. הוא subclass של Decorator שמגדיר את פעולת ה Draw() מחדש כך שתצייר גם גבול. הוא גם מגדיר לצורך זה פעולת DrawBorder() פרטית שמבצעת את הציור. את כל שאר המימושים הוא יורש מ Decorator:

class BorderDecorator : public Decorator {
public:
     BorderDecorator(VisualComponent*,int borderWidth);

     virtual void Draw();
private:
     void DrawBorder(int);
     int _width;
};

void BorderDecorator::Draw() {
     Decorator::Draw();
     DrawBorder(_width);
}

מימוש דומה יתבצע עבור ScrollDecorator ו DropShadowDecorator שיוסיפו ל component וויזואלי אפשרויות לגלילה ולצללית. כעת נוכל להרכיב מופעים של class ים אלה על מנת לקבל דקורציות שונות. הקוד הבא מדגים כיצד ניתן להשתמש ב decorator ים על מנת ליצור TextView שניתן לגלילה ויש לו גבול מסביבו.
תחילה נשים את ה VisualComponentבתוך אובייקט חלון. אנו נניח שמחלקת ה Window שלנו מספקת פעולת SetContents() למטרה זו:

void Window::SetContents(VisualComponent* contents) {
     //...
}

כעת ניתן ליצור את TextView וחלון לשים אותו בתוכו:

Window* window = new Window;
TextView* textView = new TextView;

TextView הוא VisualComponent ולכן אנו יכולים לשים אותו בתוך החלון:

window->SetContents(textView);

אבל אנו נרצה שיהיה ל TextView גם גבול ואפשרות לגלילה ולכן נבצע לו דקורציה לפני שנשים אותו בחלון:

window->SetContents(
     new BorderDecorator(
         new ScrollDecorator(textView), 1
     )
);

מכיוון ש Window נכנס לתוכן שלו דרך הממשק של VisualComponent הוא אינו מודע לנוכחות של ה decorator. עם זאת אנחנו עדיין יכולים לעקוב אחר ה TextView למקרה שנצטרך לתקשר איתו ישירות, למשל במקרים שנצטרך פעולות שספציפיות לו ואינן קיימות בממשק של VisualComponent . כל הקליינטים אשר מסתמכים על זהותו האמיתית של ה component, כלומר על פעולות שספציפיות רק לו, חייבים להתייחס אליו ישירות ולא דרך ה Decorator.

למעלה







 
מה בעמוד:
 
מימוש
קוד לדוגמה