Zasoby i projektowanie klas

0

Witam. Mam pewien problem. Chcę stworzyć klasę Army, która przechowuje żołnierzy różnego typu: bohaterów(+3), jednostki specjalne(+2), jednostki podstawowe(+1). W nawiasach podałem ile dodatkowych zdolności może posiadać każda z nich (nazwa + opis - 2 stringi). Poza tym, wszystkie mają prawie te same rzeczy do przechowywania. No właśnie - prawie. Najlepiej byłoby tak, żeby każda klasa wyższego stopnia rozszerzała poprzednią, czyli basic -> special -> hero, przy czym w każdej następnej dostępne byłoby o jedno pole więcej dodatkowej umiejętności. Problem jest taki, że np. osobnik A klasy hero posiada 2 PODSTAWOWE umiejętności, a osobnik B, również klasy hero, - 3 umiejętności. Równie dobrze np. soldier klasy basic ma 0 podstawowych, a archer, też klasy basic, ma 2 podstawowe.
Jak rozwiązać ten problem, żeby nie robić niepotrzebnych pól?

  1. Od razu w klasie podstawowej dodać 3 pola umiejętności podstawowej, i w zależności od potrzeb używać od 0 do 3 potrzebnych?
  2. Dodać pole, które trzyma ilość podstawowych umiejętności, oraz jakiś ArrayList, na którego będę wrzucał podstawowe umiejętności w konstruktorze?
  3. jakoś inaczej?

Drugi problem:
Jako że opisy skilli, itemów, nazwy, etc. mogą się zmieniać, wszystko chcę trzymać w plikach txt (pewnie w xmlu byłoby przyjemniej, bardziej profesjonalnie i więcej możliwości, ale nie umiem XMLa, a zanim wezmę się za jego naukę chcę napisać coś prościej, aby utrwalić sobie zdobyte informacje). Jest takie fajne polecenie: getClass().getResource(String path).
Nie byłoby problemu, gdyby zasoby były w tym samym katalogu co plik .class, albo dalej zagnieżdżone. Ale załóżmy że mamy folder Program, a tam foldery: Characters i Resources i łatwo się domyślić, że plik .class będzie w Program/Characters/bin a dany zasób w Program/Resources. Oczywiście istnieje możliwość podania pełnej ścieżki, np D://Java/hehe/test/.../Program/Resources, ale zakładam, że będę chciał program spakować w .jar i np. użyć na innym komputerze, co wtedy? Jak uzyskać dostęp z katalogu Character/bin do Resources? Żeby tak się cofnąć do folderu głównego i wejść do innego.

Proszę o pomoc i z góry dziękuję za odpowiedź.

1

Ad.1.
Dużo zależy od tego jak potem chcesz z tego korzystać. Niemniej jednak opcja 2) jest jedyną sensowną. Jednocześnie pomyślałbym o tym czy dziedziczenie jest tu dobrym rozwiązaniem i czy nie lepszy byłby dekorator z delegacją, ale tu znów wszystko zależy od tego jak potem tych klas chcesz używać.

Ad.2.
../ i jesteśmy wyżej o 1 poziom, ../../ i o dwa!

1

ad 2. System.getProperty("user.home") i mamy położenie katalogu domowego użytkownika.
Co do XMLa to zapoznaj się z np. bibliloteką Jackson, która w wersji 2.0 wspiera xmla. Jedyne co będziesz musiał wiedzieć na tym etapie ograniczny się do tego, że pliki xml istnieją.

0

Dziękuję za pomoc, pobawię się z tym.

Shalom - Hmmm, poczytałem trochę o tym wzorcu projektowym i przyznam, że ciekawa opcja.
Co do zastosowania:

  1. tworzymy armię: możemy stworzyć daną jednostkę (która ma swój koszt), która zostaje dodana to JList (umieszczony w prawej części panelu dzielonego); dane danej jednostki wyświetlają się w lewej części panelu dzielonego; co więcej, w zależności od danej postaci możemy wybrać od 1 do 3 dodatkowych umiejętności (które też kosztują) oraz kupić bronie (teoretycznie nieskończenie wiele, ale ich koszt nie może przekroczyć jakiegoś limitu);
    koszt całej postaci z dodatkami sumujemy i wysyłamy do głównej karty z Armią, która nam sumuje koszt wszystkich jednostek;
  2. każda jednostka posiada kilkanaście pól (imię, statystyki, umiejętności podstawowe, koszt postaci, limit na zakup broni);

Tak więc ma to takie zastosowanie, że chcę praktycznie wszystkie informacje o danej postaci wyświetlać. Jak patrzyłem na dekorator to w wielu przykładach jest zastosowanie przesłonięcia metody, aby np. zsumować koszt bajerów do danego samochodu (http://www.algorytm.org/wzorce-projektowe/dekorator-decorator/decorator-j.html). Mi chodzi o to, żeby dodać nowe pole (a raczej dwa) z nazwą i opisem umiejętności podstawowej (lub kilku).

Odnośnie 1) zastanawia mnie jedna sprawa: kiedyś myślałem, żeby użyć do tego CardLayout, ale czy to nie byłoby pamięciożerne? W sensie trzymać gotowe komponenty? Czy nie lepiej byłoby przy każdym wybraniu postaci z listy na nowo odrysować panel?

1

Dekorator do tego właśnie służy :) Patrz np.

class Soldier implements Unit{
    int str;
    int dex;
}

class SoldierWithCośtam implements Unit{
    Soldier soldier;
    int cośtam;
}

I w takiej sytuacji masz nowego żołnierza, z dodatkowym polem, a nie ma dziedziczenia :)

0

Faktycznie :D

Ostatnie pytania: lepiej interfejsy (jak Ty zaprezentowałeś) czy klasę abstrakcyjną (jak w podanym przeze mnie przykładzie ze strony)? Czy to też od "czegoś" zależy?

Jeśli klasę abstrakcyjną, to czy dane typu imię, statystyki etc. zaimplementować właśnie w tej najgłówniejszej klasie abstrakcyjnej, wraz z ewentualnymi metodami niekoniecznie abstrakcyjnymi?

1

Interfejs reużywa tylko deklaracje pewnych metod (chyba, że korzystasz z javy 8, gdzie w interfejsie mogą istnieć już domyślne implementacje metod), klasa abstrakcyjna reużywa ich implementacje. Więc, jeżeli w każdej podklasie miałbyś mieć identyczne ciało tych metod to lepiej zamknąć to w klasie abstrakcyjnej żeby ograniczyć duplikowanie kodu.

0

Co prawda zaktualizowałem ostatnio jdk do 8 (a raczej mi wymusiło w trakcie otwierania czegoś), ale nic jeszcze się nie wtajemniczałem.

Tak czy inaczej dziękuję, o taką odpowiedź mi chodziło :)

0

@Naitoreivun to jest trochę pytanie o wyższość nart nad rowerem :) Generalnie dziedziczenie powoduje często wiele problemów, których delegacja nie ma. Jednocześnie nie zawsze da sie to w ten sposób rozwiązać i nie zawsze ma to sens.

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