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ć
.csv
plik 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
XML
s 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?
źródło
Odpowiedzi:
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.
źródło
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.
źródło
Programowanie obiektowe dodaje cztery nowe narzędzia do Twojego arsenału:
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.
źródło
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.
źródło
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ć.
źródło
W kategoriach laika:
To powiedziawszy, należy wziąć pod uwagę inne czynniki:
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.
źródło
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.
źródło
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ć
źródło