Jak projektujesz projekty obiektowe? [Zamknięte]


231

Pracuję nad dużym projektem (dla mnie), który będzie miał wiele klas i będzie musiał być rozszerzalny, ale nie jestem pewien, jak zaplanować mój program i jak klasy muszą ze sobą współdziałać.

Wziąłem kurs OOD kilka semestrów wstecz i wiele się z niego nauczyłem; jak pisanie UML i tłumaczenie dokumentów wymagań na obiekty i klasy. Nauczyliśmy się również schematów sekwencji, ale jakoś przegapiłem wykład lub coś takiego, tak naprawdę nie trzymały się mnie.

W poprzednich projektach próbowałem używać metod, których nauczyłem się na kursie, ale zwykle kończy się to kodem, który, gdy tylko mogę powiedzieć „tak, wygląda to tak, jak miałem na myśli”, nie chcę przekopywać błota, aby dodać Nowe funkcje.

Mam kopię kodu Complete Steve'a McConnella, który ciągle słyszę, że jest niesamowity, tu i gdzie indziej. Przeczytałam rozdział o projektowaniu i nie wydawałam się, aby uzyskać informacje, których szukam. Wiem, że mówi, że to nie jest wycięty i wysuszony proces, że opiera się on głównie na heurystyce, ale nie mogę wziąć wszystkich jego informacji i zastosować ich do moich projektów.

Więc co robisz podczas fazy projektowania na wysokim poziomie (zanim zaczniesz programować), aby określić, jakich klas potrzebujesz (zwłaszcza tych, które nie są oparte na „prawdziwych obiektach”) i jak będą ze sobą współdziałać ?

W szczególności jestem zainteresowany, jakich metod używasz? Jakim procesem się kierujesz, który zwykle tworzy dobry, czysty projekt, który będzie ściśle reprezentował produkt końcowy?


2
Myślałem, że Code Complete był bardzo pomocny w tym temacie - szczególnie rozdziały 5.3 i 5.4 (które mają bardziej konkretne sugestie) oraz cały rozdział 6. Jednak tak naprawdę nie opracowałem żadnego projektu kodu dla dużego projektu.
Paul D. Waite,

1
Mogę polecić udział w kursie projektowania obiektowego w Javie. Jest doskonały jeden opublikowany na UDEMY udemy.com/mastering-object-oriented-design-in-java/... . Myślę, że to z pewnością może ci pomóc. Innym doskonałym zasobem jest wypróbowanie problemu obiektowego ATM. Możesz to zrobić w Google.
Horse Voice

Polecam wszystkim, aby wrócili do tego pytania podczas projektowania. Tutaj jest dużo treści. W ten sposób możesz pobudzić pamięć podczas projektowania.
Kevin Wheeler,

Odpowiedzi:


199

Kroki, których używam do wstępnego projektowania (przejście do diagramu klas), to:

  1. Zbieranie wymagań. Porozmawiaj z klientem i rozróżnij przypadki użycia, aby określić, jaką funkcjonalność powinno mieć oprogramowanie.

  2. Skomponuj opis poszczególnych przypadków użycia.

  3. Przejrzyj narrację i zaznacz rzeczowniki (osoba, miejsce, rzecz), jako klasy kandydujące i czasowniki (działania), jako metody / zachowania.

  4. Odrzuć zduplikowane rzeczowniki i wyróżnij wspólną funkcjonalność.

  5. Utwórz diagram klas. Jeśli jesteś programistą Java, NetBeans 6.7 firmy Sun ma moduł UML, który pozwala na tworzenie diagramów oraz inżynierii w obie strony i jest BEZPŁATNY. Eclipse (środowisko Java IDE typu open source) również ma strukturę modelowania, ale nie mam z tym doświadczenia. Możesz także wypróbować ArgoUML, narzędzie typu open source.

  6. Zastosuj zasady OOD, aby zorganizować swoje zajęcia (wyróżnij wspólną funkcjonalność, buduj hierarchie itp.)


6
Jest to rzeczywiście przydatna technika, zwłaszcza gdy nie masz prawdziwego doświadczenia w dziedzinie problemów. Jednak rzadko tworzy optymalną architekturę.
NomeN

1
Mogę polecić udział w kursie projektowania obiektowego w Javie. Jest doskonały, opublikowany na UDEMY udemy.com/mastering-object-oriented-design-in-java/.... Myślę, że to z pewnością może ci pomóc. Innym doskonałym zasobem jest wypróbowanie problemu obiektowego ATM. Możesz to zrobić w Google.
Horse Voice

1
Gdzie się tego uczysz? Czy możesz podać źródło?
Kanagavelu Sugumar

68

