2010-12-16 11 views
5
class MyThing { 
    protected HashMap<String,Object> fields; 

    protected MyThing(HashMap<String,Object> newFields){ 
     fields.putAll(newFields); 
    } 

    protected Object get(String key){ 
     return fields.get(key); 
    } 
} 

Teraz małe tło. Używam tej klasy jako super klasy do grupy różnych klas, które reprezentują obiekty z pliku XML. Jest to w zasadzie implementacja wrappera API i używam go jako adaptera pomiędzy sparsowanym XML z API a bazą danych. Przesyłanie jest delegowane do wywołującego metodę get. Jeśli podklasy muszą coś zrobić, gdy są tworzone lub zwracają zmienną, po prostu wywołują super, a następnie manipulują tym, co zostanie zwrócone później. np .:Używanie nienumerowanej klasy otoki wokół obiektów przechowywanych w XML, jest takie złe?

class Event extends MyThing {  
    public Event(HashMap<String,Object> newFields){ 
     super(newFields); 

     // Removes anything after an @ symbol in returned data 
     Pattern p = Pattern.compile("\\@.*$"); 
     Matcher m = p.matcher((String)fields.get("id")); 
     boolean result = m.find(); 

     if (result) 
      fields.put("id", m.replaceFirst("")); 
     } 
    } 

    public Object get(String key){ 
     Object obj = super(key); 

     if (key.equals("name")){ 
      return "Mr./Mrs. " + ((String)obj); 
     } 
    } 
} 

Powodem czuję się jak zrobić to tak nie mam do napisania getId, getName, metody getWhatever dla każdej podklasy tylko dlatego, że mają różne atrybuty. Zaoszczędziłoby to czas i jest dość oczywiste.

Teraz jest to oczywiście "nieślubne" i bardziej jak kunsztowny język, ale czy istnieje logiczny powód, dla którego absolutnie nie powinienem tego robić?

+0

Dlaczego nie napiszesz getString, getInt, ... metod? – thejh

+0

Nie ma w tym nic nie w porządku (imo). Dopóki użytkownicy podklasy wiedzą, że umieszczają tylko pewne przedmioty w klasie, nie ma nic złego w tym, że rzucają je w drogę. – Falmarri

+1

Zmieniłem trochę tytuł, zobacz, czy nadal pasuje do twojego zamiaru. : D –

Odpowiedz

2
  1. Oczywiście nie jest to typ bezpieczny.
  2. Przyszli opiekunowie nie będą wiedzieli, jakie typy mają być i będą ogólnie mylić, dlaczego nie używasz POJO.
  3. Zamiast stałego czasu, złożoności przestrzeni i wydajności, masz cechy HashMap.
  4. Staje się bardzo trudne pisanie niebanalnych programów pobierających/ustawiających w przyszłości.
  5. Większość systemów łączenia danych zaprojektowano do pracy z POJO/Beans (JAXB, JPA, Jackson itp.).

Jestem pewien, że jest ich więcej, ale to wystarczy. Spróbuj użyć odpowiednich bibliotek OXM, a będziesz znacznie lepiej.

3

Jeśli chcesz osiągnąć ten poziom złożoności i zmiękczania swojego modelu obiektowego tylko dlatego, że nie chcesz mieć modułów pobierających i ustawiających, zrób to zamiast tego w Groovy.

Groovy jest dynamicznym językiem wpisanym na maszynie JVM, która akceptuje 98% poprawnego kodu Java, więc znasz już większość języka (nie tracisz funkcjonalności) ... są "bardziej idiomatyczne" sposoby robienie rzeczy, ale możesz je wybrać z czasem. Ma również wbudowany XmlSlurper, który prawdopodobnie robi większość tego, co i tak próbujesz zrobić.

Jeśli chodzi o "powody, dla których nie powinieneś", wprowadzasz wszystkie rodzaje problemów związanych z konserwacją.

  1. Nowe klasy będą zawsze musiały pochodzić z klasy bazowej.
  2. Będą musieli wdrożyć konstruktora, który zawsze wywołuje konstruktor bazowy
  3. Będą musieli zastąpić get() [który jesteś w zasadzie używany do hermetyzacji swoje pobierające i ustawiające tak, dlaczego nie tylko dodać, że sposób i delegata do tych innych metod] i napisać specyficzną logikę, która z czasem ulegnie pogorszeniu.

Dlaczego nie powinieneś? To zadziała, prawda? Pewnie. Ale to kiepska inżynieria, ponieważ albo tworzysz koszmar utrzymania, albo wymyślasz koło i prawdopodobnie źle zrobisz.

+0

Podoba mi się twoja odpowiedź. Jednak kilka problemów: Groovy nie jest dla mnie opcją. Ten skrypt ma zostać przekazany do przyszłego użytku i mam duże wątpliwości, czy chcą się nauczyć nowej składni Groovy. Czy też działa na zwykłej maszynie JVM bez Groovy zainstalowanej na serwerze lub innej maszynie? Ponieważ nie mogę powiedzieć. Jeśli chodzi o "Nowe klasy będą zawsze musiały pochodzić z klasy bazowej." - nie wiem, dlaczego to jest problem. "Będą musieli zaimplementować konstruktora, który zawsze wywołuje konstruktor bazowy" - Będą musieli napisać własny konstruktor, bez względu na wszystko. i ... – AndrewKS

+0

Dla 3. Będę musiał napisać programy pobierające i ustawiające dla wszystkiego, jeśli zrobię to w normalny sposób w Javie. Zamiast tego będą one po prostu wypełniane przez publiczną funkcję getId() {return id;}, public getName() {return name;} składającą się z kilku różnych klas. Jest to zasadniczo powtarzający się kod. – AndrewKS

Powiązane problemy