2012-03-15 12 views
5

Mam wspólny jar, który używa pewnego unmarshaling obiektu String. Metoda powinna działać inaczej w zależności od aplikacji, z której jest wywoływana, jak to zrobić, oprócz tego, że mogę zidentyfikować aplikację, próbując załadować jakąś unikalną klasę, którą ma (nie lubię). Czy istnieje jakiś wzór, który rozwiązuje ten problem?Jak zmienić zachowanie metody zgodnie z aplikacją, która go nazywa?

+12

The „wzorzec projektowania”, który _should_ być przy użyciu jest po prostu nie mają zmiany zachowania metody na podstawie czynników zewnętrznych! Różne zachowanie powinno być inną metodą. – cdeszaq

+4

I sekunda komentarza @ cdeszaq. Jest to słoik ** pospolity ** ze wspólną funkcjonalnością lub ** dla ** szczególnych aplikacji. Jeśli próbujesz oddzielić wspólny kod w zewnętrznym słoiku, jest to dobre. Ale musisz też napisać ten kod, jakby nie wiedział, kto to nazwie (unikaj logicznych odwołań w kodzie). – MicSim

Odpowiedz

3

Jak wspomniałem w moim komentarzu, najlepszą rzeczą do zrobienia jest rozbicie tej metody uber na różne metody, które obejmują określone zachowania, i prawdopodobnie także inną metodę (używaną przez wszystkie aplikacje specyficzne dla aplikacji). te), które dotyczą wspólnych zachowań.

Najważniejszą rzeczą do zapamiętania jest to, że zachowanie ma znaczenie. Jeśli coś działa inaczej w różnych scenariuszach, aplikacja wywołująca nie może skutecznie używać tej metody, ponieważ nie ma żadnej kontroli nad tym, co się dzieje.

Jeśli nadal naprawdę chce mieć jedną metodę, że wszystkie aplikacje telefon, że zachowuje się inaczej w każdej z nich, to może to zrobić, stosując pewien wzorzec projektowy, w sposób, który ma sens i jest do utrzymania. Wzór nosi nazwę "Template Method".

Generalna koncepcja polega na tym, że aplikacja wywołująca przekazuje kawałek logiki, że wywoływana metoda owija się i wywołuje, gdy jest taka potrzeba. Jest to bardzo podobne do programowania funkcjonalnego lub programowania przy użyciu zamknięć, gdzie przekazujesz fragmenty logiki, jakby były danymi. Mimo że Java nie obsługuje zamknięć, inne języki oparte na JVM, takie jak Groovy, Scala, Clojure, JRuby itp. do zamykają obsługę.

Ta sama ogólna idea jest bardzo potężny w pewnych okolicznościach i może zastosowanie w Twoim przypadku, ale takie pytanie wymaga bardzo intymną wiedzę o domenie aplikacji i architektury, a tak naprawdę nie ma wystarczająco dużo informacji w wysłane pytanie wykopać zbyt głęboko.

2

Właściwie, myślę, że dobrym rozwiązaniem zorientowanym na OO jest, we wspólnym słoiku, posiadanie jednej klasy bazowej i kilku klas pochodnych. Klasa podstawowa zawierałaby wspólną logikę dla wywoływanej metody, a każda klasa pochodna zawierałaby określone zachowanie.

Tak w słoiku, może mieć następujące:

public abstact class JarClass { 
    public method jarMethod() { 
     //common code here   
    } 
} 

public class JarClassVersion1 extends JarClass { 
    public method jarMethod() { 
     // initiailzation code specific to JarClassVerion1 
     super.jarMethod(); 
     // wrapup code specific to JarClassVerion1 
    } 
} 

public class JarClassVersion2 extends JarClass { 
    public method jarMethod() { 
     // initiailzation code specific to JarClassVerion2 
     super.jarMethod(); 
     // wrapup code specific to JarClassVerion2 
    } 
} 

, jak działa rozmówcy, jeśli są chętni do projektowania swój kod tak, że wiedza, która pochodzi klasę do korzystania mieszka z wywołujący, wtedy oczywiście po prostu wywołujesz wywołanie odpowiedniej klasy pochodnej i wywołujesz jarMethod.

Jednak biorę to z twojego pytania, chcesz wiedzieć, której klasy użyć, aby zamieszkać w słoiku. W takim przypadku istnieje kilka rozwiązań. Ale dość łatwo jest zdefiniować metodę fabryczną wewnątrz słoika, która tworzy odpowiednią klasę pochodną.Tak, wewnątrz abstrakcyjnego JarClass, można określić w następujący sposób:

public static JarClass createJarClass(Class callerClass) { 
    if (callerClass.equals(CallerClassType1.class)) { 
     return new JarClassVersion1(); 
    } else if (callerClass.equals(CallerClassType2.class)) { 
     return new JarClassVersion1(); 
     // etc. for all derived classess 
} 

a następnie dzwoniący po prostu wykonaj następujące czynności:

JarClass.createJarClass(this.getClass()).jarMethod(); 
Powiązane problemy