Jak przestać marnować czas na projektowanie architektury [zamknięte]


53

Niedawno ukończyłem uniwersytet i rozpocząłem pracę jako programista. Trudno mi rozwiązać problemy „techniczne” lub debugować za pomocą rzeczy, które, jak powiedziałbym, mają jedno rozwiązanie.

Ale wydaje się, że istnieje klasa problemów, które nie mają jednego oczywistego rozwiązania - takich jak architektura oprogramowania. Te rzeczy wprawiają mnie w osłupienie i przysparzają mi wielkiego cierpienia.

Spędzam wiele godzin, próbując zdecydować, jak „zaprojektować” moje programy i systemy. Na przykład - czy podzielę tę logikę na 1 lub 2 klasy, jak mam nazwać klasy, czy powinienem to uczynić prywatnym czy publicznym, itp. Tego rodzaju pytania zajmują mi dużo czasu i to mnie bardzo frustruje. Chcę tylko stworzyć program - niech to będzie architektura.

Jak mogę szybciej przejść przez fazę architektury i przejść do fazy kodowania i debugowania, którą lubię?


61
Robiąc o wiele więcej. Dowiesz się, co działa, a co nie. Zauważ, że postawienie pytania tutaj jest zgodne z tym samym trendem dyskusji bez kontekstu rzeczywistego kodu: czas, który można poświęcić na naukę. Debata na ten temat jest zabawna, a niektóre wzorce są obiektywnie lepsze niż inne, ale naprawdę bardzo trudno jest mieć sensowną opinię bez doświadczenia (czytaj: blizny).
Jared Smith

5
Architektura jest fazą planowania - zrób to dobrze, a 90% twojego wysiłku, a reszta to kodowanie, debugowanie i akceptacja użytkownika. Pomijanie go lub gwałtowny To jest nie zalecane, ponieważ może się to skończyć z unmaintainable, unextendable rozwiązań, więc jeśli nie lubisz to robić wtedy prawdopodobnie trzeba kogoś robi to dla ciebie innego ... Naming jest jednym z najtrudniejszych problemów w programista, programista może agonować przez kilka dni w oparciu o nazwę metody 5-liniowej. Uczyń wszystko prywatnym, aż będzie musiało być czymś innym. Podziel klasy, gdy robią więcej niż jedną rzecz.
Moo

5
w przypadku OOP możesz zacząć od zrozumienia i zastosowania zasad SOLID . Powinno to pomóc w udzieleniu odpowiedzi na niektóre pytania (np. Czy powinno to być prywatne czy publiczne, podzielenie czy nie podzielenie logiki ...), podając uzasadnienie podjętych decyzji.
njzk2

8
Uważam, że pytanie nie jest tak dobre, jak sugeruje jego wynik. Pytanie pozbawione jest kontekstu . Mówi także coś o tym, jak programowanie jest (być może) źle nauczane. Informatyki nie należy uczyć w sposób sparaliżowany przez początkujących do kodu.
Basile Starynkevitch

3
„Tygodnie kodowania mogą zaoszczędzić wiele godzin planowania”.
mickeyf

Odpowiedzi:


59

Idealny jest wrogiem dobra.

To powiedziawszy, nie powinieneś skracać kątów. Projektowanie oprogramowania będzie miało długotrwały wpływ i pozwoli zaoszczędzić tobie (i rówieśnikom) mnóstwo czasu i wysiłku w przyszłości. Prawidłowe potrwa dłużej. Większość czasu spędzanego na programowaniu nie polega na wbijaniu w klawiaturę, ale przez tablicę wymyślającą, jak rozwiązać problem.

Ale nie powinieneś również martwić się o doskonałość. Jeśli dwa projekty walczą o impas, oznacza to, że prawdopodobnie mają taką samą dobroć. Po prostu idź z jednym. To nie tak, że nie możesz zmienić rzeczy, gdy odkryjesz wady tego projektu.

(Mam nadzieję, że to również pomoże, gdy dowiesz się, że nie ma tylko jednego sposobu debugowania / rozwiązywania problemów technicznych.)


25
Przychodzi mi na myśl paraliż analizowany.
mike65535

7
Czasami idealnym ostatecznym arbitrem dla decyzji projektowej jest jedna czwarta.
candied_orange

11
YAGNI i KISS i GTFO;)
JollyJoker

10
Dla każdego, kto czyta tę odpowiedź - Na miłość boską nie używaj słowa „Idealny jest wrogiem dobra”, aby usprawiedliwić słabe realizacje. Celem tego powiedzenia jest zapobieżenie nadmiernej inżynierii, a nie zwolnienie i stworzenie jakiegoś źle zaprojektowanego bałaganu, takiego jak Windows Vista lub Apple III.
T. Sar - Przywróć Monikę

@ T.Sar: awaria Visty była praktycznie 0% awarii technicznych i około 100% awarii MBA.
whatsisname

39

W przypadku prostych i małych programów (np. Z mniej niż dziesięcioma tysiącami wierszy kodu źródłowego) możesz je zaprojektować podczas pisania kodu. Jeśli zastosujesz iteracyjne i przyrostowe podejście programistyczne , będziesz stopniowo podejmować decyzje architektoniczne: więc napisz kilkadziesiąt wierszy kodu (dodając jedną pojedynczą funkcję mikro), ulepszaj je, aż nie pojawią się żadne ostrzeżenia z twojego kompilatora, przetestuj to w twój debugger i powtórz.

czy podzielę tę logikę na 1 lub 2 klasy, jak nazwać klasy, czy powinienem to uczynić prywatnym czy publicznym itp. Tego rodzaju pytania zajmują mi dużo czasu

Oni nie powinni. I nie mają one większego znaczenia dla małego programu (ponieważ małe, proste programy łatwiej jest ulepszyć, np. Zmienić nazwy itp.). Musisz tylko zachować spójność i nadać priorytet czytelności kodu źródłowego. Od czasu do czasu możesz potrzebować nieco refaktoryzować niektóre małe części swojego programu (i to nie jest wielka sprawa).