Dodając do tego, co powiedział Scott Davies:

  1. Przed rozpoczęciem upewnij się, że wiesz, o co chodzi w twoim programie. Jaki jest twój program Czego nie zrobi? Jaki problem próbuje rozwiązać?

  2. Twój pierwszy zestaw przypadków użycia nie powinien być listą rzeczy do prania wszystkiego, co program ostatecznie zrobi. Zacznij od najmniejszego zestawu przypadków użycia, które możesz wymyślić, które wciąż oddają istotę tego, do czego służy Twój program. Na przykład w przypadku tej witryny internetowej głównymi przypadkami użycia mogą być logowanie , zadawanie pytań , odpowiadanie na pytania oraz przeglądanie pytań i odpowiedzi . Nic o reputacji, głosowaniu czy wiki społeczności, tylko surowa esencja tego, do czego strzelasz.

  3. Kiedy wymyślisz potencjalne klasy, nie myśl o nich tylko w kategoriach rzeczowników, które reprezentują, ale jakie obowiązki mają na sobie. Odkryłem, że jest to największa pomoc w ustaleniu, w jaki sposób klasy odnoszą się do siebie podczas wykonywania programu. Łatwo jest wymyślić takie relacje, jak „pies to zwierzę” lub „szczeniak ma jedną matkę”. Zwykle trudniej jest znaleźć relacje opisujące interakcje między obiektami w czasie wykonywania. Algorytmy twojego programu są co najmniej tak samo ważne jak twoje obiekty i są znacznie łatwiejsze do zaprojektowania, jeśli określiłeś, jakie jest zadanie każdej klasy.

  4. Po uzyskaniu minimalnego zestawu przypadków użycia i obiektów zacznij kodować. Zdobądź coś, co faktycznie działa tak szybko, jak to możliwe, nawet jeśli nie robi wiele i prawdopodobnie wygląda jak bzdura. To punkt wyjścia i zmusi cię do odpowiedzi na pytania, które możesz przeświecać na papierze.

  5. Teraz wróć i wybierz więcej przypadków użycia, napisz, jak będą działać, zmodyfikuj model swojej klasy i napisz więcej kodu. Podobnie jak w przypadku pierwszego cięcia, bierz tak mało, jak to możliwe, jednocześnie dodając coś znaczącego. Wypłukać i powtórzyć.

Tylko moje dwa centy. Mam nadzieję, że jest to przydatne.


19

Kiedy miałem okazję, zwykle używam tego, co nazywam „regułą trzech iteracji”.

W pierwszej iteracji (lub uruchomieniu) opracowuję ogólny układ aplikacji zgodnie z obiektami modelu, algorytmami i oczekiwanymi ( tak naprawdę oczekiwanymi, może nieoczekiwane) przyszłe kierunki. Nie piszę dokumentów projektowych, ale jeśli muszę koordynować wiele osób, oczywiście potrzebny jest wstępny szkic procedury wraz z analizą zależności i oszacowaniem potrzebnego czasu. Spróbuj ograniczyć tę fazę do minimum, jeśli tak jak ja wolisz bardziej zwinną metodę. Są przypadki, w których potrzebna jest silna faza projektowania, w szczególności gdy wszystko jest znane i prawdziwe w logice twojego programu, i jeśli planujesz mieć wiele interakcji między funkcjami w twoim kodzie. W takim przypadku przypadki użycia lub historie użytkowników są dobrym pomysłem na wysokim poziomie, w szczególności w przypadku aplikacji GUI. W przypadku aplikacji wiersza polecenia, a w szczególności bibliotek, spróbuj napisać „historie programu”, w których piszesz kod do biblioteki, którą musisz opracować, i sprawdź, jak ona wygląda.

Po tej pierwszej iteracji będziesz lepiej rozumieć, w jaki sposób rzeczy wchodzą w interakcje, wydostałeś się ze szczegółów i trudnych miejsc, rozwiązałeś problemy z przyklejoną taśmą klejącą. Możesz skorzystać z tego doświadczenia, aby poprawić, wyczyścić, wypolerować, podzielić to, co było zbyt duże, połączyć to, co było zbyt rozdrobnione, zdefiniować i zastosować wzorce projektowe, analizować wąskie gardła wydajności i nietrywialne problemy bezpieczeństwa. Ogólnie rzecz biorąc, wszystkie te zmiany będą miały ogromny wpływ na napisane testy jednostkowe, ale nie na testy funkcjonalne.

Po zakończeniu tej drugiej iteracji będziesz miał mały klejnot, dobrze przetestowany, dobrze udokumentowany i dobrze zaprojektowany. Teraz masz zarówno doświadczenie, jak i kod do wykonania trzeciej iteracji, rozszerz. Dodaj nowe funkcje i przypadki użycia, aby ulepszyć swoją aplikację. Znajdziesz szorstkie miejsca i ostatecznie wejdziesz w czwartą iterację, analogiczną do drugiej. Wypłukać i powtórzyć.

