Рассуждения о проектировании
От: R1K0 Россия  
Дата: 20.01.10 08:50
Оценка:
Всем привет.
Сейчас сидел придумывал дополнительную фичу к коду и нашел такую штучку. Сразу оговорюсь, что это просто размышления вслух, а не призыв к активному юзу

Допусти есть такая системка:

class cOption
{
  public:
    int attr;
};

class cOptions
{
  private:
    vector<cOption *> _options;
};


И нашел я два способа (ну больше и не искал ) для того чтобы управлять набором опций:
1. Добавить в класс cOption ряд public-методов для получения управления — думаю смысл понятен;
2. В класс cOption добавить ряд управляющих static методов (как алтернатива их добавлению в cOptions) и радосно юзать методы которые относятся к конкретному cOption из класса cOption.

У кого какие мысли на данный счет.
Re: Рассуждения о проектировании
От: R1K0 Россия  
Дата: 20.01.10 09:15
Оценка:
В догонку.
Вот реальный пример:

class cOption
{
    public:
        cOption() {}
        ~cOption() {}

        static CString GetName(UINT index_);
        static bool    GetState(UINT index_);

    private:
        CString name;
        bool    state;

        static vector<cOption *> _options;
};


Функционала минимум, но, думаю, что тема ясна.
Re: Рассуждения о проектировании
От: kvasya  
Дата: 20.01.10 09:43
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>У кого какие мысли на данный счет.


Я не уловил, какую проблему ты решаешь? Или — в чем смысл?
Re[2]: Рассуждения о проектировании
От: R1K0 Россия  
Дата: 20.01.10 09:53
Оценка:
Здравствуйте, kvasya, Вы писали:

K>Я не уловил, какую проблему ты решаешь? Или — в чем смысл?


Да это не проблема. Я же в первом посте сказал, что это просто размышления о +/- такого подхода. И все

Мне интересно, что по этому поводу думает наше сообщество, потому как мне этот подход кажется достаточно удобным, а может кто выскажет такие контраргументы, что я сразу думать по другому начну
Re[2]: Рассуждения о проектировании
От: andyag  
Дата: 20.01.10 10:20
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>В догонку.

RK>Вот реальный пример:

Такое решение может быть вполне приемлемым в случае одного отдельно взятого проекта, но в качестве общего решения много недостатков:
1. Как этот класс будет использоваться? Обращения по индексам достаточно? А если хочется обращаться по имени? 2 набора функций — Set/GetByIndex и Set/GetByName? Неуниверсально. Но — ещё раз зависит от задачи.
2. Откуда возьмутся значения в _options? Делать друзей класса и через зад заталкивать? Тоже как-то не очень логично.
3. Как быть, если возникнет задача хранения двух наборов опций? Сделать класс шаблонным — добавить "номер хранилища"?

Объясни всё-таки что тебя навело на такой дизайн.
Re: Рассуждения о проектировании
От: ankorol Украина  
Дата: 20.01.10 10:21
Оценка:
Здравствуйте, R1K0, Вы писали:
RK>Допусти есть такая системка:

RK>
RK>class cOption
RK>{
RK>  public:
RK>    int attr;
RK>};

RK>class cOptions
RK>{
RK>  private:
RK>    vector<cOption *> _options;
RK>};
RK>



RK>У кого какие мысли на данный счет.


Мне гораздо привычнее работать с vector<cOption *> чем с cOptions. Зачем плодить сущности?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[3]: Рассуждения о проектировании
От: R1K0 Россия  
Дата: 20.01.10 11:25
Оценка:
Здравствуйте, andyag, Вы писали:

A>Здравствуйте, R1K0, Вы писали:


RK>>В догонку.

RK>>Вот реальный пример:

A>Такое решение может быть вполне приемлемым в случае одного отдельно взятого проекта, но в качестве общего решения много недостатков:

