Powiedzmy, że mam klasę wroga, a konstruktor wyglądałby mniej więcej tak:
public Enemy(String name, float width, float height, Vector2 position,
float speed, int maxHp, int attackDamage, int defense... etc.){}
Wygląda to źle, ponieważ konstruktor ma tak wiele parametrów, ale kiedy tworzę instancję wroga, muszę określić wszystkie te rzeczy. Chcę również tych atrybutów w klasie Enemy, abym mógł iterować ich listę i uzyskać / ustawić te parametry. Myślałem, że może podklasę Enemy do EnemyB, EnemyA, jednocześnie kodując ich maxHp i inne specyficzne atrybuty, ale wtedy straciłbym dostęp do ich zakodowanych atrybutów, gdybym chciał iterować listę EnemyA (składającą się z EnemyA, EnemyB i EnemyC).
Próbuję tylko nauczyć się, jak kodować w sposób czysty. Jeśli to robi różnicę, pracuję w Javie / C ++ / C #. Doceniany jest każdy punkt we właściwym kierunku.
Odpowiedzi:
Rozwiązaniem jest połączenie parametrów w typy kompozytowe. Szerokość i wysokość są powiązane koncepcyjnie - określają wymiary wroga i zwykle będą potrzebne razem. Można je zastąpić
Dimensions
typem, a może takżeRectangle
typem obejmującym pozycję. Z drugiej strony, może to więcej sensu do grupyposition
ispeed
doMovementData
rodzaju, szczególnie jeśli przyspieszenie później wchodzi w obraz. Z kontekstu ZakładammaxHp
,attackDamage
,defense
itp należą również razem wStats
rodzaju. Zmieniony podpis może wyglądać mniej więcej tak:Dokładne informacje o tym, gdzie narysować linie, będą zależeć od reszty kodu i od tego, jakie dane są powszechnie używane razem.
źródło
Enemy
jest tylko klasą atakowanąPlayer
, ale ich wspólna klasa podstawowaCombatant
potrzebuje statystyk walki.Dimensions
/MovementData
jako zwykłych starych kontenerów danych) lub metodami (jeśli zamieni je w dane abstrakcyjne typy / obiekty). Na przykład, jeśli jeszcze nie stworzyłVector2
typu, mógł skończyć matematyką wektorowąEnemy
.Możesz rzucić okiem na wzorzec Konstruktora . Z linku (z przykładami wzorca kontra alternatywy):
źródło
Używanie podklas do ustawiania niektórych wartości nie jest pożądane. Tylko podklasę, gdy nowy typ wroga ma inne zachowanie lub nowe atrybuty.
Wzór fabryki jest zwykle używany do abstrakcyjny nad dokładnym klasy używanego, ale może być również wykorzystane w celu zapewnienia szablonów do tworzenia obiektów:
źródło
Zarezerwowałbym podklasę dla klas reprezentujących obiekt, który możesz chcieć samodzielnie wykorzystać, np. Klasę postaci, w której wszystkie postacie, nie tylko wrogowie, mają imię, prędkość, maxHp lub klasę reprezentującą duszki, które są obecne na ekranie o szerokości, wysokość, pozycja.
Nie widzę nic z natury złego w konstruktorze z wieloma parametrami wejściowymi, ale jeśli chcesz go trochę podzielić, możesz mieć jednego konstruktora, który ustawia większość parametrów, i innego (przeciążonego) konstruktora, którego można użyć aby ustawić określone, a inne ustawić na wartości domyślne.
W zależności od wybranego języka niektórzy mogą ustawić wartości domyślne parametrów wejściowych konstruktora, takie jak:
źródło
Przykład kodu, który należy dodać do odpowiedzi Rory Hunter (w Javie):
Teraz możesz tworzyć nowe instancje wroga w następujący sposób:
źródło