Open close principle

0

Wujek Bob każe by klasy były otwarte na rozszerzenia ale zamknięte na zmiany. Czy rozszerzenie oznacza tylko dziedziczenie czy także rozbudowywanie metod poprzez ingerencję w ich kodzie?

Problem praktyczny:
Mam apkę do przeglądania tego forum, która składa się z klas:

*Topic* - klasa abstrakcyjna, przechowuje wątek z forum, zwraca posty z tematu którym jest
Topic4programmers - dziedziczy po Topic, działa na naszym forum

*Post* - klasa abstrakcyjna, posty tematu, zwraca zawartość postów
Post4programmers - dziedziczy po Post, działa na naszym forum

i załóżmy, że celem apki jest to by można było se przeglądać wybrany temat i zliczyć słowa w postach. W tym wypadku nie jest konieczne przechowywanie pobranych postów, bo będą potrzebne tylko raz.

Ale co jeśli za rok se wymyślę apkę, która robi wiele operacji na postach i musiałaby je pobierać po kilka razy? Wtedy by mi się przydał wzorzec Flyweight by nie pobierać Jsoupem tych samych postów po kilka razy, bo to trwa długo: zrobiłbym Kolekcję Postów w Topic.

Jak więc jest najlepiej:

  1. od początku dodać funkcjonalność w stylu Flyweight, rozbudowanie klas na wyrost, a nóż się przyda.
  2. robić minimalne funkcjonalności i potem dziedziczyć po klasie Topic4programmers, żeby w tej nowej ponadpisywać niektóre metody i dołozyć?
  3. robić minimalne funkcjonalności i potem edytować obecne klasy.
1

Czy rozszerzenie oznacza tylko dziedziczenie

Może też oznaczać kompozycję, albo inny sposób na rozszerzenie funkcjonalności, choćby pluginy (swoją drogą z dziedziczeniem trzeba ostrożnie, bo samo dziedziczenie to często najprostsza droga do pogwałcenia zasady open close czy paru innych zasad).

i załóżmy, że celem apki jest to by można było se przeglądać wybrany temat i zliczyć słowa w postach.
...
Ale co jeśli za rok se wymyślę apkę, która robi wiele operacji na postach i musiałaby je pobierać po kilka razy?

A wiesz, że pobieranie postów, a zliczanie słów w postach to 2 różne operacje? To nie powinno być w ogóle w jednej klasie (ale to już zasada single responsibility principle).

0
LukeJL napisał(a):

i załóżmy, że celem apki jest to by można było se przeglądać wybrany temat i zliczyć słowa w postach.
...
Ale co jeśli za rok se wymyślę apkę, która robi wiele operacji na postach i musiałaby je pobierać po kilka razy?

A wiesz, że pobieranie postów, a zliczanie słów w postach to 2 różne operacje? To nie powinno być w ogóle w jednej klasie (ale to już zasada single responsibility principle).

no i nie jest w 1 klasie, ale jest w 1 apce...

chodzi o to, że teraz cała apka używa każdy post raz i wszystko działa tak jak chce. Ale jeśli za rok rozszerzę apkę i będzie używać każdego postu po 10 razy to mi się będzie 10 razy wywoływały połączenie do 4programmers.net dla kazdego postu i będzie to trwało wieki. Wobec tego czy zawczasu powinienem to przeiwidzieć i dodać flyweight , który być może za rok wykorzystam czy raczej stawia się na minimalizm a za rok se rozszerzę jakimiś dekoratorami, kompozycjami o flyweight?

0
Julian_ napisał(a):

Ale co jeśli za rok se wymyślę apkę, która robi wiele operacji na postach i musiałaby je pobierać po kilka razy? Wtedy by mi się przydał wzorzec Flyweight by nie pobierać Jsoupem tych samych postów po kilka razy, bo to trwa długo: zrobiłbym Kolekcję Postów w Topic.

Wtedy właściciel forum zajrzy do logów dlaczego mu serwis siada i zablokuje Ci apkę.

0

Dlatego pytanie czy lepiej na zapas robić flyweight czy dopiero wtedy gdy będę potrzebował?

2

Wobec tego czy zawczasu powinienem to przeiwidzieć i dodać flyweight ,
który być może za rok wykorzystam czy raczej stawia się na minimalizm
a za rok se rozszerzę jakimiś dekoratorami, kompozycjami o flyweight?

Najlepiej wyizolować ten fragment tak, żeby reszta aplikacji nie wiedziała, czy jest to flyweight czy nie. Wtedy mógłbyś teraz zrobić bez, a jeśli kiedyś będziesz potrzebował, to bez problemu dodasz ten flyweight na biegu.

Dlatego pytanie czy lepiej na zapas robić flyweight czy dopiero wtedy gdy będę potrzebował?

Tak ogólnie - to lepiej myśleć na zapas, ale implementować tylko to, co w danym momencie potrzebne.

Tzn. myśleć po to, żeby przewidywać potencjalne problemy i żeby nie wpakować się w jakąś złą decyzję projektową robiąc bez przemyślenia i nie przewidując zawczasu problemów. Myśleć po to, żeby mieć w głowie obraz projektu w zarówno szerszym (np. jakie potencjalne zmiany biznesowe mogą się przydarzyć) jak i głębszym projekcie (dochodząc do szczegółów implementacyjnych i który sposób implementacji będzie najlepszy)

Ale to nie znaczy, że trzeba wszystko implementować od razu. Te całe zasady (SRP, OC czy inne) są fajne właśnie dlatego, że pozwalają na opóźnienie decyzji o implementacji. OC znaczy, że robisz coś dzisiaj, a jutro tego używasz i komponujesz większe całości bez modyfikacji oryginalnego komponentu. SRP znaczy, że dzielisz aplikację na takie części, żeby ich developerka była niezależna od siebie ("A class should have only one reason to change.").

Czyli w zasadzie najlpeiej zrobić aplikację tak, żeby ten flyweight by można było łatwo dodać, jeśli będzie taka potrzeba.

Najlepiej też wcześniej zrobić prototyp rzeczy, które się planuje dodać, żeby nie było potem zaskoczenia, że czegoś się nie da.

1 użytkowników online, w tym zalogowanych: 0, gości: 1