A>1. Как этот класс будет использоваться? Обращения по индексам достаточно? А если хочется обращаться по имени? 2 набора функций — Set/GetByIndex и Set/GetByName? Неуниверсально. Но — ещё раз зависит от задачи.
A>2. Откуда возьмутся значения в _options? Делать друзей класса и через зад заталкивать? Тоже как-то не очень логично.
A>3. Как быть, если возникнет задача хранения двух наборов опций? Сделать класс шаблонным — добавить "номер хранилища"?

A>Объясни всё-таки что тебя навело на такой дизайн.


Начну с конца: ничего не наводило кроме пространных рассуждений. А что касается добавлений и прочего, то, например, во так:

class cWebOption
{
    public:
        cWebOption(CString name_, bool state_) : _name(name_), _state(state_) {}
        ~cWebOption() {}

        static void Save();
        static void Load();

        static inline cWebOption * ByIndex(UINT index_) { return _options.at(index_); }


        static void Add(cWebOption * option_);
        static void Clear();

    private:
        CString _name;
        bool    _state;

        static vector<cWebOption *> _options;
};


Таким образом добавление будет:

cWebOption::Add(new cWebOption("", true));


И еще раз повторю — это просто мысли в слух, поиск альтернатив и досужие исследования.
Re[4]: Рассуждения о проектировании
От: kvasya  
Дата: 20.01.10 11:48
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>Здравствуйте, andyag, Вы писали:


RK>И еще раз повторю — это просто мысли в слух, поиск альтернатив и досужие исследования.


Имхо — рассматривать логично только в контексте конкретных задач. На универсальность не претендует. Опять же boost
Но для конкретной задачи — вполне может быть конкретным решением.

К слову, а синглетон не рассматривался? Более лаконично и потенциал для развития в своей стезе есть.
Еще к слову, а как же многопоточная среда?
Re[5]: Рассуждения о проектировании
От: R1K0 Россия  
Дата: 20.01.10 12:21
Оценка:
Здравствуйте, kvasya, Вы писали:

K>К слову, а синглетон не рассматривался? Более лаконично и потенциал для развития в своей стезе есть.

K>Еще к слову, а как же многопоточная среда?

1. Конечно, как вариант синглтон рулит, но смысла в нем не вижу, так как это нужно на начальном этапе загрузки и при закрытии, так как настройка, и очень ограниченному количеству классов;
2. Ну полагаю, что про многопоточность уже ответил Ну а вообще на этот случай CRITICAL_SECTION есть. А для read-only опции даже они не нужны.
Re[4]: Рассуждения о проектировании
От: zaufi Земля  
Дата: 20.01.10 13:35
Оценка: 1 (1) +1
почитал весь thread но так и не понял зачем это нужно. в конечном итоге сделал для себя assumption что тебе виднее и ты просто не раскрыл всех деталей спрашивая нас о дизайне твоего класса... я вполне допускаю что в рамках одного конкретного проекта (не оч большого) данный класс имеет право на существование... однако, в своей практике я предпочитаю делать обобщенный и реюзабельный код (ну по кр мере попытаться перед тем как скатываться к решению заранее зная что нигде кроме одного конкретного проекта я это использовать не смогу)

дык вот возвращаясь к твоему классу cWebOption ... (приведу его еще раз чтобы был перед глазами):

class cWebOption
{
    public:
        cWebOption(CString name_, bool state_) : _name(name_), _state(state_) {}
        ~cWebOption() {}

        static void Save();
        static void Load();

        static inline cWebOption * ByIndex(UINT index_) { return _options.at(index_); }


        static void Add(cWebOption * option_);
        static void Clear();

    private:
        CString _name;
        bool    _state;

        static vector<cWebOption *> _options;
};



хотелось бы понять цепочку рассуждений пиводящую к подобному (странному) дизайну...
если начать его реверс инжинирить с точки зрения дизайна, я бы спросил тебя (как дизайнер дизайнера):

моделью какой сущности (из предметой области) является данный класс?
то что я здесь вижу пытается совмещать в себе "имя+значение" (кое где называемое NVP (Name Value Pair))... причем только boolean значения! а также пытается быть коллекцией этих значений (включилась первая тревожная лампочка: "внимание слишком много ответственностей у класса")