Porównaj to z wieloma projektami wolnego oprogramowania (nawet dużymi, takimi jak jądro Linuksa). Deweloperzy nie poświęcili znacznego wysiłku na „architekturę” na wczesnych etapach. UML prawie nigdy nie jest używany w wolnym oprogramowaniu . Ponadto sporo się nauczysz, studiując kod źródłowy kilku projektów wolnego oprogramowania.

Jako nowicjusz albo będziesz pracować nad dużym projektem oprogramowania w zespole, w którym możesz po prostu zaufać starszemu programistowi (który podejmuje decyzje architektoniczne), albo będziesz pracować sam nad małymi projektami (zwykle mniej niż kilkadziesiąt tysięcy wiersze kodu źródłowego). W tym drugim przypadku podejmujesz stopniowe decyzje architektoniczne, od czasu do czasu zmieniając aplikację, po czym „projekt architektoniczny” ewoluuje naturalnie.

Jak mogę szybciej przejść przez fazę architektury i przejść do fazy kodowania i debugowania, co mi się podoba?

W przypadku małych projektów oprogramowania, które wymagają mniej niż roku pracy, bardzo łatwo: nie rób architektury. Poświęć około pół godziny na burzę mózgów nad ogólnym projektem. Następnie zacznij pisać kod, stosując iteracyjne i przyrostowe podejście programistyczne : napisz kilkadziesiąt wierszy, skompiluj go (z włączonymi wszystkimi ostrzeżeniami i informacjami debugowania, np. Za g++ -Wall -Wextra -gpomocą GCC dla C ++), dopóki nie otrzymasz ostrzeżeń (i przekaż go w prostym statycznym źródle analizator kodu, jeśli go masz, np. analizator clang ), przetestuj ten kod za pomocą debugera , zatwierdz go do kontroli wersji (np. git), przepłucz i powtórz. Pamiętaj jednak, aby uniknąć długu technicznego: gdy coś brzydko pachnie, wykonuj pracę (przez refaktoryzację i ponowną implementację), aby to poprawić.

Z drugiej strony w środowisku zespołowym praca nad architekturą wymaga wstępnej dyskusji w celu zdefiniowania odpowiedzialności każdego członka zespołu. Dyskusję tę prowadzi starszy programista (który nie jest nowicjuszem). Przeczytaj o zwinnym tworzeniu oprogramowania i The Mythical Man-Month .

Chcę tylko stworzyć program, niech będzie architektura.

Doskonała intuicja (przynajmniej w przypadku małych projektów). Pomyśl więc kilka minut o swoim programie i zacznij go kodować za pomocą iteracyjnego i przyrostowego podejścia programistycznego : koduj kilkadziesiąt linii i upewnij się, że działają dobrze, a następnie powtórz. Wcześniej zapoznaj się z kodem źródłowym (i obserwuj architekturę) podobnych projektów wolnego oprogramowania, a bardziej ogólnie zrób prace bibliograficzne i badania.

W niektórych przypadkach pomyśl o metaprogramowaniu : są sytuacje, w których chciałbyś wygenerować jakiś „plik źródłowy” (przykłady obejmują użycie generatorów parsera, takich jak bizon , generatorów kodów kleju, takich jak SWIG , Google protobuf , a czasami możesz chcieć napisać prosty skrypt - lub użyj ogólnego preprocesora, takiego jak GPP - aby wyemitować część kodu C ++ lub Java, aby uniknąć powtarzalnego kodowania).

PS. Jestem inżynierem badawczym, mam doktorat z informatyki i 40-letnie doświadczenie, i nigdy nie „architektura”, jak sugeruje twoje pytanie, pracując z powodzeniem nad kilkoma średnimi projektami i kilkoma dużymi (sam kompilator GCC ). Dla mnie „architektura” jest tylko fazą planowania pracy w ciągu najbliższych kilku dni lub tygodni (i zwykle robię to podczas snu lub snu, a na pewno bez komputera i zwykle nawet bez ołówka). Pisząc granty badawcze , w jakiś sposób i w niepełny sposób projektuję architekturę.

Uwaga: niektóre projekty oprogramowania wymagają znacznie więcej architektury niż inne. Na przykład, jeśli napiszesz system sterowania sztucznego serca lub robota neurochirurgicznego, nie będziesz pracować w taki sam sposób, jak podczas pisania przeciętnej aplikacji na telefon komórkowy. Zobacz także stronę Naucz się programowania w Norvig za dziesięć lat .


1
Tak też zwykle do mnie przychodzi. Daję wystarczająco dużo czasu przed uruchomieniem programu i zanim zacznę, będę miał kilka jasnych pomysłów na to, jak chcę go ustrukturyzować, i tak naprawdę nie miałem sensu siedzieć i myśleć o tym. To po prostu naturalnie przepływa do kogoś, kto regularnie rozwiązuje takie problemy.
Neil

1
Biorąc pod uwagę kod źródłowy GCC, całkowicie organiczny wzrost zazwyczaj nie jest czymś, z czego ludzie z przyszłości będą wdzięczni. Większość wkładów GCC, które widziałem, to szczególnie rażące przypadki „zmuszenia mnie do działania i ucieczki stąd tak szybko, jak to możliwe”, ponieważ reszta już taka jest.
Kafein

1
Twierdzę, że każda wystarczająco duża baza kodu rośnie organicznie (patrz prawo Galla ...). Również głupotą byłoby obsłużyć architekturę wielkiego projektu oprogramowania dla początkującego
Basile Starynkevitch

