Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[52.14.85.76] |
|
Сообщ.
#1
,
|
|
|
Обнаружил интересную статью http://habrahabr.ru/post/147927/
Там есть пример с классом собаки. В классе собаки (или вне его) должен быть метод "выгулять". Дополнительно будем задавать сколько часов гулять. Есть несколько решений 1. Решение в стиле С - вообще не ООП class Dog { //данные класса "собака" }; void walk(Dog& dog, int h){ //... } Dog dog; walk(dog, 1); 2. Метод класса с параметром class Dog { //данные класса "собака" public: void walk(int h);//метод "выгулять собаку в течение h часов" }; Dog dog; dog.walk(1); 3. Метод класса без параметра, который в данных класса class Dog { //данные класса "собака" public: void walk();//метод "выгулять собаку" void set_hours(int h)//сколько часов будем гулять? }; Dog dog; set_hours(1); dog.walk(); 4. Создать "менеджер собак", в котором будет метод выгуливания. Но здесь тоже есть вопросы. Должен ли он содержать в себе объект собаки (или все объекты собак в программе), или может быть он должен наследоваться от класса собаки? Или может быть собака наследуется от своего менеджера? class DogManager1 { public: void walk(Dog& dog, int h); }; class DogManager2 { Dog dog; public: void walk(int h); }; class DogManager3 { vector<Dog> dogs; public: void walk(int h, int n_dog); }; //и еще много вариантов Какое решение вы считаете лучшее? |
Сообщ.
#2
,
|
|
|
Первый или второй как наиболее простые. Выбор из них будет зависеть от языка.
Третий вариант — это, по-моему, пример плохого дизайна: ну зачем в классе собаки хранить параметр часов текущего выгула, если это не ее характеристика? Четвертый — какой-то «over-engineering», необоснованно (пере)усложнен, попахивает «паттернами проектирования головного мозга». |
Сообщ.
#3
,
|
|
|
seregaz, фишка в том, что операция "выгул собаки" - это не ответственность собаки. Хоть в прямом, хоть в переносном смысле. В твоём случае класс собаки должен выглядеть так:
enum LocationType { Indoor, Outdoor }; class Dog { public: //... void MoveTo(LocationType loc); //... }; И появляется класс хозяина: class DogOwner { public: void WalkDog(Dog* d); }; |
Сообщ.
#4
,
|
|
|
Там же есть аналогичный пример с банковским счетом. Есть класс счета Account
Должны быть функции "снять со счета" - Transfer, "перевести на другой счет" - Withdraw. Теперь начинаются проблемы Счет не должен сам с себя снимать. Т.е поместить методы в класс счета плохо. Какой вариант выбрать, или оба неправильные? acc.Withdraw(100);//снять 100 рублей со счета acc accfrom.Transfer(100,accto);//перевести 100 рублей со счета accfrom на счет accto или Withdraw(acc, 100);//снять 100 рублей со счета acc Transfer(100,accfrom,accto);/перевести 100 рублей со счета accfrom на счет accto В случае выбора второго варианта, нужен ли специальный контейнер для этих функций наподобие class AccountManager |
Сообщ.
#5
,
|
|
|
Ответ на вопрос про собаку или счета - зависит исключительно от требований задачи! ООП само по себе не диктует единственно верный ответ, хоть ты тресни. ООП - это просто классы и методы, не более того.
Поэтому подход к проектированию классов напрямую зависит от выбора модели (и её детализации), которую мы будем использовать для решения нашей задачи. Если смотреть на реальную жизнь, то больше всего, имхо, ей соответствует вариант с отдельным понятием процесса выгула собаки (перевода денег между счетами) - сервис, менеджер и т.д. И естественно никакого наследования! Это вообще похоже на бред. |