Какую афигительно полезную функциональность несет в себе данный класс (как option)?
т.е. чем cWebOption лучше чем std::pair<CString, bool> или boost::tuple<CString, bool>? -- я думаю, скорее всего, ничем! Да, да я догадываюсь что ты не привел в примере весь код... но думается мне врядли в твоем классе есть методы офигенно расширяющие границы использования пары (по сути) стринга и булика...

Какую афигительно полезную функциональность несет в себе данный класс (как коллекция optionов)?
Опять таки, сокрее всего ты не привел весь код целиком, а выделил наиболее важные (я надеюсь) методы... и опять таки я не вижу тут ничего аццки удобного или полезного по сравнению с просто вектором... более того, я вижу спложные проблемы и ограничения накладываемые данным классом:
*) штатно есть только один контейнер для хранения options -- т.е. предлагается хранить optionы только в нем... но это всего лишь добрая воля пользователя данного класса... ничто не заставит меня сделать это!
*) тип контейнера жестко задан: вектор инстанциированный указателями(!) на cWebOption и дефолтным аллокатором!... для end userа может быть не самый лучший выбор!
*) учитывая размер класса option не понимаю зачем хранить их в векторе как указатели а не by value? (может optionы полиморфны? см. ниже)
*) даже если аккци хочется указателей... почему не smart_ptrы?
*) набор функциональности над коллекцией optionов также весьма странен: можно добавлять, но удялять только все. можно обратиться по индексу но нельзя узнать сколько элементов. нафиг мне вообще какиета индексы? у меня ведь есть имя optionа!? -- былоб разумно получать значение по имени! Нет возможности сделать for_each по всем optionам (ну там проерить чонить например)...
*) Судя по тому что Load и Save без параметров они сами типо знают куда чего сохранять\загружать? (файл\база\etc)? и если так то это наделение низкоуровневой сущности знаниями которые ей не положено иметь...

тогда зачем вообще заставлять пользоваться этим недоконтейнером? почему не остапвить end-userу выбирать где и как он будет хрянить свои optionы?

ЗЫ: если скажешь какую задачу ты пытаешься решать, может найдутся телепаты которые помогут сделать дизайн по расссказам... да вопщем я и сам хотел было написать, но оч мало данных об исходной задаче (а много писать я не готов... и так уже наколбасил тут...)
Re[4]: Рассуждения о проектировании
От: andyag  
Дата: 20.01.10 14:36
Оценка: +1
Здравствуйте, R1K0, Вы писали:

RK>Начну с конца: ничего не наводило кроме пространных рассуждений. А что касается добавлений и прочего, то, например, во так:

Хорошо, если абстрактно, то так: это монолитный класс, который умеет делать всё. Читать файлы, писать файлы, кешировать(?) значения, делать поиск по значениям, сам же является контейнером своих же значений. У него слишком большая область ответственности. Тому, кто будет (в теории) сопровождать такой код, будет тяжко
Re: Рассуждения о проектировании
От: Turyst  
Дата: 21.01.10 14:03
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>Всем привет.

RK>Сейчас сидел придумывал дополнительную фичу к коду и нашел такую штучку. Сразу оговорюсь, что это просто размышления вслух, а не призыв к активному юзу

RK>Допусти есть такая системка:


RK>
RK>class cOption
RK>{
RK>  public:
RK>    int attr;
RK>};

RK>class cOptions
RK>{
RK>  private:
RK>    vector<cOption *> _options;
RK>};
RK>


RK>И нашел я два способа (ну больше и не искал ) для того чтобы управлять набором опций:

RK>1. Добавить в класс cOption ряд public-методов для получения управления — думаю смысл понятен;
RK>2. В класс cOption добавить ряд управляющих static методов (как алтернатива их добавлению в cOptions) и радосно юзать методы которые относятся к конкретному cOption из класса cOption.

RK>У кого какие мысли на данный счет.


Может я и ошибаюсь, но посмотри на паттерн Фасад...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.