To jest moje ogólne podejście do projektowania oprogramowania. Jest podobny do projektowania spiralnego, z krótkimi, trzymiesięcznymi iteracjami i elementami rozwoju Agile, który pozwala poznać problemy i poznać swoje oprogramowanie i zakres jego zastosowania. Oczywiście jest to kwestia skalowalności, więc jeśli aplikacja jest tak duża, że ​​angażuje setki programistów, sprawy są nieco bardziej złożone niż to, ale ostatecznie myślę, że pomysł jest zawsze taki sam, divide et impera .

Podsumowując:

  1. W pierwszej iteracji masz przedsmak tego i uczysz się
  2. W drugiej iteracji posprzątasz swój produkt i przygotujesz go na przyszłość
  3. W iteracji trzeciej dodajesz nowe funkcje i dowiadujesz się więcej
  4. Goto 2

16

Najciekawszym źródłem, jakie znam na ten temat, jest część D zorientowanej obiektowo budowy oprogramowania, druga edycja autorstwa Bertranda Meyera.

Część D: Metodologia obiektowa: dobre zastosowanie metody

19: Metodologia, 20: Wzorzec projektowy: interaktywne systemy wielopanelowe, 21: Studium przypadku dziedziczenia: „cofnij” w systemie interaktywnym, 22: Jak znaleźć klasy , 23: Zasady projektowania klas, 24: Dobrze wykorzystując dziedziczenie , 25: Przydatne techniki, 26: Poczucie stylu, 27: Analiza obiektowa, 28: Proces budowy oprogramowania, 29: Nauczanie metody

Co ciekawe, rozdział 22. Jak znaleźć zajęcia jest dostępny online.


12

Jest to często powtarzane, ale całkowicie prawdziwe - zrozum swoje dane.

W przypadku OOP twoje klasy powinny opisywać istotne informacje i ich interakcje.

Jeśli masz model mentalny, który dobrze opisuje zachowanie i czas życia danych, z łatwością zorganizujesz zajęcia.

Jest to po prostu rozszerzenie: Dowiedz się dokładnie, co próbujesz zrobić.


12
Zachowanie obiektu jest ważniejsze niż dane. Jest to bezpośredni wynik enkapsulacji: serce programowania obiektowego. Ujawnienie danych (z języków takich jak C i Pascal) prowadzi do systemów, które są trudne w utrzymaniu (ulepszeniu i debugowaniu) po prostu dlatego, że nigdy nie wiadomo, jakie inne miejsce w systemie zmienia dane. OOP nie dotyczy danych; OOP dotyczy zachowania. To ważne rozróżnienie.
Dave Jarvis

Jest to ważne rozróżnienie, ale nie oznacza to, że zachowanie jest ważniejsze niż dane.
Johnny

W przypadku OOD zwykle zaczynam od zaprojektowania modelu po wyjaśnieniu wymagań, co daje mi podstawowe wyobrażenie o tym, jak należy zorganizować byty i jak relacje między nimi. Jednocześnie mam podstawowe wyobrażenie o tym, że operacje mogą się zdarzyć w każdej jednostce. Po szkicowym zdjęciu modeli możemy przejrzeć wymagania i sprawdzić, czy czegoś brakuje. A wtedy łatwiej będzie wrócić do poziomu klasy i poziomu kontrolera.
Joshua

10

Spróbuj użyć rozwoju opartego na zachowaniu. Trudno będzie przełamać swoje stare nawyki, ale przekonałem się, że BDD jest naprawdę najlepszym rozwiązaniem, jeśli chodzi o rozwój w prawdziwym świecie.

http://behaviour-driven.org/


1
+1 Korzystanie z rozwoju opartego na testach / zachowaniach / domenach pozwala tworzyć klasy w miarę upływu czasu, dzięki czemu unikniesz problematycznej metodologii projektowania dużych wodospadów.
Halvard,

8

Problem z dużymi projektami polega na tym, że nie można nadzorować wszystkich interakcji między komponentami. Ważne jest zatem zmniejszenie złożoności projektu. Diagramy klas i sekwencji są zbyt szczegółowe dla tej fazy projektowania.

Najpierw spróbuj myśleć z wyższego poziomu abstrakcji. Pomyśl o głównych komponentach i ich obowiązkach (ich interfejsie z innymi komponentami), spójrz na niektóre wzorce architektoniczne dla inspiracji (nie, nie wzorce projektowe, to są zbyt niskie poziomy! MVC i wielopoziomowe są przykładami wzorów architektonicznych). W przypadku stosunkowo dużych projektów taki widok powinien zawierać około 3-5 elementów.