Jestem w zespole, który jest gdzieś pomiędzy dwoma rozmiarami, które opisałeś w pierwszej połowie twojej odpowiedzi. Nasz projekt ma ponad dziesięć tysięcy linii, ale nie jest wystarczająco duży, aby wymagać od niego więcej niż pół tuzina programistów pracujących na pełnym etacie. Jesteśmy w sytuacji, w której jesteśmy na tyle duże, że musimy dokładnie zaplanować naszą architekturę, ale na tyle małe, że wszyscy musimy sami podejmować decyzje architektoniczne. Twoja rada, by albo rosnąć organicznie, albo poprosić starszego programistę, nie zadziałałaby specjalnie dla mojego zespołu. (Ale wydaje mi się, że moja sytuacja też jest trochę rzadka.)
Kevin - Przywróć Monikę

9

Są trzy motta, o których lubię pamiętać.

  • „Wszystko powinno być tak proste, jak to możliwe, ale nie prostsze”

    Na przykład „jedna klasa czy dwie?”, Zapytałbym: „które jest prostsze rozwiązanie?”

  • „Bez oczywistych błędów” kontra „Oczywiście bez błędów”

    Ten drugi jest lepszy!

    I to jest powód, dla którego musi być prosty, tzn. Abyś mógł o tym myśleć. Jedna duża klasa może być (lub może stać się) zbyt duża i zbyt skomplikowana, aby ją uzasadnić, w którym to przypadku podzielisz ją na kilka mniejszych klas, w których możesz powiedzieć: „Każda klasa jest mała i robi to, co mówi, że zrobi - a ich interfejsy są proste i łączą się we właściwy sposób ”.

    1. Kod powinien działać w teorii (tj. W twojej głowie).
    2. Następnie, jeśli to nie działa w praktyce, możesz go debugować, dopóki praktyka nie pasuje do teorii.

    Nowicjusz czasami nie przejmuje się krokiem 1, tj. Uruchomieniem go w głowie (np. Ponieważ jest to zbyt skomplikowane) - ale w takim przypadku działa tylko „przypadkowo”, a nie „teoretycznie”, być może dlatego, że nie ma „ przetestowałem go wystarczająco, aby znaleźć nieoczywiste błędy.

  • Prawo Galla

    Jest to inaczej „refaktor”.

    W praktyce oznacza to:

    1. Zacznij od [nowego] prostego systemu, który działa
    2. Teraz nadszedł czas, aby dodać nową funkcję
    3. Przebuduj istniejący system, aby (tj. Do) nowa funkcja była łatwa do dodania
    4. Dodaj nową funkcję

    5. ... i powtórz jak wyżej

    To pasuje do motta, takiego jak YAGNI, tzn. Nie zmieniaj faktury (martw się o architekturę), zanim będziesz musiał ... ale stwórz odpowiednią architekturę w odpowiednim czasie, tj. Kiedy potrzebujesz jej do określonego celu.


6

Możesz zacząć od minimalnej liczby potrzebnych abstrakcji. Na przykład klasa Person w jednym pliku. Teraz, gdy dodajesz kod i funkcje, zaczynasz widzieć rzeczy, które należy przenieść do innej abstrakcji. Na przykład zasada pojedynczej odpowiedzialności (S SOLID) mówi, aby nie mieć metod związanych z analizą adresów w klasie Person. Więc teraz wiesz, że potrzebujesz klasy adresu.

Zawsze jednak warto zastanowić się, jak wygląda „minimalna liczba abstrakcji” dla twojego systemu. Zacznij od wystarczająco dobrej architektury i ulepszaj ją w miarę upływu czasu.

edit: Odpowiedź @Basile daje przykład, w jaki sposób można iterować i ulepszać minimalną architekturę.


4
Nie zgadzam się. Próba użycia minimalnej liczby abstrakcji nie powinna być celem. Najważniejsze jest budowanie żywotnej struktury w perspektywie długoterminowej. Nie myśl tylko z wyprzedzeniem o minimalnym niezbędnym czasie, ale pomyśl o zbudowaniu kodu, aby inni mogli sobie z nim poradzić w dalekiej przyszłości. Jeśli abstrakcje sprawiają, że kod jest bardziej czytelny i wykonalny, jest to wyraźna poprawa. Wolałbym raczej napisać modułowy kod wielokrotnego użytku. To powiedziawszy, to kwestia doświadczenia, aby móc to ocenić.
Bitwa

@Battle Chodzi o to, że zabezpieczenie na przyszłość jest równie ważne, prawda? Zgodziłbym się z tym, choć przypuszczam, że idealnym rozwiązaniem byłoby stworzenie programu z minimalną liczbą abstrakcji, biorąc również pod uwagę przyszły rozwój. Twierdziłbym, że arbitralna abstrakcja bez korzyści w chwili obecnej iw przyszłości tylko pogorszy twój program, a nie poprawi.
Neil

2
W prawdziwym świecie miałbyś dużo kontekstu wokół korzystania z oprogramowania, więc Twoja minimalna architektura obejmowałaby wiele obecnie znanych przypadków użycia. Myślę, że daje to dobry punkt wyjścia. Modułowość i możliwość ponownego użycia są przez większość czasu wymaganiami niefunkcjonalnymi. Jeśli staną na drodze, zignoruj ​​i uderz w klawiaturę. Ale tak, minimalna abstrakcja nie powinna być ostatecznym celem. Ale może to być punkt wyjścia.
sul4bh

@Neil - Tak, mówiłem o zabezpieczeniu na przyszłość i myślę, że ma to związek ze strukturą kodu i abstrakcjami jako jego częścią. Ale nie mówiłem o arbitralnych abstrakcjach, ale o celu ich zminimalizowania, tak jakby były czymś z natury złym. Są złe, kiedy są źle zrobione.
Bitwa

3
@Battle: wcześniejsze dodanie struktury „na wszelki wypadek” łatwo prowadzi do nadmiernej inżynierii. Z mojego doświadczenia wynika , że posiadanie zawsze liczby abstrakcji wymaganych dla bieżącego rozmiaru podstawy kodu „jest naprawdę dobrym celem - nie mniej, nie więcej. Abstrakcje należy dodawać, gdy baza kodu rośnie, a nie wcześniej. To znaczy jak czytam tę odpowiedź. Ale może sformułowanie „minimalna liczba abstrakcji” może zostać źle zinterpretowane
Doc Brown,

