Проектирование классов, интерфейсы
От: Аноним  
Дата: 15.01.14 13:52
Оценка:
Здравствуйте.
Есть вот такие классы

class A()
{
public:
    int arr[1000];
    int foo;
    void calc();
    void calc_2();
    void calc_3();    
}

class B()
{
public:
    int arr[1000];
    char bar;
    void calc();
    void calc_2();
    void calc_4();    
}


Хочу объединить эти классы. Начитавшись статей в Интернете вижу вот такое решение:
class ISomeGeneralClass()
{
public:
    virtual void calc();
    virtual void calc_2();
}

class A(): public ISomeGeneralClass
{
public:
    int arr[1000];
    int foo;
    virtual void calc() { /* Описание поведения А */ };    
}

class B(): public ISomeGeneralClass
{
public:
    int arr[1000];
    char bar;
    virtual void calc() { /* Описание поведения B */ };    
}

Но меня смущает, что у обоих классов есть одинаковые поля данных int arr[1000]. Не нужно ли это поле вынести в отдельный класс от который будут использовать A и B? Вот что-то такое:

class ISomeGeneralClass()
{
public:
    virtual void calc();
    virtual void calc_2();
}

class Data
{
public:
    int arr[1000];
}

class A(): public ISomeGeneralClass
{
public:
    Data data;
    int foo;
    virtual void calc() { /* Описание поведения А */ };    
}

class B(): public ISomeGeneralClass
{
public:
    Data data;
    char bar;
    virtual void calc() { /* Описание поведения B */ };    
}


Помогите, пожалуйста, решить этот вопрос.
Re: Проектирование классов, интерфейсы
От: Caracrist https://1pwd.org/
Дата: 15.01.14 14:13
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Хочу объединить эти классы.

что с ними сделать? Можно поподробнее описать смысл и природу такой операции...
~~~~~
~lol~~
~~~ Single Password Solution
Re: Проектирование классов, интерфейсы
От: Кодт Россия  
Дата: 15.01.14 17:31
Оценка: +2
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте.

А>Есть вот такие классы

А если не дурить себе и людям голову преждевременным абстрагированием? Что это за calc, calc_2, etc... и зачем их объединять?

Может быть, тут нужно иерархию городить, а может, шаблоны.
Перекуём баги на фичи!
Re: Проектирование классов, интерфейсы
От: Stgl  
Дата: 15.01.14 19:26
Оценка:
Есть класс A() в программе foo и класс B() в программе bar. Сейчас классы — это просто обертка над кучей функций. Часть данных у этих двух классов совпадают, но есть и отличия. Аналогично с функциями — часть полностью одинакова, часть выполняют похожие действия с некоторыми отличиями. Хочу написать единую программу, так как действия обоих классов схожи и было бы логично иметь все в одном месте и для последующей поддержки будет проще менять что-то в коде одной программы.

class A()
{
public:
    int arr[1000]; // это поле полностью совпадает с полем в классе B
    int foo; // это уникальное поле данных для данного класса

    // код этой функции полностью совпадает с кодом в классе B
    void calc()
    {
        for (int i = 0; i < 1000; i++) arr[i] = i;
    } 

    // У этой функции есть небольшие отличия от аналогичной в классе B
    void calc_2()    
    {
        std::cout << arr[0];
        foo = 123 + arr[1];
        std::cout << foo;
    }

    // Уникальная функция для класса А     
    void calc_3()
    {
        arr[3] = 0xFF;
    } 
}

class B()
{
public:
    int arr[1000];
    char bar;

    void calc()
    {
        for (int i = 0; i < 1000; i++) arr[i] = i;
    } 

    void calc_2()
    {
        std::cout << arr[0];
        bar = 'A';
        std::cout << bar;
    }

    // Уникальная функция для класса B   
    void calc_4()
    {
        arr[100] = 0xAA;
    } 
}
Re: Проектирование классов, интерфейсы
От: opener  
Дата: 16.01.14 03:59
Оценка: +1 :)
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте.

А>Есть вот такие классы

А>
А>class A()
А>{
А>public:
А>    int arr[1000];
А>    int foo;
А>    void calc();
А>    void calc_2();
А>    void calc_3();    
А>}

А>class B()
А>{
А>public:
А>    int arr[1000];
А>    char bar;
А>    void calc();
А>    void calc_2();
А>    void calc_4();    
А>}
А>


А>Хочу объединить эти классы. Начитавшись статей в Интернете вижу вот такое решение:

А>
А>class ISomeGeneralClass()
А>{
А>public:
А>    virtual void calc();
А>    virtual void calc_2();
А>}

А>class A(): public ISomeGeneralClass
А>{
А>public:
А>    int arr[1000];
А>    int foo;
А>    virtual void calc() { /* Описание поведения А */ };    
А>}

А>class B(): public ISomeGeneralClass
А>{
А>public:
А>    int arr[1000];
А>    char bar;
А>    virtual void calc() { /* Описание поведения B */ };    
А>}
А>

А>Но меня смущает, что у обоих классов есть одинаковые поля данных int arr[1000]. Не нужно ли это поле вынести в отдельный класс от который будут использовать A и B? Вот что-то такое:

А>
А>class ISomeGeneralClass()
А>{
А>public:
А>    virtual void calc();
А>    virtual void calc_2();
А>}

А>class Data
А>{
А>public:
А>    int arr[1000];
А>}

А>class A(): public ISomeGeneralClass
А>{
А>public:
А>    Data data;
А>    int foo;
А>    virtual void calc() { /* Описание поведения А */ };    
А>}

А>class B(): public ISomeGeneralClass
А>{
А>public:
А>    Data data;
А>    char bar;
А>    virtual void calc() { /* Описание поведения B */ };    
А>}
А>


А>Помогите, пожалуйста, решить этот вопрос.


Общее замечание: не должно быть никаких публичных данных. Вообще. Без никаких исключений.
Re[2]: Проектирование классов, интерфейсы
От: Stgl  
Дата: 16.01.14 06:34
Оценка:
O>Общее замечание: не должно быть никаких публичных данных. Вообще. Без никаких исключений.
Это само собой разумеется.
Re[2]: Проектирование классов, интерфейсы
От: jazzer Россия Skype: enerjazzer
Дата: 16.01.14 08:08
Оценка: :))
Здравствуйте, opener, Вы сами себе противоречите:

O>Общее замечание: не должно быть никаких публичных данных. Вообще. Без никаких исключений.


jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Проектирование классов, интерфейсы
От: Кодт Россия  
Дата: 16.01.14 09:45
Оценка:
Здравствуйте, Stgl, Вы писали:

S>Есть класс A() в программе foo и класс B() в программе bar. Сейчас классы — это просто обертка над кучей функций. Часть данных у этих двух классов совпадают, но есть и отличия. Аналогично с функциями — часть полностью одинакова, часть выполняют похожие действия с некоторыми отличиями. Хочу написать единую программу, так как действия обоих классов схожи и было бы логично иметь все в одном месте и для последующей поддержки будет проще менять что-то в коде одной программы.


Если это обёртка над кучей функций, то было бы естественно выделить библиотечный базовый класс, который неизменен — не зависит от целей приложения.
После чего в каждом приложении выполнять настройку этой базы.

Настройку можно выполнять несколькими способами, по вкусу:
— наследники являются обёртками над обёрткой, т.е. это не ООП-наследование, а, скорее, паттерн Адаптер
— у базы есть точки кастомизации в виде виртуальных методов, наследники их переопределяют
— ... в виде членов-данных, возможно, функциональной природы (колбеки, указатели на интерфейсы и т.п.), — наследники снабжают базовый объект своими Стратегиями
— ... в виде параметров шаблона (база — шаблон класса), наследники указывают эти параметры, вплоть до использования идиомы CRTP

// У этой функции есть небольшие отличия от аналогичной в классе B
void calc_2()

Специально для этого есть паттерн Шаблонный Метод, суть которого в том, чтобы
void calc_2() { calc2_1(); calc2_2(); ..... } // общий план работ одинаковый, но
virtual void calc2_1(); // детали (пере)определяются в наследниках
virtual void calc2_2();
....


Если поведение варьируется только от программы к программе, т.е. в одной программе не могут сосуществовать оба класса,
то можно даже без шаблонов, — выполнить декомпозицию: вынести уникальные части во внешние классы и функции, и в разных программах определить их по-разному.
Фактически, это получается условная компиляция.
Перекуём баги на фичи!
Re[2]: Проектирование классов, интерфейсы
От: TarasB  
Дата: 16.01.14 11:02
Оценка:
Здравствуйте, Stgl, Вы писали:

S> int arr[1000]; // это поле полностью совпадает с полем в классе B

S> // код этой функции полностью совпадает с кодом в классе B

ну так их и выноси в отдельный базовый класс
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.