Dopiero wtedy przybliżasz określony komponent i próbujesz go zaprojektować. Teraz jesteśmy na poziomie wzorców projektowych i schematów klas. Spróbuj skoncentrować się na tej części projektu, jeśli uznasz, że musisz dodać odpowiedzialność do jednego z pozostałych komponentów, po prostu dodaj go do swojej dokumentacji / listy rzeczy do zrobienia. Nie trać czasu na myślenie o implikacjach, w tym momencie zmieniają się one zbyt szybko, sprawdź, kiedy projekt jest bardziej solidny.

W tym momencie nie musisz w pełni projektować każdego komponentu, chociaż prawdopodobnie rozsądnie jest mieć kawałek kodu, który implementuje interfejs niezaimplementowanych komponentów i generuje proste, ale przydatne odpowiedzi. W ten sposób możesz rozpocząć opracowywanie (i projektowanie) jednego elementu na raz i testowanie go w rozsądnym stopniu.

Oczywiście, kiedy nowe komponenty są gotowe, powinieneś przetestować, w jaki sposób (i czy) integrują się ze sobą przed przejściem dalej.

W skrócie: weź zasadę OO i ukrywanie informacji i podnieś ją na wyższy poziom!


PS: Wykonuj dużo szkicowania podczas projektowania, to jest jak prawdziwa architektura!

PPS: Spróbuj podejść do sprawy z różnych punktów widzenia, nieszablonowo (choć może to być odpowiednia droga), dyskusja z rówieśnikami może być bardzo przydatna w tym ... i masz coś do powiedzenia podczas lunchu.


7

Techniką, którą zastosowałem w prawdziwych projektach z rozsądnym sukcesem, jest projektowanie oparte na odpowiedzialności, zainspirowane książką Wirfsa-Brocka.

Zacznij od historii użytkowników najwyższego poziomu, a wraz z kolegami na tablicy naszkicuj sugerowane przez nich interakcje wysokiego poziomu. To daje ci pierwsze pojęcie o tym, czym są duże moduły; i iteracja lub dwie gry CRC na wysokim poziomie, powinieneś ustabilizować listę głównych komponentów, ich działania i interakcji.

Następnie, jeśli którykolwiek z obowiązków jest duży lub złożony, udoskonalaj te moduły, aż będziesz mieć rzeczy, które są wystarczająco małe i proste, aby być obiektami, odtwarzając interakcje wewnątrz modułu dla każdej z głównych operacji zidentyfikowanych przez interakcje wyższego poziomu .

Wiedza, kiedy przestać, jest kwestią osądu (który przychodzi tylko z doświadczeniem).


+1 za tablicę, wyjątkowa rzecz: DI rozwiązuje 80% problemów siedząc przed tablicą, patrząc na nią i myśląc „co byłoby najlepsze?”
usoban

7

Wzorce projektowe

Wzory projektowe

Singleton - Upewnij się, że tworzona jest tylko jedna instancja klasy i Zapewnij globalny punkt dostępu do obiektu.

Factory (Uproszczona wersja metody Factory) - Tworzy obiekty bez ujawniania logiki tworzenia instancji klientowi i odnosi się do nowo utworzonego obiektu za pośrednictwem wspólnego interfejsu.

Metoda fabryczna - definiuje interfejs do tworzenia obiektów, ale pozwala podklasom decydować, którą klasę utworzyć i odwołuje się do nowo utworzonego obiektu za pośrednictwem wspólnego interfejsu.

Fabryka abstrakcyjna - oferuje interfejs do tworzenia rodziny powiązanych obiektów, bez wyraźnego określania ich klas.

Konstruktor - definiuje instancję do tworzenia obiektu, ale pozwala podklasom decydować, która klasa ma zostać utworzona, i umożliwia lepszą kontrolę nad procesem budowy.

Prototyp - Określ rodzaje obiektów do utworzenia przy użyciu instancji prototypowej i utwórz nowe obiekty, kopiując ten prototyp.

Zachowawcze wzorce projektowe

Łańcuch odpowiedzialności - unika dołączania nadawcy żądania do odbiorcy, dając w ten sposób innym przedmiotom możliwość obsługi żądania. - Obiekty stają się częścią łańcucha, a żądanie jest wysyłane z jednego obiektu do drugiego w całym łańcuchu, dopóki jeden z obiektów nie obsłuży go.

Polecenie - enkapsuluje żądanie w obiekcie, umożliwia parametryzację klientów z różnymi żądaniami i umożliwia zapisywanie żądań w kolejce.

