Kiedy faktycznie używamy programowania obiektowego? [Zamknięte]

35

Piszę program w języku Python, który w zasadzie manipuluje ciągami znaków i zastanawiałem się, czy powinienem to zrobić przy użyciu zasad OOP, czy nie. Klient powiedział mi, że nie obchodzi go kod, po prostu chce, żeby to się stało .

Wiem, że kod zorientowany obiektowo nie jest z definicji czyszczący, a odwrotnie, kod inny niż OO nie jest z definicji kiepski. Pytanie, które zadaję, może być mniej więcej oparte na opiniach, ale mogą istnieć pewne zasady, których nie jestem świadomy.

Więcej informacji o tym, co należy zrobić:

  • parsować .csvplik i przetwarzać dane na podstawie pliku konfiguracyjnego (kolumny mogą być różne - na przykład pod względem liczby kolumn lub przechowywanych danych)
  • użyj wyżej przetworzonych danych, aby utworzyć nowe niestandardowe sformatowane dane (lub wiele plików w oparciu o niektóre z powyższych wartości)
  • użyj ostatnio sformatowanych danych, aby utworzyć plik XML.
  • podzielić plik XML na wiele XMLs na podstawie ich zawartości
  • aplikacja powinna być oparta na interfejsie CLI
  • są oczywiście inne rzeczy, takie jak: rejestrowanie niektórych zdarzeń, analizowanie argumentów CLI i tak dalej.

Teraz nie jest to wcale duża / trudna aplikacja i jest prawie ukończona, ale podczas całego procesu programowania ciągle zadawałem sobie pytanie, czy należy to zrobić przy użyciu OOP, czy nie.

Moje pytanie brzmiałoby: skąd, wiecie / decydujecie, kiedy używać OOP w aplikacji?

Grajdeanu Alex.
źródło
12
Odp .: „Klient… nie dba o kod, chce tylko, żeby to się stało”. OK, a następnie zrób to. Ale jak skomplikowana jest to rzecz? Jak dobrze naprawdę rozumiesz wymagania? Jak prawdopodobne jest to, że klient poprosi Cię później o zmianę? Czasami szybkie i zabrudzony hack, jest wszystko, czego potrzeba, ale im więcej czasu i energii masz zamiar inwestować w nią, tym bardziej prawdopodobne, że niektóre zorganizowane podejście do rozwiązania problemu (na przykład projekt OO) będą korzystać ci.
Solomon Slow
5
Nie używaj „EDYTUJ” ani innych podobnych pseudonimów w swoich postach. Każdy post Stack Exchange ma szczegółową historię edycji, którą każdy może przejrzeć. Informacje takie jak „Nie pytałem, co to jest OOP” są bardziej odpowiednie w komentarzu, a nie w twoim pytaniu.
Robert Harvey
@RobertHarvey ok, rozumiem. Zrobię to następnym razem.
Grajdeanu Alex.

Odpowiedzi:

60

Python jest językiem o wielu paradygmatach, co oznacza, że ​​możesz wybrać paradygmat najbardziej odpowiedni dla zadania. Niektóre języki, takie jak Java, są jednostopniowym systemem operacyjnym, co oznacza, że ​​będziesz mieć bóle głowy, jeśli spróbujesz użyć dowolnego innego paradygmatu. Plakaty mówiące „zawsze używaj OO” prawdopodobnie pochodzą z tła w takim języku. Ale na szczęście masz wybór!

Zauważ, że twój program jest aplikacją CLI, która odczytuje niektóre dane wejściowe (pliki csv i pliki konfiguracyjne) i generuje pewne dane wyjściowe (pliki xml), ale nie jest interaktywna, a zatem nie ma stanowego interfejsu GUI ani interfejsu API. Taki program jest naturalnie wyrażany jako funkcja od wejścia do wyjścia, która przekazuje inne funkcje podzadaniom.

Z drugiej strony OO polega na enkapsulacji stanu zmiennego i dlatego jest bardziej odpowiedni dla aplikacji interaktywnych, GUI i API ujawniających stan zmienny. To nie przypadek, że OO zostało opracowane równolegle z pierwszymi GUI.

OO ma jeszcze jedną zaletę, ponieważ polimorfizm pozwala na luźniej sprzężoną architekturę, w której różne implementacje tego samego interfejsu można łatwo zastąpić. W połączeniu z wtryskiem zależności może to pozwolić na ładowanie zależności i innych fajnych rzeczy na podstawie konfiguracji. Jest to jednak najbardziej odpowiednie w przypadku bardzo dużych aplikacji. W przypadku programu o wielkości opisywanej byłby o wiele za duży, bez widocznych korzyści.