5

Czas poświęcony na myślenie o architekturze systemu nie jest marnowany.

Wierzę, że twoje pytanie może zostać przeformułowane jako „w jaki sposób mogę bardziej skutecznie podejmować decyzje architektoniczne?”.

Moja krótka odpowiedź brzmiałaby następująco: musisz odkryć podstawowe zasady, które pozwolą ci rzetelnie i skutecznie podejmować decyzje, a następnie naprawdę musisz wyjść i ukształtować prawdziwe oprogramowanie. To będzie długa podróż do poszukiwania wiedzy, prób i błędów oraz rozwoju osobistego.

-

I dla dłuższej odpowiedzi ...

Najpierw powinienem wyjaśnić pojęcia: używam słowa architektura do opisu struktury złożonego systemu oprogramowania podczas pracy z procesami, usługami, interfejsami API i bazami danych. Używam słowa design, aby opisać strukturę tylko jednego elementu z bardziej złożonego systemu, kiedy pracuję z klasami, funkcjami i bibliotekami. To są moje definicje, niektórzy ludzie mają różne definicje. Ale w tym kontekście uważam, że mówisz o projektowaniu .

Myślę, że podczas omawiania tego tematu należy pamiętać o 3 ważnych rzeczach:

  • architektura i projekt istnieją bez ich wyraźnego opisania za pomocą diagramów lub dokumentacji, a także bez utrzymywania ich przez zespół lub osobę ( architekta ). Każdy system ma wewnętrzną architekturę i wewnętrzny projekt, który można opisać po fakcie.

  • tworzenie oprogramowania nie jest programowaniem, lecz programowaniem w czasie. Rozróżniam to, ponieważ uważam, że jest to jedna z największych martwych stron dla osób przybywających do branży (w tym także mnie, w pewnym momencie). Oznacza to, że w porównaniu z projektami uniwersyteckimi lub projektami osobistymi praca nad systemem oprogramowania w świecie rzeczywistym jest wykładniczo bardziej złożona, ponieważ każda decyzja architektoniczna będzie miała duży wpływ na rozwój systemu z czasem. Twoje decyzje wrócą teraz, by cię prześladować, gwarantowane.

  • ponieważ architektura i projektowanie istnieją instruktażowo, a podstawa kodu jest żywą istotą, która ewoluuje z czasem, architektura i projektowanie również muszą ewoluować. Będą ewoluować w kontrolowany sposób poprzez świadome decyzje podejmowane w czasie rdzenia lub ewoluują chaotycznie, kierując się kodowaniem. Jest to bardzo ważne, aby zrozumieć, ponieważ oznacza to, że tradycyjne podejście „najpierw architekt i kod pisz drugi” jest wadliwe. Oczywiście rozpoczynając projekt od zera, niektóre prace architektoniczne i projektowe należy wykonać z góry. Ale poza tym, podczas opracowywania systemu będzie jeszcze wiele decyzji architektonicznych i projektowych.

Aby dokładniej wyjaśnić powyższe, bardzo ważne jest, aby zdawać sobie sprawę z faktu, że będziesz podejmować decyzje projektowe podczas pisania kodu, świadomie lub nie. Powinieneś starać się podejmować jak najwięcej decyzji świadomie i krytycznie, ponieważ każda lekka decyzja może mieć duży wpływ na przyszłe prace (wpływ ten zwykle objawia się w podstawie kodu, która staje się bardzo trudna do zmiany w celu naprawy błędów lub implementacji funkcji). Robert C. Martin pięknie to ilustruje, wykorzystując dane, w swojej książce „Clean Architecture” (którą przy okazji bardzo polecam).

Skoro już wiemy, dlaczego architektura i design są ważne, jakie są podstawowe zasady, które mogą dać nam odpowiednie ramy dla dobrego podejmowania decyzji? Miałem to pytanie wcześniej w mojej karierze, czułem się, jakby czegoś brakowało w moim zestawie narzędzi, ale nie wiedziałem, czego, nie wiedziałem, jak to opisać lub poszukać. Podzielę się niektórymi z tych zasad, które odkryłem z czasem i mam nadzieję, że ułatwią ci życie:

  • zestaw bardzo prostych, ale potężnych sztuczek kodujących można znaleźć, czytając książkę Martina Fowlera „Refaktoryzacja: ulepszanie projektu istniejącego kodu”. Jest ich tu zbyt wiele, ale są to decyzje podejmowane na bardzo niskim poziomie czasu kodowania, które można podjąć w celu znacznej poprawy struktury kodu i pomocy w podejmowaniu decyzji projektowych. Książka stanowi również dobry przykład na zintegrowanie testów jednostkowych z osobistym przepływem pracy oraz na temat pisania testowalnego kodu.

  • specjalnie dla OOP powinieneś przyjrzeć się zasadom SOLID . Są nieco abstrakcyjne i na początku trudno je otulić, ale bardzo potężne. Sugeruję zacząć od pierwszych 2, aby szybko uzyskać jak najwięcej korzyści:

Zasada jednej odpowiedzialności : klasa powinna mieć tylko jedną odpowiedzialność (tj. Tylko zmiany jednej części specyfikacji oprogramowania powinny mieć wpływ na specyfikację klasy).

