Який простий процес проектування системи OOP перед її кодуванням?


10

Кожного разу, коли від мене вимагали будувати проект, я завжди встигав його скласти, не заздалегідь розробивши план чи дизайн, а після того, як спочатку написав потрібний клас, склавши весь проект, будуючи знизу вгору. Тепер я знаю, що це не правильний спосіб створення програмного забезпечення, але мені непросто обернути голову навколо того, що називається об'єктно-орієнтованим аналізом та дизайном. Я можу легше зрозуміти процедурну конструкцію зверху вниз, оскільки вона полягає в простому розбитті завдань на підзадачі, речі, які мають свого аналога за кодом, функціями. Але об'єктно-орієнтований аналіз та дизайн я не можу легко зрозуміти, бо не розумію, як можна знати, які класи їм знадобляться та як вони будуть взаємодіяти, якщо вони не знають, як їх кодувати.

Оскільки ми впроваджуємо поняття класів та об’єктів у процес проектування, ми вже не можемо проектувати зверху вниз, оскільки ми більше не розбиваємо свої проблеми на ті речі, які можна реалізувати як процедури. Натомість, відповідно до того, що я прочитав з цього приводу, ми повинні визначити, які класи потрібні, та створити різні артефакти в уніфікованій мові моделювання, які потім ми можемо використовувати під час реалізації програмного забезпечення. Але такий процес проектування я не розумію. Бо як хтось знає, які класи їм знадобляться, і як вони будуть взаємодіяти, якщо вони вже не задумали всю систему?

Це тоді моя проблема. Я не розумію, як створити об'єктно-орієнтовану систему, хоча я розумію поняття об'єктно-орієнтованого програмування і можу використовувати ці поняття в будь-якій мові об'єктно-орієнтованого програмування. Тому мені потрібен хтось, який мені пояснить, який простий процес я можу використовувати для проектування об'єктно-орієнтованих систем таким чином, щоб він міг мати сенс для мене.


8
"Тепер я знаю, що це не правильний спосіб створення програмного забезпечення" - хто вам це сказав? Здається, якимось чином ви потрапляєте у популярну пастку вважати, що «дизайн - це те, що ви робите перед кодуванням, можливо, малюючи фантазійні діаграми UML». Щоб вилікувати вас від цієї помилки, рекомендую почати з «Коду як дизайн» Джека Ривза.
Док Браун


@DocBrown. Ви не вважаєте, що дизайн під час кодування - це те, що робить нашу роботу настільки саморобною? Я не можу уявити, щоб інші інженери працювали однаково. Уявіть, як архітектор розкладає цеглу та розчин та проектує будівлю / міст на шляху.
Лаїв

5
@Laiv: «кодування» є частиною того , що в інших інженерних дисциплінах , як називаються дизайном. У будівництві будинку крок від проектування до кінцевого продукту робиться за допомогою кладки цегли та розчину. У програмуванні цей крок виконує компілятор при перекладі конструкції (= програми) в кінцевий продукт (= виконуваний двійковий файл). І це не нова мудрість. Нарисам Ривза 25 років.
Док Браун

@DocBrown, розробник. * Вже не куратор? Наприклад, кнопка підписки порушена.
radarbob

Відповіді:


20

Стиль водоспаду зверху вниз OOAD не гарантує, що код, який ви пишете, взагалі орієнтований на об'єкт. Я бачив гори суворо кодового коду, що це підтверджує. Якщо ОО вас бентежить, не шукайте тут допомоги. Ви цього не знайдете. OO НЕ вимагає, щоб ви проектували зверху вниз.

Якщо ви любите кодувати, так і нехай буде. Дозвольте сказати вам підказку. Прокластувати.

Дивно, як легко створювати класи, написавши код, який використовує їх, навіть коли вони ще не існують. Забудьте про процедуру. Забудьте про структуру. Просто отримайте собі хороший послідовний рівень абстрагування і дотримуйтесь цього. Не піддавайся спокусі і не змішуй зайвих деталей. Все, що виводить вас із поточної абстракції, може бути зроблено в якомусь методі, який може бути на якомусь іншому об'єкті, який якимось чином знає все, що він повинен знати. Не будуйте нічого, що ви можете просто попросити передати вам.

Навчіться писати так, і ви виявите, що займаєтесь OO, навіть не дуже намагаючись. Це змушує вас дивитися на свої об’єкти з точки зору того, як вони використовуються (їх інтерфейс) та які об’єкти знають, про які інші об’єкти. Здогадайтесь, що таке основні дві точки діаграм UML?