Oprócz funkcji faktycznie odczytujących i zapisujących pliki, większość logiki można zapisać jako funkcje bez skutków ubocznych, które pobierają pewne dane wejściowe i zwracają inne dane wyjściowe. Jest to niezwykle łatwe do przetestowania, o wiele prostsze niż testowanie jednostek OO, w których musisz wyśmiewać zależności i tak dalej.

Konkluzja: Proponuję kilka funkcji podzielonych na moduły do ​​organizacji, ale żadnych obiektów.

JacquesB
źródło
8
Wreszcie dobrze wyważona odpowiedź, która nie tylko śpiewa pochwały OOP :-)
cmaster
1
Tego rodzaju odpowiedzi się spodziewałem. Czy możesz rozwinąć nieco swoją odpowiedź? Jak dotąd wygląda niesamowicie.
Grajdeanu Alex.
3
@ Dex'ter: Niż ciebie. Jakiego rodzaju dodatkowych informacji szukasz?
JacquesB
3
Dodam do tego, że Programowanie Funkcjonalne może być paradygmatem do przeczytania.
Andrew mówi Przywróć Monikę
1
@Bergi: Tak, to jest korzyść języka opartego na paradygmacie. Możesz korzystać z bibliotek OO bez konieczności pisania własnego programu w stylu OO.
JacquesB
15

Rozważ przycisk na GUI. Ma stan (jego rozmiar, kolor, położenie, etykieta itp.). Może się to zdarzyć (kliknięcie, potrzeba przerysowania itp.). W takich sytuacjach modelowanie go jako obiektu ma sens. Jako obiekt może zawierać swój stan, zestaw działań, które można na nim wykonać (metody), i może powiadamiać inne części aplikacji, że coś się z nim stało przez odpalenie zdarzeń.

OOP to doskonałe narzędzie do obsługi GUI i innych sytuacji, w których części systemu mają niestabilny stan.

Inne sytuacje, takie jak opisana przez ciebie, w których dane są odczytywane ze źródła, przetwarzane i zapisywane do miejsca docelowego, są dobrze obsługiwane przez inne podejście: programowanie deklaratywne (lub funkcyjne). Kod deklaratywny do przetwarzania danych jest zazwyczaj łatwiejszy do odczytania i krótszy niż rozwiązania OOP.

Zarówno młot, jak i piła są potężnymi narzędziami, jeśli są właściwie używane, podobnie jak obiektowe i deklaratywne techniki programowania. Prawdopodobnie możesz wbić gwóźdź w kawałek drewna za pomocą rączki piły. Podobnie możesz rozbić kawałek drewna na pół młotkiem. Podobnie, możesz stworzyć GUI z tylko funkcjami i przetwarzać dane za pomocą obiektów. Gdy narzędzia są używane prawidłowo, wyniki są czystsze i prostsze.

Ogólna zasada, której używam, jest taka, że ​​jeśli mam dużo stanu lub potrzebuję interakcji użytkownika, używam obiektów; w przeciwnym razie używam (czystego i wyższego rzędu, tam gdzie to możliwe) funkcji.

David Arno
źródło
6

Programowanie obiektowe dodaje cztery nowe narzędzia do Twojego arsenału:

  1. Kapsułkowanie
  2. Abstrakcja
  3. Dziedzictwo
  4. Wielopostaciowość

Używałbyś OOP w swojej aplikacji, gdy stała się wystarczająco duża i wystarczająco złożona, aby korzystać z tych narzędzi.