Zasada otwarta / zamknięta : „jednostki oprogramowania… powinny być otwarte na rozszerzenie, ale zamknięte na modyfikację”.

  • pojęcie składu nad spadkiem

    zasada, że ​​klasy powinny osiągnąć zachowanie polimorficzne i ponowne użycie kodu poprzez ich skład (poprzez zawieranie instancji innych klas, które implementują pożądaną funkcjonalność), a nie dziedziczenie po klasie podstawowej lub nadrzędnej.

  • pojęcia sprzężenia („stopień współzależności między modułami oprogramowania”) i spójności („stopień, w jakim elementy wewnątrz modułu należą do siebie”).
  • DRY (dry) pojęcie
  • koncepcji oddzielania rozkaz / zapytanie ( „każda metoda powinna być albo polecenie, które wykonuje czynność, czy zapytanie, które zwraca dane do rozmówcy, ale nie oba”)
  • koncepcja systemu stanowego a bezstanowego (moja ogólna zasada: unikaj obsługi stanu; buduj systemy bezstanowe w jak największym stopniu).

Oczywiście są to tylko koncepcje, a nie reguły. Pierwszym krokiem jest ich zrozumienie i bycie ich świadomym. Następnie przychodzi wykorzystanie ich w praktyce i budowanie doświadczenia, kiedy należy ich przestrzegać, a kiedy nie. Następnie trwa ciągły proces doskonalenia zrozumienia tych pojęć, ich negatywnych stron i złożonych interakcji między sobą.

Myślę, że najcenniejszą radą, jaką mogę ci dać, jest: cierpliwość wobec siebie. Właśnie zacząłeś długą, ale satysfakcjonującą drogę. Ćwicz i eksperymentuj, zwróć uwagę na to, co działa, a co nie, a z czasem poprawisz się.


Tego należy nauczyć się z doświadczeniem. To połowa twojego zadania, a robienie tego źle kosztuje ogromne koszty, ale nie uczy się tego w szkole, ponieważ informatyka i tworzenie oprogramowania to prawie zupełnie inne rzeczy.
Nie U

1

Większość tego, co opisujesz, nie jest tak naprawdę (ważną) architekturą - dobre nazewnictwo i dobry projekt klasy to coś, co powinno być dla ciebie drugą naturą. Będzie to po prostu lepsze, im więcej będziesz kodować. Najbardziej pomocne w takich przypadkach jest zwykle programowanie w parach - pomaga wyjaśnić takie problemy i pomaga nauczyć się tego skutecznie.

Tam, gdzie niezbędna jest architektura, PRZED projektem:

  1. Zbierz dokładne wymagania i wymagania niefunkcjonalne (ile żądań / sekundę muszę obsłużyć?). Wszelkie niedopasowanie w tej fazie doprowadzi do kodowania piekła - integrowanie pominiętych pomysłów po tym, jak jest to czasochłonne, denerwujące i czasami niemożliwe. Wiem, że to nie jest zabawne jak kodowanie, ale próba zmuszenia kodu do zrobienia czegoś, do czego nie został zaprojektowany, jest jeszcze mniej przyjemna.

  2. Jeśli jest to właściwe, zdefiniuj granice kontekstów swojego systemu i upewnij się, że masz proste słownictwo, np. Jeśli firma mówi o „Frobbels”, upewnij się, że nazywasz klasy / interfejsy itp. „*** Frobbels”. Brzmi trywialnie, ale jeśli mówisz o przepływach pracy, podczas gdy firma mówi o operacjach, tłumaczenie bardzo szybko irytuje.

  3. Jeśli pracujesz z wieloma osobami / zespołami, opisz swoje interfejsy wcześnie i upewnij się, że wszystkie założenia i problemy są zrozumiałe dla wszystkich - jeśli nie masz wspólnego kontekstu, integracja będzie „fajna”. Np. Budujesz generator obrazu bananów, ale twój frontend-dev potrzebuje generatora obrazu jabłka. Lub budujesz coś, co może odpowiedzieć na 100 żądań na sekundę, ale potrzeba 10000 r / s.

Uwaga: duży wpływ na to ma moja praca nad architekturą mikrousług. Sposób, w jaki serwery są budowane wewnętrznie, MOŻE być również zaprojektowany - ale przez większość czasu jest to o wiele mniej ważne niż poprawienie dużego obrazu.


1

Nie zamierzam narzucać ci wielu terminów i skrótów (z których większość nie jest w większości uzgodniona przez większość programistów / inżynierów oprogramowania). Zamiast tego rozważ następujące kwestie:

  1. Uczysz się - nie marnujesz czasu, wypróbowujesz różne podejścia i uczysz się, co działa. Możesz to zrobić bez planowania z wyprzedzeniem, nurkując z problemem pierwszego rozwiązania, które przychodzi na myśl, i zmieniając go, jeśli nie działa. Jeśli to działa dobrze, świetnie! Znalazłeś proste rozwiązanie problemu. Proste rozwiązania są w porządku, jeśli działają dobrze, a czasem są wystarczająco dobre .

  2. Wszystko jest kompromisem - możesz zaprojektować ten sam system na wiele różnych sposobów, handlując czasem i przestrzenią, złożonością i elastycznością, abstrakcją i czytelnością, lub jednym z wielu możliwych kompromisów. Żadne rozwiązanie nie jest doskonałe pod każdym względem i żadna reguła nie wyklucza wyjątków w inżynierii oprogramowania. Ktokolwiek mówi ci inaczej, jest albo naiwny, albo sprzedaje coś.

  3. Jako ostatni absolwent kodowanie i debugowanie może być bardzo ekscytujące, ale z czasem to się skończy, a umiejętności, których się uczysz, będą ci dobrze służyć, kiedy to zrobi.

  4. Twierdziłbym, że oprogramowanie do budowania to więcej sztuki / rzemiosła niż inżynierii. Wielka sztuka to nie tylko pojedyncze pociągnięcia pędzla, ale raczej decyzje na wysokim szczeblu i kompromisy podejmowane przez artystę / rzemieślnika.


1

Spróbuję odpowiedzieć na to pytanie z punktu widzenia rozwoju stron internetowych (co oznacza: pochodzić z dziedziny, w której ludzie często dręczą się architekturą). Zacznę od wyjaśnienia, dlaczego ludziom zależy na architekturze, a następnie przedstawię sposoby szybszego przejścia przez część architektury.