Якщо ви можете потрапити в такий режим мислення, то залишилося архітектура. Ми все ще це з'ясовуємо. Від MVC до чистої архітектури до дизайну, керованого доменом. Вивчіть їх і пограйте. Використовуйте те, що працює. Якщо ви знайдете щось на 100% надійне, поверніться і дайте мені знати. Роблю це десятиліттями, і я все ще шукаю.


2
Або ви виявите, що не робите OO, і все-таки все "якось" добре справляється ...
Дерек Елкінс покинув SE

2
"Дивно, як легко створити класи, написавши код, який використовує їх, навіть коли вони ще не існують", - я називаю цей дизайн зверху вниз, але, здається, я помиляюся. Що таке дизайн зверху вниз і як це я назвав? Це програмування на інтерфейс?
Piovezan

Це не просто зверху вниз. Ви також повинні бути готові не будувати речі, про які ви можете просто запитати, приймаючи параметри.
candied_orange

@Piovezan ви можете це зробити навіть тоді, коли інтерфейс ще не існує. Просто трохи проігноруйте ваш компілятор. Пізніше ви змусите його існувати.
candied_orange

@CandiedOrange "Ви також повинні бути готові не будувати речі, про які ви можете просто попросити, прийнявши параметри." - Я не впевнений, що я розумію, чи можете ви пояснити / надати короткий приклад (або зустрічний приклад з цього питання)?
Piovezan

4

Ви стверджуєте, що можете використовувати об'єктно-орієнтовані методи у своєму коді, тому, ви вже знаєте, як створити об'єктно-орієнтовану систему , я вважаю, що ваша проблема полягає в тому, щоб , чи не можете ви. Вам здається, що комфортно з об'єктно-орієнтованим дизайном короткотерміновим ітераційним способом замість довгострокового планування.

Під час першої розробки проекту планувати та розробляти проект може бути дуже важко, саме тоді спритний розвиток розвивається над розвитком водоспадів , оскільки великий обсяг плану водоспаду часто не охопить усіх складностей програмного проекту.

Ви стверджуєте, що розвиватись на ходу без "початкового плану" є:

"... не правильний спосіб створення програмного забезпечення ..."

Якщо ваша проблема полягає в тому, що ваш початковий план недостатньо деталізований, знайдіть трохи більше часу, щоб пояснити свої перші думки. Яку першу частину програми ви плануєте написати? Що це потрібно ? Можливо, навіть не думайте, з яких об’єктів почати, натомість думайте, які функції та плануйте звідти.

Якщо ваша проблема полягає в тому, що ви не впевнені у своїх навичках документування / проектування / UML , практикуйте, документуючи існуючий проект.

Особисто я рекомендую не турбуватися про те, щоб ваші проекти були ідеально орієнтованими на об'єкти, більшість систем не є 100% об'єктно-орієнтованими. Мета - створити краще розуміння та візуалізацію системи, а не ідеальну абстракцію. Об'єктно-орієнтована не срібна куля, це просто ще один інструмент на поясі.


Я також хотів зазначити відповідь, хоча трохи поза темою для відповіді ... Ваші плани не повинні бути дуже великими! Іноді план - це лише питання "я хочу його запустити, і він робить щось". Це досить добре, якщо це дійсно все, що потрібно робити.
Erdrik Ironrose

2

OOAD - утопія. Маючи на увазі, я не маю на увазі, що це найкращий підхід, я маю на увазі, що він ніколи не є справді досяжним на мою скромну думку. З мого досвіду, щось завжди змінюється, будь то вимоги чи специфіка, або навіть конфлікт залежності, який змушує вас повністю замінити залежність. Чи то тому, що я навчився таким чином, чи тому, що для мене це найбільш природно, мої ідеї щодо дизайну приходять найбільш легко, коли я пишу код. Якщо я збираюся кодувати, і я не маю чіткого уявлення про те, як буду структурувати код, я спершу присвячую час, щоб спочатку зрозуміти проблему, хоча частіше, ніж ні, я бачу необхідність для класу, і я зроблю це.

Моя порада полягає в тому, що найкраще, що ви можете зробити для себе - це використання коду за допомогою фасадів , що забезпечує простий інтерфейс для введення та виводу, і сподіваюся, що входи та виходи не змінюються часто. Хоча навіть якщо вони є, знайте, що це не проблема дизайну настільки, як проблема технічних характеристик (зміна необхідності / експлуатації / функціональності). Це зробить вашу програму дещо стійкішою до проблем, що резонують у вашій програмі, до тих, хто називає вашу програму чи розділ коду, і навпаки.