Robert Harvey
źródło
18
Abstrakcja i polimorfizm są narzędziami zapewnianymi przez wiele „orientacji” programowania. OOP faktycznie oferuje słabszą formę enkapsulacji niż inne podejścia, ponieważ dziedziczenie zachęca do nieszczelnych projektów abstrakcji. Jedyną rzeczą, którą OOP naprawdę dodaje do zestawu narzędzi, jest dziedziczenie, które jest powszechnie postrzegane jako zła rzecz.
David Arno,
4
@DavidArno: Mówisz w zasadzie „Nigdy nie używaj OOP”.
Robert Harvey
6
Wynika to z trudu spędzonego w pracy, gdy patrzy się na kod innych ludzi, prosta implementacja proceduralna programu jest często lepsza niż implementacja ze złym zrozumieniem projektu OO. Architektura OO może być bardzo potężna, ale powinna być używana jak przyprawa w gotowaniu, z fachową wiedzą i odpowiednią ilością. Niewłaściwe użycie projektu OO jest tak powszechne, jak proszenie o ketchup w złej restauracji.
Phill
6
Żadne z czterech narzędzi (enkapsulacja, abstrakcja, dziedziczenie, polimorfizm) nie jest specyficzne dla OOP. Może powinieneś wyjaśnić, w jaki sposób OOP różni się od innych paradygmatów wrt do tych wymiarów.
Giorgio
4
@gardenhead twoje dziwne poczucie wyższości nic nie robi dla twojej pozycji. Być może powinieneś wypytać pytanie zatytułowane „Dlaczego najczęściej zatrudniane języki to OO?”. Jeszcze lepiej, Ctrl + F i wpisz „GUI”.
Gusdor
1

To pytanie wydaje mi się trochę zagmatwane. Jeśli piszesz go w Pythonie, na pewno będziesz używać obiektów. Po otwarciu plik zwraca obiekt. Po uzyskaniu wyniku zwraca obiekt iteratora. Każda tworzona funkcja jest obiektem. Pytanie o wartość OO w aplikacjach Pythona wydaje się co najmniej dziwne.

Tak, w oparciu o komentarze tutaj, Python obsługuje paradygmaty funkcjonalne, ale przede wszystkim jest oparty na obiektach. Sam język i wbudowane biblioteki lib są zorientowane na obiekty. Tak, obsługuje lambda (podobnie jak Java i dowolną liczbę języków zwykle określanych jako OO), ale jest celowo uproszczony w porównaniu do prawdziwego języka funkcjonalnego.

Być może te rozróżnienia wokół projektowania OO i projektowania funkcjonalnego stają się przestarzałe. Jeśli utworzę, weź funkcję polimorficzną na obiekcie zaprojektowanym przez OO * i przekażę wskaźnik do tej funkcji na obiekcie jako parametr funkcji funkcjonalnie stylizowanej *, czy to OO, czy też działa? Myślę, że to zarówno, jak i bardzo skuteczne podejście do rozwiązywania problemów.

Myślę, że prawdziwe pytanie brzmi: „kiedy powinieneś zacząć projektować własne klasy, a nie tylko tworzyć moduł z funkcjami?”. Myślę, że właściwą odpowiedzią jest: kiedy pomaga uprościć rozwiązanie. Podałbym tę samą podstawową odpowiedź dla dowolnego języka obiektowego.

* redundancja jest zamierzona: nie chcę być tutaj oskarżany o zakładanie, że obiekty są OO lub że funkcje są funkcjonalne.

JimmyJames
źródło
5
tak, obiekty nie są równe OOP. istnieje różnica między posiadaniem obiektu a budowaniem architektury wokół obiektów i ich interakcji. coś w rodzaju, jeśli stworzysz funkcję, która nie oznacza, że ​​zajmujesz się programowaniem funkcjonalnym.
sara
można dość łatwo uznać obiekt Python / JavaScript za Record, który jest całkiem funkcjonalny. Języki funkcjonalne mają obiekty. Klucz jest w drugim słowie: zorientowany. Języki OOP są całkowicie zorientowane na używanie obiektów, podczas gdy niektóre inne języki wydają się po prostu inną częścią zestawu narzędzi.
Dan Pantry
0

Jedną z największych rzeczy w programowaniu obiektowym jest to, że zamiast wnioskowania o przebiegu programu, zaczynasz rozumować o stanie.

Wiele razy widzę obiekt, widzę metody, ale widzę też, że główną zasadą kodu jest przepływ zamiast stanu.

A kiedy już zaczniesz myśleć o stanie, łatwo jest zbudować dobry kod OOP, ponieważ gdy tylko kod stanie się zbyt skomplikowany, zauważysz, że nie możesz już dłużej myśleć o swoim stanie i wiesz, że musisz zrefaktować.

Rozważ swój przykład: chcesz przeanalizować plik csv. Skąd pochodzi: plik na dysku. Ładujesz go, zapisujesz w pamięci i analizujesz. Teraz przychodzi twój klient: hej, chcę też parsować pliki z sieci. Więc jesteś szczęśliwy, ponieważ stworzyłeś ładny interfejs do ładowania pliku i musisz tylko zrobić kod, który pobiera go z sieci, a reszta programu pozostaje dokładnie taka sama.