Tłumacz - biorąc pod uwagę język, zdefiniuj reprezentację dla jego gramatyki wraz z tłumaczem, który używa reprezentacji do interpretacji zdań w języku / Mapuj domenę na język, język na gramatykę i gramatykę na hierarchiczny obiektowy projekt

Iterator - umożliwia sekwencyjny dostęp do elementów obiektu agregującego bez ujawniania jego podstawowej reprezentacji.

Mediator - Zdefiniuj obiekt, który określa sposób interakcji zestawu obiektów. Mediator promuje luźne sprzężenie, uniemożliwiając obiektom bezpośrednie odwoływanie się do siebie i pozwala niezależnie zmieniać ich interakcje.

Obserwator - Zdefiniuj zależność jeden-do-wielu między obiektami, aby w przypadku zmiany stanu jednego obiektu wszystkie jego zależności były powiadamiane i aktualizowane automatycznie.

Strategia - Zdefiniuj rodzinę algorytmów, obuduj każdy z nich i uczyń je wymiennymi. Strategia pozwala algorytmowi zmieniać się niezależnie od klientów, którzy go używają.

Metoda szablonów - Zdefiniuj szkielet algorytmu w operacji, odraczając niektóre kroki do podklas / Metoda szablonów pozwala podklasom na nowo zdefiniować pewne kroki algorytmu, nie pozwalając im na zmianę struktury algorytmu.

Gość - reprezentuje operację, która ma zostać wykonana na elementach struktury obiektu / Gość umożliwia zdefiniowanie nowej operacji bez zmiany klas elementów, na których ona działa.

Obiekt zerowy - Podaj obiekt jako surogat dla braku obiektu danego typu. / Wzorzec obiektu zerowego zapewnia inteligentne zachowanie bezczynności, ukrywając szczegóły przed współpracownikami.

Wzory konstrukcyjne

Adapter - Konwertuj interfejs klasy na inny interfejs, którego oczekują klienci. / Adapter pozwala klasom współpracować ze sobą, czego inaczej nie byłoby z powodu niekompatybilnych interfejsów.

Most - Komponuj obiekty w struktury drzewne, aby reprezentowały hierarchie częściowe. / Composite umożliwia klientom jednolite traktowanie poszczególnych obiektów i kompozycji obiektów.

Złożony - Komponuj obiekty w struktury drzewne, aby reprezentowały hierarchie częściowe. / Composite umożliwia klientom jednolite traktowanie poszczególnych obiektów i kompozycji obiektów.

Dekorator - dynamicznie dodawaj dodatkowe obowiązki do obiektu.

Flyweight - użyj współużytkowania, aby obsłużyć dużą liczbę obiektów, które mają wspólną część swojego stanu wewnętrznego, gdzie inna część stanu może się różnić.

Pamiątka - przechwytuj wewnętrzny stan obiektu bez naruszania hermetyzacji, zapewniając w ten sposób sposób na przywrócenie obiektu do stanu początkowego w razie potrzeby.

Proxy - podaj „symbol zastępczy” dla obiektu, aby kontrolować odwołania do niego.


2
Wzory są przydatne dla niektórych osób. Myślę, że potrzeba dużego doświadczenia, aby zobaczyć wzorce w wymaganiach. I prawdopodobnie musisz je udokumentować. Skłaniam się do myślenia, że ​​wzorce są niczym więcej niż abstrakcyjnymi bibliotekami komponentów.
CyberFonic

5

Polecam ci korzystanie z BlueJ, a także ActiveWriter do nauki, a także do dobrego zrozumienia obiektów. Polecana książka to także niezły zasób.

Z Wikipedii :

alternatywny tekst

BlueJ to zintegrowane środowisko programistyczne dla języka programowania Java, opracowane głównie do celów edukacyjnych, ale odpowiednie również do opracowywania oprogramowania na małą skalę.

Dodatkowo używa UML i dla mnie było dobrym zasobem do zrozumienia kilku rzeczy na temat modelowania obiektów.

alt text http://www.ryanknu.com/ryan/bluej.png

ActiveWriter to narzędzie do modelowania encji i relacji, generuje również kod i jest łatwe do wprowadzania zmian. Zaoszczędzi ci czasu, a zwinny rozwój jest bardzo odpowiedni.

alternatywny tekst
(źródło: altinoren.com )


1
użyłem niebieskiego J ... to zdecydowanie przydatne, ale w jaki sposób pomaga mi projektować klasy i ich relacje?
Victor

