Брутально и бессердечно о программировании и проектировании
ГлавнаяФорумАртАнтипаттерныТест-драйвЗаметкиВопрос-ответКнигорецензииСправочная

Property

Цель паттерна «Property» — привязать какую-то функциональность к присваиванию и получению значения какого-либо члена класса. Например, пусть у вас есть класс window, и в нем есть член title. Вы хотите, чтобы в момент присваивания этому члену какого-то значения автоматически вызывалась API функция, которая устанавливала бы текст заголовка окна.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <windows.h>
#include <iostream>

template <class object, class type>
class property
{
public:

    typedef type (object::*get_proc)() const;
    typedef void (object::*set_proc)(type const&);

    property(object& object, get_proc getpr, set_proc setpr)
    : obj   (object)
    , getter(getpr)
    , setter(setpr)
    {
    }

    operator type ()
    {
        return get();
    }

    type const& operator = (type const& value)
    {
        set(value);
        return value;
    }

    property& operator = (property const& prt)
    {
        set(prt.get());
        return *this;
    }

private:

    object& obj;
    get_proc getter;
    set_proc setter;

    inline type get() const
    {
        return (obj.*getter)();
    }

    inline void set(type const& value)
    {
        (obj.*setter)(value);
    }
};

class window
{
public:

    property<window, std::string> title;

    window(std::string const& title_text)
    : title(*this, &window::get_title, &window::set_title)
    {
        // Как-то инициализируем handle
        set_title(title_text);
    }

private:

    HWND handle;

    std::string get_title() const
    {
        char buffer[1024] = {0};
        GetWindowTextA(handle, buffer, sizeof(buffer));
        return buffer;
    }

    void set_title(const std::string& new_title)
    {
        SetWindowTextA(handle, new_title.c_str());
    }
};

int main()
{
    window w1("Toolbar");
    window w2("About box");

    w1.title = "Help page";

    std::string title = w2.title;

    w2.title = w1.title;

    return 0;
}
Паттерн «Property» является далеко не самым привычным и естественным паттерном для языка C++. Например, прямое присваивание (строка 91), и присваивание через агрегирующий класс (строка 93), очевидно, должны иметь различный результат. В первом случае мы ожидаем вызова соответствующих геттера и сеттера, во втором же мы хотим чтобы было выполнено полноценное присваивание с подменой ссылки на объект, которым управляет propetry. Очевидно, что C++ не различает эти два типа присваивания.
«Property» хорошо уживается в языках с более ярковыраженными динамическими свойствами, такими как Java или C#. В языке C++ следует стараться использовать альтернативные приемы, поскольку данный паттерн не является естественным для языка и не может быть реализован полностью в соответствии со своей семантикой.

Оглавление
Статистика
© 2007—2009 Inside C++ Коммерческие услугиКонтактная информация

анализаторы ИКМ - Беркут Е1. . На icedland.ru Вы найдете: онлайн игры bubble, наша специализация онлайн игра.