Architektura robi dwie rzeczy dla twojego kodu:

  1. Ułatwia zrozumienie kodu dla ciebie i innych.
  2. Pomaga uporządkować kod w sposób ułatwiający jego rozszerzenie i integrację.

Styl kodu ułatwia czytanie określonej części kodu, zapewniając konwencje, które można rozpoznać i używać do poruszania się po nim. Podobnie dobra architektura pomaga zidentyfikować miejsce, w którym rzeczywiście znajdziesz kod, który obsługuje określoną funkcję. Na przykład w większości projektów internetowych architektura ściśle wiąże się ze sposobem sortowania folderów i plików. Z drugiej strony, dobra architektura powinna pomóc ci mniej myśleć o kodzie, ponieważ powinien on już mieć intuicyjne miejsce, do którego należy dowolny fragment kodu.

Ponadto dobra architektura stanowi skrót do uniknięcia wielu pułapek, które mogłyby uniemożliwić łatwe użycie kodu. Ponownie, jeśli podejmiesz decyzję dotyczącą architektury, powinna ona ustanowić konwencję, która pomoże ci mniej myśleć o tym, jak pisać kod.

Teraz część, po którą jesteś tutaj:

Co możesz zrobić, aby szybciej przejść przez część architektury:

  1. Nie rób tego

Jak już wskazano wiele odpowiedzi. Najpierw zadaj sobie pytanie, czy naprawdę potrzebujesz architektury. Jeśli nie będziesz mieć dużo kodu (i możesz mieć pewność, że projekt nie rozwinie się w najbliższej przyszłości), możesz po prostu pominąć część architektury i połączyć razem coś, co po prostu działa. JEDNAK, jeśli jesteś na początku swojej kariery, skorzystałbym z okazji, aby ćwiczyć, kiedy tylko możesz. W pewnym momencie będziesz robić większe projekty, a wtedy prawdopodobnie jest już za późno na naukę.

Z tego, co możesz zrobić, aby architektura była mniej bolesna:

  1. Zrób to wcześnie
  2. Skraść
  3. Naucz się / trzymaj się tego
  4. Nie przesadzaj

Decyzja o architekturze powinna być wczesną częścią procesu planowania. Gdy tylko zorientujesz się, jaką aplikację / program / stronę internetową stworzysz, zastanów się, jaką architekturę to obsługuje.

W tym momencie nadszedł czas, aby ukraść bezkształtnie. Istnieje wiele literatury na temat tego, jak poprawnie skonfigurować architekturę programu, a zdumiewająca liczba przypadków użycia jest uwzględniona w tych istniejących prototypach architektury. Powinieneś zapoznać się z ogólnym przeglądem istniejących architektur, nawet jeśli nie wiesz, jak je wdrożyć.

Jeśli zdecydowałeś się na jakąś architekturę, trzymaj się jej. W przeważającej części decyzja dotycząca architektury powinna być intuicyjna i potrwać kilka sekund po wstępnej konfiguracji. Wiele z tego sprowadza się do doświadczenia.

Wreszcie, nie przemyślaj innych rzeczy. Podajesz przykład, czy coś powinno być publiczne czy prywatne, a prawda jest taka, że ​​prawdopodobnie nie ma znaczenia, czy wszystko upublicznisz. Tak, nie powinieneś tego robić w ten sposób i do wielu z tych drobnych błędów po pewnym czasie będzie się nakładać, ale pod koniec dnia prawdopodobnie nie zabije to również twojego projektu. Przede wszystkim stwórz działające oprogramowanie!

(PS: To ostatnie zdanie nie jest usprawiedliwieniem dla lenistwa. Ustalenie priorytetu działającego oprogramowania nie oznacza, że ​​pewnego dnia nie będziesz musiał nauczyć się dobrego kodowania.)


1

Odpowiedź jest bardzo prosta,

  • Utwórz prototyp (w pudełku czasowym)
  • Refaktoryzacja (spędzaj tyle czasu, ile chcesz lub masz na podstawie szerokiego zakresu czynników)

Podczas tworzenia prototypu należy skupić się na minimalnym produkcie żywotnym, a podczas refaktoryzacji należy skoncentrować się na zwiększeniu skalowalności projektu lub rozwiązania.


1

Jak mogę szybciej przejść przez fazę architektury i przejść do fazy kodowania i debugowania, co mi się podoba?

Przenosząc to zadanie do (lub prosząc o pomoc) bardziej doświadczonych współpracowników.

Po prostu brakuje ci doświadczenia niezbędnego do szybkiego podejmowania takich decyzji. Uni ma dobre teoretyczne tło, ale prowadzi cię tylko do linii startowej. Nie ma innego sposobu oceny danej architektury w danej sytuacji niż wiedza o tym, jak podobne architektury zachowywały się w podobnych sytuacjach w przeszłości.

Praca z ludźmi, którzy są lepsi w pracy niż Ty, to najszybszy sposób na naukę. Jeśli nie masz nikogo, do kogo się zwrócić, potrzebujesz lepszej pracy. „Lepszy” jak w „lepiej dostosowany do twoich potrzeb”. Potrzeba wiedzy i doświadczenia jest w tej chwili najbardziej pilną potrzebą, o czym świadczy dylemat. Lubisz fazę kodowania i debugowania? Brzmi jak idealny junior. Ale junior potrzebuje wskazówek seniora. Właśnie o to chodzi w opisach stanowisk. Nieznajomi w Internecie mogą ci tylko pomóc, potrzebujesz mentora.


Myślę, że to dobra odpowiedź, ale sugerowałbym zmianę „Praca z ludźmi, którzy są lepsi od ciebie” na „Praca z ludźmi, którzy są bardziej doświadczeni niż ty”. „Lepszy” może być interpretowany na wiele różnych sposobów, jak wykazano w następnym zdaniu.
JimmyJames