1
Wydaje mi się, że wyjaśniłem cały obraz tego, jak identyfikować klasy i jak odnosić je wizualnie. W pierwszych krokach eksperymentowałem, w jaki sposób reprezentacja kodowa obiektów i jak rozumieć, jak myśleć w obiektach. Pamiętam, kiedy poświęciłem czas na ustalenie „jest” i „ma”, a UML był doskonałą pomocą. Od tego czasu używam tych narzędzi wizualnych do projektowania moich obiektów, a kiedy odkryłem ActiveWriter, byłem bardzo zadowolony, ponieważ BlueJ nie ma generowania kodu, a to narzędzie ma, tylko w celu wymuszenia mojego argumentu. Myślę, że wizualnie masz szersze podejście do rozwiązania.
Nelson Miranda

4

Przede wszystkim - projekt powinien pochodzić z twojej duszy. Musisz to wyczuć przy każdym włóknie. Zwykle chodzę po nim przez dwa lub trzy miesiące, zanim zacznę cokolwiek robić, po prostu chodzę ulicami (naprawdę). I myślenie. Chodzenie to dobra medytacja. Dzięki temu możesz się dobrze skoncentrować.

Po drugie - używaj OOP i klas tylko tam, gdzie istnieje hierarchia obiektów naturalnych. Nie „wkręcaj” tego w sztuczny sposób. Jeśli nie istnieje ścisła hierarchia (jak w większości aplikacji biznesowych) - przejdź do proceduralnych / funkcjonalnych lub przynajmniej używaj obiektów tylko jako kontenerów danych z izolowanymi akcesoriami.

I ostatni - spróbuj przeczytać to: Algorytm kreatywnego myślenia


4

Wystarczy zacytować http://www.fysh.org/~katie/computing/methodologies.txt

A rdzeniem RUP jest niewielki obszar, w którym musisz wykorzystać talenty projektowe OO ... jeśli ich nie masz, to tak, jakbyś miał metodologię do pokonania 100m.

„Krok 1: napisz o bieganiu naprawdę szybko. Krok 2: Idź i narysuj plan toru wyścigowego. Krok 3: idź i kup naprawdę ciasne spodenki z lycry. Krok 4: biegnij naprawdę, bardzo, bardzo szybko. Krok 5: najpierw przekrocz linię „

To ten trudny krok 4. Ale jeśli położysz duży nacisk na 1,2,3 i 5, możliwe, że nikt tego nie zauważy, a wtedy prawdopodobnie zarobisz dużo pieniędzy, sprzedając metodologię tym sportowcom, którzy uważają, że istnieje „sekret” bycia 100 m biegacz


4

Zadałeś pytanie, którego wielu autorów używa do napisania książki. Istnieje wiele metodologii i powinieneś wybrać taką, która wydaje ci się „najładniejsza”.
Mogę polecić książkę Erica Evansa „Domain Driven Design” . Sprawdź także witrynę dddcommunity.org .


3

Myślę, że odpowiedź tutaj powinna być bardzo różna w zależności od rzeczywistych doświadczeń pytającego faceta.

Jeśli masz tylko rok lub dwa lata doświadczenia zawodowego, musisz przejść do tego, co następuje: jak dojść do tego, że naprawdę znasz swoje dane i dokładnie rozumiesz, co próbujesz zrobić?

Tak, jeśli pracujesz w prawdziwym świecie od ponad 5 lat, wybierzesz jeden z wielu modeli lub technik procesów tworzenia oprogramowania.

Ale nie zyskujesz doświadczenia, czytając tylko książki. Powinieneś się uczyć, pracując w dobrej grupie pod dobrym przywództwem.

Jeśli nie jest to możliwe, powinieneś zrobić to sam. Rozpocznij iterację od kodowania prawdopodobnie bardzo nieprzyjemnego fragmentu kodu, uczenia się błędów, zrzucania wszystkiego, kodowania lepszego i tak dalej.

Dowiesz się wiele o swojej bazie kodu. Narzędzia są narzędziami, niczego cię nie nauczą.


3

Jeśli masz specjalistyczną wiedzę na temat projektu, nad którym będziesz pracować, powiedzmy bankowość. Łatwo jest uporządkować obiekty i wiesz, jak te ulepszenia pojawiają się co drugi dzień.

Jeśli nie masz takiej wiedzy, pracuj z kimś, kto ma taką wiedzę i przekonwertuj te pomysły na szczegóły techniczne.

Jeśli masz wątpliwości co do struktury projektu swojego projektu. ŚWIECIE postępuj zgodnie z książką „pragmatyczny programista”. Byłem wcześniej w takiej samej sytuacji, spróbuj przeczytać rozdział z tej książki. zobaczysz różnicę, zmieni to sposób myślenia jako programista.


2
  1. studiuj i opanuj wzorce projektowe.
  2. Następnie dowiedz się o projekcie opartym na domenie
  3. Następnie naucz się zbierania wymagań