A miłą rzeczą jest to, że możesz to przetestować.

Pieter B.
źródło
3
Twój przykład z odczytem pliku z dysku w porównaniu z odczytem pliku z sieci można również zaimplementować za pomocą różnych funkcji. Nie potrzebujesz do tego OO.
JacquesB
0

W kategoriach laika:

  • Możesz używać OOP lub non-OOP w każdym rodzaju projektów, które chcesz.
  • OOP nie jest panaceum, ale pomaga zarządzać złożonością.
  • Wykracza poza modułowość, chodzi o podział na przedziały. Pomyśl o różnych przedziałach, które statek ma do utrzymywania pływalności, jeśli kadłub jest uszkodzony.
  • OOP to sposób zarządzania zależnościami, dzięki czemu błędy mogą być łatwiejsze do wyśledzenia, ponieważ istnieje tylko określony zestaw sposobów, w jaki różne komponenty programu mogą komunikować się z innymi.
  • W programie działa wiele rzeczy: zmienne, stałe, metody, pliki, parametry, funkcje, moduły itp. Mogą oddziaływać na siebie w sposób, który czasem może być nieprzewidywalny. OOP to zestaw zasad, które zmniejszają liczbę sposobów interakcji między sobą. Nie musisz do tego używać OOP, ale to pomaga.

To powiedziawszy, należy wziąć pod uwagę inne czynniki:

  • Czy Twoi programiści są biegli w OOP / OOD?
  • Czy Twoi programiści są biegli w języku OOP?
  • Czy uważasz, że oprogramowanie z czasem się skomplikuje?
  • Czy planujesz skalować lub ponownie wykorzystywać kod w przyszłości?
  • Czy uważasz, że Twój „projekt” może stać się atutem? tj. Czy będziesz w stanie wykorzystać to do rozwoju lub jako podstawę przyszłych projektów?

Nie zrozum mnie źle: możesz to wszystko osiągnąć bez użycia OOP, ale z OOP będzie łatwiej.

Ale...

Jeśli Twój zespół nie jest biegły w OOP / OOD i nie ma specjalistycznej wiedzy w tej dziedzinie, skorzystaj z posiadanych zasobów.

Tulains Córdova
źródło
-2

Moje pytanie brzmiałoby: skąd, wiecie / decydujecie, kiedy używać OOP w aplikacji?

Zawsze go używaj. Gdy już go przyzwyczaisz, będziesz go używać do wszystkiego. Jest to świetny sposób na zapewnienie dobrego wyodrębnienia możliwości i ich wykorzystania, co stanowi znaczącą korzyść z konserwacji. Używamy go na przykład do

  • małe obiekty struktury danych, ponieważ są one często polimorficzne, na przykład pośrednia struktura danych po parsowaniu czegoś często ma wiele małych bytów, które mają wspólne zachowanie, ale jeszcze są wyspecjalizowane. Są to świetne przypadki użycia dla wspólnej klasy bazowej lub interfejsu ze specjalnymi implementacjami i zachowaniami, tj. Hierarchią klas (polimorfizm).

  • rejestrowanie, jako przykład, ponieważ ułatwia zastąpienie innego rejestratora

  • duże kawałki struktury programu, ponieważ tworzysz wiele współbieżnych, a być może korzystasz z wielu procesorów. Na przykład serwer WWW może trywialnie używać wielu współbieżnych procedur obsługi żądań z powodu obiektów.

Ułatwia to refaktoryzację i ponowne użycie, jak już wspomniałem, zachęca do dobrej abstrakcji, co ułatwia utrzymanie. OOP powinien być objęty i używany przez cały czas. Dobre programowanie OOP pozwala uniknąć metod statycznych i / lub danych statycznych oraz używa obiektów do wszystkiego.