@JimmyJames Zmieniłem na „lepszy w pracy”. Ponieważ doświadczenie jest tylko jego częścią.
Agent_L

Ogólnie nie zgadzam się z tym i właśnie dlatego uważam, że „lepiej” niekoniecznie jest tutaj dobrym słowem. Myślę, że w przypadku OP wirują, ponieważ nie mają kontekstu procesu projektowania. Nawet zły projektant / architekt może w tym pomóc i jest technicznie „lepszy” niż PO. Ale kiedy PO zrozumie pracę, może być „lepszy” niż mentor. Więc to nie jest tak, że twoja odpowiedź jest niepoprawna, jest tylko wiele niuansów, które nie są oczywiste po użyciu terminu „lepiej”.
JimmyJames

1

Widzę kilka poważnych problemów z tym pytaniem. Zaczynajmy.

Jak przestać marnować czas na projektowanie architektury

To pytanie jest raczej załadowane. Nie projektujesz także architektury. Ty architekt . Architektura i projektowanie są działaniami uzupełniającymi się i powiązanymi, ale nie są takie same, nawet jeśli mogą się nakładać.

Podobnie, w ten sam sposób, w jaki można marnować czas na tworzenie architektury (przez nadmierną architekturę), możesz także marnować czas na nadmierne projektowanie i nadmierne kodowanie (przez kodowanie rzeczy w sposób znacznie bardziej skomplikowany niż to konieczne lub przez zaniechanie kod rzeczy, które są wymagane).

Właściwa architektura ma na celu zapobieganie marnotrawstwu w kodowaniu. Robi to poprzez ograniczenie, zawężenie i udokumentowanie możliwych sposobów 1: zaprojektowania złożonego systemu, 2) zakodowania i przetestowania go, 3) dostarczenia, 4) utrzymania, 5) odzyskania po awarii i 6) ostatecznego wycofania z eksploatacji.

Z mojego doświadczenia wynika, że ​​ludzie, którzy po prostu lubią kodować, po prostu kodują, nie myśląc o tym, jak system ma działać i utrzymywać się na dłuższą metę, przechodząc do następnego gorącego ziemniaka, pozostawiając jakąś biedną duszę, aby utrzymać brzydkiego golema.

Ale dygresję ...

O to chodzi: w przypadku systemów prostych architektura jest oczywista i wynika z dobrych praktyk projektowania i implementacji.

Dotyczy to tylko dużych systemów, które wymagają dość dużej liczby osób lub oprogramowania na poziomie systemu, które wykonuje bardzo złożone czynności wymagające wyraźnej architektury.

Niedawno ukończyłem Uni i zacząłem pracować jako programista. Nie jest mi tak trudno rozwiązać problemy „techniczne” lub przeprowadzić debugowanie, rzeczy, które powiedziałbym, że mają 1 rozwiązanie.

To minimum wymagane dla tego zawodu i cieszę się, że nie masz problemu z ich wykonaniem (byłbym zmartwiony, gdybyś zrobił).

Ale wydaje się, że istnieje klasa problemów, które nie mają jednego rozwiązania

To chleb powszedni w naszym zawodzie, rodzaj problemów, za które pracodawcy są skłonni zapłacić nasze (zazwyczaj) znacznie wyższe od przeciętnego wynagrodzenie.

W rzeczywistości problemy warte rozwiązania to takie, które mogą mieć więcej niż jedno rozwiązanie. Problemy w świecie rzeczywistym, takie są. Świat wymaga od nas, jako twórców oprogramowania, naszej wiedzy specjalistycznej, aby uzyskać akceptowalne kompromisy.

- rzeczy takie jak architektura oprogramowania.

Architektura rzeczy jest nieuniknioną cechą złożonego systemu, czy to wirtualnego / oprogramowania, czy w konkretnym świecie. Każdy działający system, który pobiera dane wejściowe i generuje dane wyjściowe, będzie złożony i będzie miał architekturę.

Kiedy tworzymy oprogramowanie dla takich systemów (system bankowy, system monitorowania mocy, system sprzedaży biletów itp.), Staramy się stworzyć oprogramowanie, które naśladuje funkcje i wymagania takiego systemu.

Po prostu nie możemy tego po prostu ułożyć i zakodować w stylu kowbojskim. Potrzebujemy jakiejś architektury. Jest to szczególnie prawdziwe, jeśli projekt wymaga dziesiątek inżynierów, jeśli nie więcej.

Te rzeczy wprawiają mnie w osłupienie i przysparzają mi wielkiego cierpienia.

To dobrze. Nauczenie się lub nauczanie nie jest łatwym przedmiotem, nie bez dużej praktyki.

Spędzam wiele godzin, próbując zdecydować, jak „zaprojektować” moje programy i systemy. Na przykład, czy podzielę tę logikę na 1 lub 2 klasy, jak mam nazwać klasy, czy powinienem to uczynić prywatnym czy publicznym, itp. Tego rodzaju pytania zajmują mi dużo czasu i bardzo mnie to frustruje. Chcę tylko stworzyć program, niech będzie architektura.

Niestety, to nie jest architektura oprogramowania.

To nawet nie projekt, ale tylko kodowanie. Podam kilka sugestii na dole tego postu.

Jak mogę szybciej przejść przez fazę architektury i przejść do fazy kodowania i debugowania, co mi się podoba ?

Trudno mi znaleźć odpowiedź na to pytanie, ponieważ jest to raczej emocjonalne.

Czy staramy się wykonać pracę, czy po prostu czerpiemy przyjemność z praktyki? Wspaniale jest, gdy oba są jednym i tym samym, ale w prawdziwym życiu wiele razy tak nie jest.

Wspaniale jest robić rzeczy, które lubimy, ale w tak złożonym zawodzie, jak nasz, skupianie się tylko na tym, co sprawia nam przyjemność, a to nie sprzyja prowadzeniu owocnej kariery.