Wziąłem kurs OOD kilka semestrów wstecz i wiele się z niego nauczyłem; jak pisanie UML i tłumaczenie dokumentów wymagań na obiekty i klasy. Nauczyliśmy się również schematów sekwencji, ale jakoś przegapiłem wykład lub coś takiego, tak naprawdę nie trzymały się mnie.

  1. Wiesz o kroku 3. Musisz go opanować. Mam na myśli wiele praktyk, aby stała się twoją drugą naturą. To dlatego, że metoda, której się uczysz, jest po prostu sprzeczna z naszą poprzednią. Musisz więc naprawdę go opanować. W przeciwnym razie zawsze będziesz wracał do swojego pierwotnego sposobu robienia rzeczy. Jest to w pewien sposób podobne do Test Driven Process, w którym wielu programistów Java rezygnuje z tego po kilku próbach. Chyba że w pełni go opanują, w przeciwnym razie będzie to dla nich tylko ciężar

  2. Napisz przypadki użycia, szczególnie dla kursu alternatywnego. Kurs alternatywny zajmuje ponad 50% naszego czasu rozwoju. Zwykle, gdy twój PM przydzieli Ci zadanie, na przykład stwórz system logowania, pomyśli, że to proste, możesz zająć 1 dzień, aby go zakończyć. Ale nigdy nie bierze pod uwagę, że należy wziąć pod uwagę: 1. co jeśli użytkownik wprowadzi błędne hasło, 2. co jeśli użytkownik wprowadzi błędne hasło 3 razy, 3. co jeśli użytkownik nie wpisze nazwy użytkownika itp. Musisz je wymienić i pokazać swojemu PMowi, poprosić go o przesunięcie terminu.


2

Obawiam się, że ludzie nie lubią takich odpowiedzi . W każdym razie pozwól mi wyrazić swoją opinię.

OOP należy postrzegać jako jeden z paradygmatów, a nie jako nadrzędny paradygmat. OOP jest dobry do rozwiązywania określonych problemów, takich jak tworzenie biblioteki GUI. Pasuje również do stylu tworzenia oprogramowania, za którym zwykle podążają duże firmy programistyczne - elitarny zespół projektantów lub architektów określa projektowanie oprogramowania w diagramach UML lub innym podobnym medium i mniej oświecony zespół programistówprzetłumacz ten projekt na kod źródłowy. OOP oferuje niewiele korzyści, jeśli pracujesz sam lub z małym zespołem wysoce utalentowanych programistów. Następnie lepiej jest użyć języka, który obsługuje wiele paradygmatów i pomoże szybko wymyślić prototyp. Python, Ruby, Lisp / Scheme itp. Są dobrym wyborem. Prototyp to twój projekt. Potem poprawiasz to. Użyj paradygmatu, który najlepiej rozwiązać dany problem. W razie potrzeby zoptymalizuj hotspoty za pomocą rozszerzeń napisanych w C lub w innym języku systemowym. Korzystając z jednego z tych języków, zyskujesz także rozszerzalnośćza darmo, nie tylko na poziomie programisty, ale także na poziomie użytkownika. Języki takie jak Lisp mogą dynamicznie generować i wykonywać kod, co oznacza, że ​​użytkownicy mogą rozszerzyć aplikację, pisząc małe fragmenty kodu w języku, w którym jest zakodowane samo oprogramowanie! Lub jeśli zdecydujesz się napisać program w C lub C ++, rozważ osadzenie interpretera dla małego języka, takiego jak Lua. Ujawnij funkcje jako wtyczki napisane w tym języku.

Myślę, że przez większość czasu OOP i OOD tworzą oprogramowanie, które jest ofiarą nadmiernego projektowania.

Podsumowując, moim preferowanym sposobem pisania oprogramowania jest:

  1. Użyj dynamicznego języka.
  2. Napisz projekt (prototyp) w tym języku.
  3. W razie potrzeby zoptymalizuj niektóre obszary za pomocą C / C ++.
  4. Zapewniają rozszerzalność za pomocą interpretera samego języka implementacji.

Ostatnia funkcja umożliwia łatwe dostosowanie oprogramowania do konkretnych wymagań użytkownika (w tym mnie!).


Nie jest to
zalecane,

2
Stosuję podobne podejście. Aby uniknąć przytłoczenia złożonością, zacznij od widoku helikoptera. Lubię szkic z 8-20 funkcjami. Jeśli zacznę dostawać więcej, przyjrzę się, jak partycjonować w podsystemy. Kiedy już zobaczę ten widok wysokiego poziomu, rozłożę każdą funkcję na 8-20 podfunkcji itp. Patrząc na to, jak manipulują te funkcje, otrzymuję klasy najwyższego poziomu. Wtedy zacząłem układać układ szkieletowy w Pythonie, czyli pseudo-kod wykonywalny. To wraz z blokami komentarzy jest moją „specyfikacją wykonywalną”, która następnie jest stopniowo dopracowywana.
CyberFonic

