Konstruktor a dobry styl programowania

0

Czołem,

Chciałem zapytać się, jak daleko można pójść z operacjami wykonywanymi w konstruktorze tak, żeby było to zgodne z dobrym stylem programowania.

Sprawa dotyczy konstruktora obiektu, który jest głównym obiektem w moim programie: koordynuje wątki i jest interfejsem między użytkownikiem, a resztą programu. Chciałbym, żeby konstruktor "przygotował" obiekt, to jest: wyświetlił powitanie, pobrał parametry startowe od użytkownika i wygenerował obiekty startowe programu. Ten zestaw opcji jest trochę obszerny, ale stanowi faktyczną konstrukcję obiektu - bez wykonania któregoś z kroków obiekt jest bezwartościowy i niezdolny do współpracy z użytkownikiem.

Czy powinienem wyodrębnić jakąś osobną metodę typu "przygotuj", którą jawnie wywołam sobie po utworzeniu obiektu?

0

A może warto wykorzystać pewne możliwości które daje C++ i takie rzeczy jak wypisanie powitania zamknąć w zwykłej funkcji, a faktyczne operacje związane z obiektami wykonywać na obiektach?

0

który jest głównym obiektem w moim programie

To już jest niezgodne z dobrym stylem programowania ;)

wyświetlił powitanie, pobrał parametry startowe od użytkownika i wygenerował obiekty startowe programu

Wszystko oprócz ostatniego (generowanie obiektów) jest zupełnie niedopuszczalne w konstruktorze jeśli chociaż trochę Ci zależy na jakośc kodu.

Czy powinienem wyodrębnić jakąś osobną metodę typu "przygotuj", którą jawnie wywołam sobie po utworzeniu obiektu?

Byłoby to już lepsze rozwiązanie... Ale może spróbuj(my) się zastanowić co właściwie chcesz osiągnąć i czy na pewno ten wszechmogący obiekt (antywzorzec) jest konieczny?

0

Wobec tego bardziej szczegółowo:

Program jest grą tekstową.

Obiekt:
Czynności przygotowawcze:

  • wyświetlenie ekranu powitalnego
  • pobranie parametrów wejściowych (nowa gra, ładuj grę...)
  • (jeśli jest żądana przez użytkownika) kompilacja plików źródłowych kodu świata gry
  • ładowanie świata gry z plików i (jesli jest żądane) ładowanie zapisanego stanu gry

Działanie :
Utwórz dwa wątki:

  • jeden z wątków w pętli pobiera kolejne rozkazy z klawiatury i wrzuca je do kolejki (pętla komend)
  • drugi z wątków kolejno: obsługuje rozkaz i utrzymuje świat (pozwala światowi "wykonać" czynności związane z upływem czasu) (pętla świata)

Z tego, co pamiętam, pół roku temu myślałem nad utrzymaniem tego w ramach funkcji main(), ale pierwotnie sam obiekt miał być bardziej rozbudowany, później dopiero został okrojony do, w zasadzie, "utrzymywacza wątków". Jakoś zostałem tak nauczony, że w ramach funkcji main() powinno być tak mało kodu, jak to jest możliwe, reszta powinna siedzieć w obiektach.

Do tego metoda wątku "pętli świata" musi posiadać w sobie obiekty mapy świata i mapy bohaterów (tworzone podczas ładowania), przekazuję je (trochę kombinując) przekazując do metody statycznej wątku wskaźnik do mojego obiektu silnika; w przypadku uzycia funkcji main musiałbym zrobić zmienne globalne dla tych map, albo jakiś sztuczny obiekt, który będzie w sobie "transportował" wskaźniki.

[edit]
Zauważyłem, że podobną sytuację wyrzeźbiłem w obiekcie, który również jest singletonem; w tym wypadku jest to mocno uzasadnione: jest to obiekt zawierający słownik na potrzeby gry (odmiana polskich wyrazów). Również tu w ramach konstruktora pobieram z plików i ładuję dane. Dla mnie rozwiązanie w konstruktorze jest eleganckie, konstruktor wygląda tak:

LangUtil::LangUtil() {
	log.info("Budowanie slownikow.");
	wypelnijRzeczowniki();
	wypelnijLiczebniki();
	wypelnijPrzymiotniki();
	wypelnijPrzyslowki();


}

Również tworzenie obiektu w grze wygląda spokojnie, bo:

//Piszę tak:

LangUtil lang;

//Zamiast, na przykład.

LangUtil lang;
lang.inicjalizuj();

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