Erik Eidt
źródło
6
Nie głosowałem (choć byłem blisko), ale myślę, że to jest powód, dla którego otrzymaliście głosy negatywne: „Zawsze używaj tego, bo to świetne” rzadko jest dobrą radą. Zawsze są wyjątki. Żadne narzędzie nie ma wad, a OOP nie jest wyjątkiem. Powiedz ludziom, że jest dobry, powiedz ludziom, po co jest dobry, powiedz ludziom, dlaczego jest dobry, powiedz ludziom, aby unikali alternatyw, jeśli mogą, ale nigdy nie mów ludziom, aby nie myśleli o alternatywach.
cmaster
@cmaster, nic mi nie jest, jeśli ludzie głosują, to ich wybór i ja też to zrobiłem. W tej kwestii nadal uważam, że jest to właściwa odpowiedź dla osoby zadającej pytanie; IMHO, OP musi wskoczyć do końca i używać OOP, zamiast próbować decydować, kiedy użyć OOP i od czasu do czasu decydować się na utworzenie klasy, ale w inny sposób pisząc kod proceduralny.
Erik Eidt,
2
@cmaster Mogę docenić porady Erika. Tak często, jak odpowiedź „zależy” może być politycznie poprawną drogą, spójrzmy prawdzie w oczy ludziom, OO stała się prawie podstawą dla środowisk programistycznych, które ją obsługują. Więc nie oszukujmy się, trudno nie pomylić się z OO. Opisany skrypt jest, choć liniowy, wystarczająco złożony, aby obiekty przyniosły pewne korzyści.
Martin Maat,
2
@ErikEidt „OP musi wskoczyć do końca i użyć OOP”. Można sparafrazować to jako: „OP musi przestać myśleć o najlepszym sposobie rozwiązania problemu klienta i po prostu podążać Jedną Prawdziwą Ścieżką do Oświecenia”. Niestety, miałem do czynienia z dużą ilością tak zwanych specjalistów komputerowych, którzy zrobienia podążać tą metodologię projektowania oprogramowania. Obowiązkowa kreskówka Dilberta: dilbert.com/strip/1996-02-27
alephzero
1
choć jest to tak łatwe, że można to zrobić jako „kolejny bezmyślny fanatyk OOP”, myślę, że jest coś, co można powiedzieć o włożeniu 100% w coś, co naprawdę internalizuje i absorbuje. nie po to, abyś mógł używać go codziennie przez resztę życia, ale tak naprawdę UCZY SIĘ mocnych i słabych stron, a nie tylko o nich czytać. Poleciłbym każdemu, kto spędził kilka miesięcy na hardcorowym OOP i kilka miesięcy na hardcorowym FP (á la haskell) oraz kilka miesięcy na procedurę C i tak dalej. po prostu wejdź tam i zejdź na dół i ubraj go.
sara
-2

Programowanie obiektowe zapewnia narzędzia do tworzenia frameworka. Te narzędzia to enkapsulacja, abstrakcja, dziedziczenie i polimorfizm. Te pomysły pomogą ci podzielić swój program na dwie części.

Jak to zrobić - jest to część kodu związana z tworzeniem ramek, w której tworzysz abstrakcję, decydujesz, w jaki sposób działają Twoje bloki i jak współdziałają z innymi blokami.

Co należy zrobić - w tej części bloki wykonują samą pracę. Tutaj klasa pochodzi od klas podstawowych utworzonych w „Jak to zrobić”.

Z OOPS można wiele skorzystać

  1. jeśli możesz ponownie użyć istniejącego frameworka i musisz tylko wdrożyć określone szczegóły w sekcji „co robić”.
  2. Funkcjonalność, która jest wdrażana dla bieżącego projektu, jest ogólna / powszechnie używana, a inne projekty / przyszłe projekty mogą czerpać korzyści z frameworku, który jest tworzony podczas opracowywania bieżącego projektu.
  3. Podział dużych projektów na powszechnie znane wzorce w celu rozwiązania dużego problemu.
  4. Użyj OOPS nawet dla małego projektu, aby nabrać nawyku korzystania z niego i być gotowym, gdy pojawi się 1–3 rodzaje problemów
Rahul Menon
źródło
Więc zasadniczo mówisz, że zawsze powinieneś używać OOP, niezależnie od faktycznego zadania, które chcesz rozwiązać?
JacquesB
Nie :), istnieje wiele padigramów programów i niektóre z nich lepiej rozwiązują dany problem niż inne. OOPS nie jest najlepszym rozwiązaniem dla wszystkich, ale OOPS jest dość popularne. zbudowanie dobrej klasy i struktur w OOPS zajmie trochę czasu i praktyki, więc jeśli chcesz efektywnie korzystać z OOPS, zacznij od mniejszych projektów. Gdy go opanujesz, zależy to wyłącznie od Ciebie. Widzę koncepcje OOPS głównie jako narzędzie do budowania frameworka.
Rahul Menon