2

Używam Test-Driven Design (TDD). Najpierw napisanie testu pomaga stworzyć projekt, który jest czysty i poprawny. Zobacz http://en.wikipedia.org/wiki/Test-driven_development .


2
TDD pomaga początkowo wizualizować system jako czarną skrzynkę z przykładowymi danymi wejściowymi i wyjściowymi. Ale samo w sobie nie pomaga ci wymyślić projektu systemu. Miałem na myśli test jednostkowy, w którym najpierw musisz wymyślić interfejs klasy
Vicente Bolea

2

Naucz się wzorców projektowych . To była moja osobista rewolucja w ciągu ostatnich dwóch lat w zakresie OOP. Zdobądź książkę. Poleciłbym ci ten:

Head First Design Patterns

Jest w Javie, ale można go rozszerzyć na dowolny język.


1

Szczerze mówiąc, dobrym krokiem byłoby cofnięcie się i spojrzenie na schematy blokowe i schematy sekwencji. Istnieje mnóstwo dobrych witryn, które pokazują, jak to zrobić. Uważam, że jest to bezcenne, gdy patrzę na to, jak chcę rozbić program na klasy, ponieważ dokładnie wiem, co program wymaga wprowadzania, obliczania i generowania, a każdy krok można podzielić na jedną część programu.


1
Lubię schematy blokowe, kiedy utknąłem na problem. Czasami pomaga mi myśleć o problemie w inny sposób.
user133018,

Zamiast lub podobnie jak schematy blokowe , „Diagramy przepływu danych” (DFD) mają znacznie wyższy poziom: bardziej przypominają schemat wdrażania UML i są odpowiednie do uzyskiwania wglądu w funkcjonalność systemu (tj. Wprowadzanie danych i wyjście danych, wewnętrzne i zewnętrzne przechowywanie danych oraz przetwarzanie danych) i architektura. Schematy blokowe mają (IMHO) zakres bliższy modelowaniu pojedynczej funkcji za pomocą instrukcji if-then-else.
ChrisW,

Tak, używam obu przez większość czasu, zwykle wykresy przepływu są przede wszystkim, gdy próbuję znaleźć jakiś konkretny problem.
user133018,

Korzystanie z linii pływackich rozwiązuje wiele problemów z schematami blokowymi. Przekonałem się, że użycie jednego schematu sekwencji na scenariusz działa najlepiej. Każdy scenariusz obejmuje jedną określoną ścieżkę przez drzewo decyzyjne, więc w przepływie nie ma żadnych IF. Jeśli chcesz mieć jeden schemat z całym przepływem, musisz uwzględnić punkty decyzyjne, ale szybko się zaśmieca, szczególnie jeśli chcesz uwzględnić przypisanie odpowiedzialności.
Kelly S. French


1

Jedną przydatną techniką jest powiązanie unikalnego opisu problemu z czymś, co można znaleźć w prawdziwym świecie. Na przykład modelujesz złożony system opieki zdrowotnej, który szturmem podbije świat. Czy są jakieś przykłady, na które możesz z łatwością przywołać model?

W rzeczy samej. Obserwuj, jak działałaby boczna apteka lub gabinet lekarski.

Sprowadzaj problem z domeną do czegoś, co jest dla ciebie zrozumiałe; coś, do czego możesz się odnosić.

Następnie, gdy „gracze” w domenie zaczną wydawać się oczywiste i zaczniesz modelować swój kod, wybierz modelowanie „dostawca-konsument”, tzn. Twój kod jest „dostawcą” modelu, a Ty jesteś „konsumentem” „.

Powiązanie z domeną i zrozumienie jej na wysokim poziomie jest kluczową częścią każdego projektu.


1

Podczas moich przygód związanych z projektowaniem struktur klas zauważyłem, że bardzo pomocne jest rozpoczęcie pisania pseudokodu. To znaczy: zaczynam od „pisania” ogólnych fragmentów kodu aplikacji na najwyższym poziomie, bawię się nim i odkrywam elementy, które się pojawiają - w rzeczywistości elementy, które ja - jako programista - chciałbym używać. To bardzo dobry punkt wyjścia do projektowania ogólnej struktury modułów i ich interakcji. Po kilku iteracjach cała struktura zaczyna przypominać pełny system klas. Jest to bardzo elastyczny sposób projektowania części kodu. Można to nazwać projektowaniem zorientowanym na programistę.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.