java, wzorzec, porada co użyć i jak

java, wzorzec, porada co użyć i jak
0

Mam pewna klase, dajmy na to (pseudokod):

Kopiuj
String type = getType();

if ("ALA".equals(type) {
  new ALAMode(x).execute(y);
} else if ("BEATA".equals(type) {
 new BEATAMode(x).execute(y):
}
...

Jaki jest prosty sposob na zrobienie tego "inteligentniej"?

Myślałem o czyms w stylu:
Class c = Class.forName("com.package." + type + "Mode");
Object obj = c.newInstance();

i pozniej przerzutowac jakos i zawolac execute, ale moze sa lepsze sposoby?

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
3

Class.forName to rak.
Alternatywa to taki np. rejestr:

Kopiuj
final HashMap<String, BiFunction2<X,Y, ???> > reg   = 
reg.put("ALA", x,y -> new ALAMode(x).execute(y));
reg.put("BETA", x,y -> new BETAMode(x).execute(y));
...
...

[...]
reg.get(getType()).apply(x,y);

Albo lepiej jak ALAMode i BETAMode mają interfejs executable.
i wtedy

Kopiuj
final HashMap<String, Function1<X, Executable> > reg   = 
reg.get(getType()).apply(x).execute(y);

i gotowe.


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 3x, ostatnio: jarekr000000
nie100sowny
Ha. Cudownie wiedzieć, że są inni którzy tak eliminują switche :)
0

Dzieki!

Wyglada pro, musze doczytac troche :)

Tylko oprocz metody execute, chce moc wywolywac tez inne z tych klas (ze wspolnego interfejsu), potrzebuje wlasnie caly ten obiekt, zastanawiam sie w ogole nad czyms prostszym:

Kopiuj
final HashMap<> reg = new HashMap<String, IMode>();
      reg.put("ALA", new ALAMode());
      req.put("BEATA", new BEATAMode());

      IMode mode = reg.get(getType());
      mode.setProps(x);

      mode.execute();
      mode.doSTh();
SN
  • Rejestracja:ponad 6 lat
  • Ostatnio:ponad 6 lat
  • Postów:11
0
  1. A czy x jest znany przed budowaniem tego rejestru? Bo jeśli tak, to bym go przekazywał do konstruktorów tych AL i BEAT zamiast ustawiać setProps().
    A nawet jeśli nie, to wolałbym
Kopiuj
mode.execute(x);

zamiast

Kopiuj
mode.setProps(x);
mode.execute();
  1. A co robi getType()?
nie100sowny
  • Rejestracja:około 9 lat
  • Ostatnio:około 22 godziny
  • Lokalizacja:Kraków
  • Postów:402
1
jarekr000000 napisał(a):

Class.forName to rak.
Alternatywa to taki np. rejestr:

Kopiuj
final HashMap<String, BiFunction2<X,Y, ???> > reg   = 
reg.put("ALA", x,y -> new ALAMode(x).execute(y));
reg.put("BETA", x,y -> new BETAMode(x).execute(y));
...
...

[...]
reg.get(getType()).apply(x,y);

Albo lepiej jak ALAMode i BETAMode mają interfejs executable.
i wtedy

Kopiuj
final HashMap<String, Function1<X, Executable> > reg   = 
reg.get(getType()).apply(x).execute(y);

i gotowe.

Jeszcze można zamiast .get wykorzystać .getOrDefault gdzie default to będzie nic nie robiąca lambda lub NullObject pattern. Wówczas zabezpieczamy się przed NPE.


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"
CS
  • Rejestracja:prawie 7 lat
  • Ostatnio:dzień
  • Postów:296
1

A może coś w ten deseń:

Kopiuj
enum Modes {
    ALA(new ALAMode()),
    BEATA(new BEATAMode());
    private final Mode mode;
    Modes(Mode mode){
        this.mode = mode;
    }
    
    Mode getModeObject(){
        return this.mode;
    }
}

interface Mode {
    void execute(int y);
}

class ALAMode implements Mode {
    @Override
    public void execute(int y) {
         System.out.println("ALA "+y);
    }
}
class BEATAMode implements Mode {
    @Override
    public void execute(int y) {
        System.out.println("BEATA "+y);
    }
}

Modes m = Modes.valueOf(getType());
m.getModeObject().execute(10);
edytowany 1x, ostatnio: cs
0

ten enum tez wyglada fajnie, nie pomyslalbym o tym :)

Zastanawiam się nad bezpieczeństwem takiego rozwiazania ( w porównaniu do chamskiego new Mode w ifach).

Załózmy ze te Mody wolaja inne serwisy, a kolei wiele rzeczy będzie rownoczesnie wolac te Mody.

Ale rozumiem, że dopoki każdy Mode nie przechowuje stanu w obiekcie, tylko ma metodki, to metody daja nam bezpieczenstwo, że każde wywolanie jest niezalezne itp.

CS
  • Rejestracja:prawie 7 lat
  • Ostatnio:dzień
  • Postów:296
0

Jeśli obiekty implementujące Mode będą niemutowalne to nie powinno być problemów ze współbieżnością. Problemem jest tylko ewentualny argument konstruktorów klas implementujących Mode np. new ALAMode(x). Jeśli wartość x jest ściśle określona dla każdego moda to nie ma problemu tworzysz enum {ALA(new AlaMode(value_for_ALA)) ...}, ale jeśli nie to trzeba zrobić setera i kombinować np. aby x było typu AtomicXXX z pakietu java.util.concurrent.atomic, ale to już zależy jak wykorzystywany jest ten x.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.