Nie będziesz robić postępów, nie dojrzejesz ani nie zdobędziesz nowej wiedzy.

W armii jest takie powiedzenie: „obciągnij ssanie”.

Inne frazy mają podobne rady. „Jeśli to nie jest do bani, to nie jest tego warte” i mój ulubiony: „Jeśli to do bani (i jest to ważne), rób to, aż przestanie ssać”.

Moje rekomendacje:

Wydaje mi się, że wciąż próbujesz zrozumieć różnice między nimi

  1. kodowanie (jak kodować swoje klasy, moduły lub co nie, konwencje nazewnictwa, widoczność dostępu, zakres itp.),

  2. projektowanie (ile poziomów, front-end / back-end / db, jak każdy się komunikuje, co idzie gdzie) i niejawne decyzje dotyczące architektury wynikające z projektowania prostych systemów,

  3. architektura (jak w złożonych systemach wymagających tysięcy, jeśli nie setek tysięcy roboczogodzin).

Proponuję więc zagłębić się w pierwszy temat (kodowanie), aby przenieść go na wyższy poziom.

Wyczyść kod

Dobrym miejscem na początek jest „Clean Code” Roberta „Wujka Boba” Martina

Spójność oprogramowania

Ponadto sugeruję zapoznanie się z konkretną metryką oprogramowania obiektowego o nazwie LCOM, a raczej LCOM4.

Może być dość matematyczny i nie jest kuloodporny, ale twoim celem powinno być empiryczne zrozumienie i wykrycie (lub wzrok, jeśli chcesz), jeśli klasa jest spójna lub brakuje jej spójności.

http://www.aivosto.com/project/help/pm-oo-coicity.html#LCOM4 https://www.computing.dcu.ie/~renaat/ca421/LCOM.html

Zasady oprogramowania

Jest to ściśle związane z „zasadą pojedynczej odpowiedzialności” lub SRY, którą wszyscy powinniśmy znać. SRY jest jednym z 5 „SOLIDNYCH” , z którymi wszyscy musimy się zapoznać, jeśli chcemy osiągnąć biegłość w kodowaniu.

Przechodząc przez zasady SOLID, musimy również zapoznać się z zasadami „GRASP” , które rządzą, a raczej kierują sposobem, w jaki kodujemy klasy.

Dodatkowe książki

Na koniec zasugeruję również:

  • „Refaktoryzacja” Martina Fowlera i Kena Becka byłaby kolejną książką, którą przeczytałam na tej liście.

  • „Design by Contract, by example” Richarda Mitchella, Jima McKima i Bertranda Meyera (późniejsza sława Eiffla). Ta książka jest wyczerpana, ale w Amazon można znaleźć tanie, używane kopie.

Dzięki temu powinieneś dobrze zrozumieć, jak zacząć kodować i projektować, a także, w praktyce, przenosić i opanować (lub przynajmniej zrozumieć) architekturę oprogramowania.

Jestem pewien, że będą inni specjaliści, którzy dodają, odejmują lub sprzeciwiają się tym sugestiom. Wymyślą inne sugestie, prawdopodobnie potwierdzone przez własne doświadczenie.

Mogę tylko powiedzieć, że nie ma skrótów.

Wszystkiego najlepszego.


1

Jest tu wiele informacji i szczerze mówiąc TL; DR. Wydaje mi się, że ludzie popełniają błąd, próbując nauczyć się projektować system: próbują myśleć o tym w kolejności, w jakiej praca zostanie wykonana. Zamiast tego musisz pracować wstecz. Oznacza to, że głównym celem projektowania / architektury jest określenie, jaki powinien być wynik końcowy.

Jako analogię rozważ architekturę domu. Architekt nie zaczyna zadawać sobie pytań typu: „ile okien powinien mieć ten dom?”, „Gdzie należy umieścić pierwszą cegłę?”. Te szczegóły implementacji nie są projektem, pochodzą z projektu. Architektura zaczyna się od wizji, być może szkicu, jak może wyglądać gotowy dom. Czy to dom jednorodzinny, dupleks? Czy to luksusowy dom, czy niedrogi? Podobnie to, czy zmienne są prywatne i czy dzielisz klasę, ma bardzo niewiele wspólnego z architekturą.

Zacznij od ustalenia, jakie są cele Twojego projektu. Na przykład, czy jest to rozwiązanie jednorazowe? Czy będzie rozwijany, poprawiany i utrzymywany przez dziesięciolecia? Odpowiedź na to wskaże bardzo różne projekty i na tym polega architektura. Kiedy już zorientujesz się, co musisz zrobić, szczegóły tego projektu są naturalne. Nie chodzi o to, że te szczegóły są oczywiste lub łatwe, ale to na planie ogólnym opierają się te wybory.


0

Jak ocenić, ile czasu należy poświęcić na zaprojektowanie dowolnego oprogramowania, zanim uzyska się jakąś pętlę testowania kompilacji zapisu, jest dość prosta: wystarczająca ilość informacji, aby zmieścić się w twojej głowie, i nic więcej. Chyba że projekt, nad którym pracujesz, wymaga bardziej rygorystycznej metodologii. W takim przypadku jako początkujący najprawdopodobniej powinieneś czytać dokument architektury, a nie go pisać.

Jeśli chodzi o nazywanie rzeczy, dla mnie jest to część „pisania”, ale niewątpliwie jest to bardzo ważna część programowania: nie wahaj się myśleć o tym, jak nazywasz rzeczy, i zastanowić się, im większy zakres nazwy.

Znalezienie odpowiednich nazw, właściwej architektury, właściwej modułowości i właściwych abstrakcji jest częścią doświadczenia, które zdobędziesz, popełniając błędy. Przez lata napisałem program, który robił to samo pięć razy, a kod był za każdym razem bardzo różny, ponieważ każda poprzednia iteracja dawała mi wskazówki dotyczące lepszego projektu.

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.