Що стосується проектування об’єктно-орієнтованої системи, щось слід сказати, намагаючись зробити все об’єктно-орієнтованим, коли цього не повинно бути. Це поширена помилка серед мов програмування OOP, таких як C # і Java, - намагатися ставитися до всього як до об'єкта, що часто призводить до створення одного екземпляра класу для виконання того, що в іншому випадку було б статичним методом, який ні в якому разі не змінює стан. З цього приводу, звичайно, ви повинні використовувати OOP-дизайн, де це можливо, хоча не відчуваєте, що ви робите це неправильно, коли ви вважаєте, що природніше писати статичний метод. Це не завжди неправильний інстинкт.

Вам слід розглянути можливість використання класу, коли ви відповідаєте "так" на будь-яке з наступних питань:

  • Чи є у мене група інформації, яка стосується того самого поняття (тобто ім'я, прізвище, адреса)?
  • Чи потрібно мені виконувати операцію, яка вимагає декількох відомостей (тобто calculatePrice(basePrice, quantity, tax))?
  • Чи є у мене інше, якщо з великими кодовими блоками виконуються трохи різні операції з однаковою або подібною інформацією (тобто if(type == "cat") { meow(name); } else if (type == "dog") { bark(name); }==> animal.speak())
  • Чи є у мене існуючий клас, який виконує більш ніж одне конкретне завдання і стає занадто великим?

Через деякий час створити заняття стане другою природою. Не бійтеся їх використовувати, якщо ваш код потрапляє в один із випадків, описаних вище. Я сподіваюся, що це допомагає!


2

Я думаю, що пункти, висловлені Доком Брауном у коментарях, заслуговують набагато більшої наочності, ніж коментар, оскільки він абсолютно правий:

" Тепер я знаю, що це не правильний спосіб створення програмного забезпечення " - хто вам це сказав? Здається, якимось чином ви потрапляєте у популярну пастку вважати, що «дизайн - це те, що ви робите перед кодуванням, можливо, малюючи фантазійні діаграми UML». Щоб вилікувати вас від цієї помилки, рекомендую почати з «Коду як дизайн» Джека Ривза. - Док Браун 21 червня о 5:27

@Laiv: "кодування" є частиною того, що в інших інженерних дисциплінах називається дизайном. У будівництві будинку крок від проектування до кінцевого продукту робиться за допомогою кладки цегли та розчину. У програмуванні цей крок виконує компілятор при перекладі конструкції (= програми) в кінцевий продукт (= виконуваний двійковий файл). І це не нова мудрість. Нарисам Ривза 25 років. - Док Браун 21 червня о 6:39

Ці ж настрої перегукуються і в інших місцях. Розгляньте розмови Глена Вандербурга про "Реальну інженерію програмного забезпечення", а в деякій мірі і його "Ремесло, інженерія та суть програмування" та "Ремесло та програмне забезпечення". Також врахуйте сторінки WhatIsSoftwareDesign та TheSourceCodeIsTheDesign на вікі C2.

Концепція дизайну коду не характерна для будь-якої парадигми. Він може застосовуватися однаково до об'єктно-орієнтованої, функціональної, процедурної, логічної чи будь-чого іншого. Основна ідея однакова - дизайн є самим вихідним кодом. Акт побудови - це процес, за допомогою якого інтерпретатор або компілятор перетворює вихідний код (конструкцію) на корисну річ.

У складній системі, ймовірно, існує деякий рівень архітектурного дизайну - ідентифікація підсистем, компонентів, модулів, служб та виділення вимог до них, перш ніж починати писати код. Ви можете використовувати UML як спосіб створення, документування та допомоги в дискусіях навколо цього архітектурного дизайну. Розглянемо ідею режимів UML, яку обговорює Мартін Фаулер , зокрема UML як ескіз, а UML як нотатки . Також розглянемо деякі ідеї Agile Modelling - Модель початкової архітектури , Ітераційне моделювання та Просто ледве достатньо моделей .

Все це означає, що правильний спосіб створення програмного забезпечення - це не конкретизувати весь проект. Потрібно витратити достатньо часу на розуміння найважливіших (на даний момент часу) вимог, виявлення технічних залежностей і компромісів між вимогами, а потім скористатися тим, що програмне забезпечення є м'яким. Також визнайте, що вартість прийняття вашого дизайну та виготовлення чогось неймовірно низька (особливо порівняно з розробкою дизайну та виготовленням чогось у багатьох інших інженерних дисциплінах). Тож повторіть свої дизайнерські (кодування) дії та скористайтеся тим, наскільки просто та дешево можна прогресивно будувати чи змінювати те, що ви зробили.


1

OOAD - це визначення ідентичності та моделювання об'єктів чи концепцій реального життя до певної міри абстрагування. Ви сприймете це як простіше, якщо замість того, щоб писати курси йої інтерфейсів для запису спочатку, оскільки вам ще не потрібно їх реалізовувати, але код складається.

OOAD не виключає можливості мислення в системі як великих модулів. Ви все ще можете це зробити. Кожен модуль існує для задоволення набору історій користувача (випадки використання). Такі історії користувачів потребують занять, які співпрацюють для їх виконання.

Однією з ключових відмінностей між процедурними підходами OO є те, що зазвичай процедурне мислення відображає вимоги до екранів, тоді як OOD має тенденцію думати про те, що відбувається під кришкою, залишаючи передню частину, щоб зробити іншою особою або не в рамках OO.

Існує техніка в екстремальному програмуванні, яка називається картками CRC . CRC розшифровується як "клас-обов'язки-співробітники".

В основному ви визначаєте очевидні класи та присвоюєте карту кожному. Скажімо, у класу Invoiceє своя картка.

Для кожного класу зберігання карт ви пишете, якою була б відповідальність цього класу, наприклад, "обчислює велику суму" .

Крім того, для кожного класу, який тримає картки, ви пишете, які ще класи цього класу повинні запитати, щоб виконати власні обов'язки. Тут ви можете виявити Invoiceпотреби співпраці InvoiceDetailабо навіть виявити, що такий клас потрібен в першу чергу.

Ви можете виявити, що деякі відповідальності, до яких ви думали, належать Invoce, дійсно належать одному з його співробітників.

Після вправи кожна картка стає класом, кожна відповідальність стає методом, і будь-які відносини співпраці можуть стати композицією, узгодженням або просто закликом.

Ці вправи можна (і слід) робити в групі, де беруть участь навіть ділові люди.

Ви можете дізнатися більше про цю техніку за посиланнями:

http://en.wikipedia.org/wiki/Class-responsibility-collaboration_card

http://www.extremeprogramming.org/rules/crccards.html

Приклади карток CRC:

введіть тут опис зображення

введіть тут опис зображення

введіть тут опис зображення


0

Основний виклик для нас, як спільноти практиків програмного забезпечення; Більш конкретно об'єктно-орієнтованими практиками дизайну є те, щоб перетворити всі наші проблеми / завдання в програмування. Будь завдання - представлені у вигляді функцій, чи то учасники завдань - представлені як інтерфейси / класи [рух у напрямку до OOAD]. Коли ми розвиваємо свої навички проектування програмного забезпечення, постійно отримуючи знання про різні методології / рамки. Наша точка зору стає все більш вдосконаленою до чіткої сегрегації об'єктів і того, який об’єкт буде виконувати, яку функцію.

Що стосується розбиття ваших проблем на підпроблеми з наявністю об'єктів навколо, ви все ще можете це зробити зручно, оскільки ВИ маєте повний контроль над усіма об'єктами, які ви хочете бути присутніми. Ви також маєте зручність передавати природу та призначення своїм об'єктам та інтерфейсам. Все, що вам потрібно зробити, це візуалізувати постановку проблеми і продумати, яка мета / функціональність може бути надана якому об’єкту.

Я спробую пояснити далі за допомогою прикладу асортименту автомобілів, і виділю два різні способи візуалізації однієї і тієї ж об'єктної моделі.

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

Щоб виробник чітко мав відокремлення категорії і призначення, існує кілька способів, за допомогою яких вони можуть створювати там класи.

Виробник транспортних засобів OOAD

  1. Виходячи з категорії (ринковий сектор) транспортного засобу: важкий транспортний засіб, легковий транспортний засіб [седан, хетчбек, універсал тощо]

  2. Виходячи з об'єму двигуна та способу руху: 800-1500 CC,> 1500 CC тощо

Ідучи найкращим способом, за яким виробник може індивідуально надавати функції об’єктам, що належать до кожної з цих класифікацій, вони можуть вибрати відповідний базовий дизайн об'єкта та побудувати там модель над ним.


Ви починаєте нормально, але тоді останній біт виглядає як помилковість, що OOD стосується категоризації речей, а не групування подібних форм поведінки.
Піт Кіркхем
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.