Tworzenie interfejsu dla getterów

0

Cześć. Jako, że Java nie supportuje multi-bazowego dziedziczenia, zastanawiam się nad pewną sytuacją. Otóż moje klasy muszą dziedziczyć po innych i od tego odstąpić nie mogę. Zastanawiam się jednak nad zrefactorowaniem tej części projektu na a'la Strategię. Implementowany interfejs zawierałby jednak wyłącznie gettery do pól. Na dobrą sprawę to widzę same plusy tego rozwiązania, bo chociaż nie upraszcza znacząco struktury kodu w stosunku do obecnego rozwiązania, to jednak w tym przypadku przestrzegamy zasady open-closed i przyspieszamy dodawanie nowej funkcjonalności. Niby fakt, że sobie po części odpowiedziałem, ale nigdy nie widziałem takiego rozwiązania i zastanawiam się, czy ktoś nie spojrzy na to krzywym okiem jako anty-pattern.

0

Pokaż kod

0

Mam wrażenie że nie chodzi Ci o strategię, tylko o metodę szablonową. Daj kawałek pseudokodu bo nie do końca rozumiem problem.

0

Nie, nie jest to metoda szablonowa. Typowa strategia też to do końca nie jest, w zasadzie nosi tylko kilka jej znamion. No dobra, nieco pseudo kodu:

Tworzymy interface zawierający wyłącznie gettery.

 public interface Functionality {
    public String getProperty1;
    public Object getProperty2;
    //...
}

Implementujemy go w kilku klasach. Każda jest odpowiedzialna za pewną konkretną i zamkniętą w tej klasie funkcjonalność programu.

public class SomeFunctionality extends InevitibleInheritanceClass1  implements Functionality {
    public String property1;
    public Object property2;
    //...
    public String GetProperty1() {
         return property1;
}
    //...
}

Wykorzystujemy je w innej klasie

public class SomeClass extends InevitibleInheritanceClass {
    public void addNewFunctionality(Functionality f) {
        //operations
    }
}
0

Ale dlaczego w takim razie w ogóle dziedziczenie/implementowanie interfejsu a nie delegacja? Dlaczego obiekt z tymi propertisami nie jest składową?

0

Poprzednia struktura projektu wymaga, by dla każdej nowej funkcjonalności dodać trzy klasy, które zdecydowanie mogłyby być przeprojektowane w jedną i nadal trzymać się zasady jedna klasa, jedna odpowiedzialność. W tej strukturze wykorzystałem właśnie delegację. Jednak, tak jak mówiłem, nie jestem zadowolony z tego rozwiązania.

W nowym rozwiązaniu aby dodać nową funkcjonalność wystarczy stworzyć jedną klasę i wywołać jedną metodę. Klasa obsługująca to jest zamknięta na modyfikacje. Muszę jednak dla tego celu stworzyć interfejs, który powoli mi z każdej funkcjonalności wybrać konkretne jej pola.

2

No dobra ale w takim kodzie który pokazałeś to każde Functionality ma zduplikowane pola, tzn w każdej z tych klas definiujesz te same pola?
Jeśli faktycznie musisz taką dziwną strukturę mieć to zacząłbym chociażby od czegoś takiego:

class FuntionalityProperties implements Functionality{
    private final String property1;
    private final Object property2;
    //...
    public String GetProperty1() {
         return property1;
    }
    //...
};
public class FunctionalityBase extends InevitibleInheritanceClass implements Functionality {
    private final FuntionalityProperties properties;
    //...
    public String GetProperty1() {
         return properties.GetProperty1();
    }
    //...
}
1

@Lectre słuchaj @Shalom on ma rację. Interfejs + delegacja są znacznie prostsze i pozwalają na dużo większą elastyczność.

interface Functionality{

    default String getProperty1(){
        return getProperties().get1();
    }

   Properties getProperties(); // to sobie implementujesz
  
   class Properties{
     // lista propsów
   }
}

BTW, GWT używa interfejsów typu HasName, HasValue itp.

0

Dzięki Shalom, podsunąłeś mi bardzo dobry pomysł. Dzięki temu wymyśliłem coś jeszcze lepszego (co chyba chciałeś mi podsunąć wcześniej, ale nie załapałem). Pozmieniałem nieco i w FunctionalityBase użyję delegacji nie tylko do propertiesów, ale i do klasy, którą wcześniej dziedziczyłem.

1

Ja myślałem, że skoro musisz dziedziczyć to musisz (bo np. masz kod który przyjmuje obiekty tej klasy i nie ma interfejsu do niego więc te twoje Funtionality muszą z tej klasy dziedziczyć). Ale skoro masz tam jakiś interfejs to znacznie lepiej będzie w tej bazowej klasie delegować zamiast dziedziczyć ;)

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