Tworzenie szkieletu programu

0

Mam do napisania program, który będzie generował raporty PDF. Każdy raport będzie (lub nie- w zależności od wyboru) składać się z kilku sekcji:

  • Sekcji tytułowej
  • Sekcji pomiarowej kształtu
  • Sekcji pomiarowej odległości
  • Sekcji pomiarowej płaskości
  • Sekcji podsumowania.

Każda z sekcji pomiarowych będzie się składać z kilku identycznych(dla danej sekcji) bloków z różnymi informacjami (liczba powstałych sekcji i bloków może być różna dla każdego raportu, dane te będę otrzymywał w jednej zbiorczej strukturze). Każdą sekcję pomiarową będzie kończyć podsumowanie, a sekcja podsumowania będzie zbiorem wszystkich podsumowań z sekcji pomiarowych.

Mam problem z ułożeniem sobie w głowie szkieletu tego programu.
Wymyśliłem, że zrobię tak:

class FilePDF
{
private:
	HPDF_Doc pdf;
	std::vector<HPDF_Page> page;
	std::vector<TitleSection*> ts;
	std::vector<MeasurementDistance*> md;
	std::vector<MeasurementShape*> ms;
	std::vector<MeasurementFlatness*> mf;
	std::vector<Resume*> rm;
private:
	FilePDF();
	bool createFile(void);
public:
	~FilePDF();
	bool saveFile(void);
	static FilePDF& getInstance(void);
	bool createTitleSection(void);
	bool createMeasurementSectionShape(void);
	bool createMeasurementSectionDistance(void);
	bool createMeasurementSectionFlatness(void);
	bool createResume(void);
}

class TitleSection{
	private:
		HPDF_Doc *pdf;
		HPDF_Page *page;
	public:
		bool createTitleBox(void);
		TitleSection(HPDF_Doc &pd, HPDF_Page &pa);
};

class MeasurementDistance{
	private:
		HPDF_Doc *pdf;
		HPDF_Page *page;
	public:
		bool createDistanceBox(void);
		MeasurementDistance(HPDF_Doc &pd, HPDF_Page &pa);
};

class MeasurementShape{
	private:
		HPDF_Doc *pdf;
		HPDF_Page *page;
	public:
		bool createShapeBox(void);
		MeasurementShape(HPDF_Doc &pd, HPDF_Page &pa);
};

class MeasurementFlatness{
	private:
		HPDF_Doc *pdf;
		HPDF_Page *page;
	public:
		bool createFlatnessBox(void);
		MeasurementFlatness(HPDF_Doc &pd, HPDF_Page &pa);
};

class Resume {
	private:
		HPDF_Doc *pdf;
		HPDF_Page *page;
	public:
		bool createResume(void);
		Resume(HPDF_Doc &pd, HPDF_Page &pa);
};


//przykładowe wywołanie funkcji createXXX
FilePDF::createMeasurementSectionShape(void) {
	
	for (int j = 0; j < size/3; j++) {
		page.push_back(HPDF_AddPage(pdf));
		
	 	for(int i = 0; i < 3; i++) {
	 		ts.push_back(new  MeasurementShape(pdf, page[page.size()-1]));
			ts[ts.size() - 1]->createShapeBox();
		 }		
	}
	rm.push_back(new Resume(pdf, page[page.size()-1]));
	
}

Stworzyłem klasę nadrzędną FilePDF, która tworzy mi dokument (wykorzystałem wzorzec singleton). Klasa ta definiuje metody to tworzenia poszczególnych sekcji createTitleSection(), createMeasurementSectionShape(), createMeasurementSectionDistance(), createMeasurementSectionFlatness(),createResume(). W metodach tych tworzę dynamicznie obiekty klas podrzędnych, odpowiadających za tworzenie bloków (kompozycja). Na razie nie zadeklarowałem jeszcze parametrów funkcji, dlatego wszędzie jest void. Czy to jest dobry kierunek i dobry tok rozumowania? Nie mogę sobie wyobrazić jak inaczej podjeść do problemu. Słabą stroną mojego rozwiązanie jest to, że w konstruktorach klas podrzędnych muszę przekazywać parametry odnoszące się do całego dokumentu.(pdf, page, font...).

0

Przepraszam za rubaszne sformułowanie, ale po kiego grzyba ci tyle klas?

0

Hmm. W sumie nie wiem. Chcialem kazdy blok zrobic jako oddzielna klasa ale jak najbardziej moge to samo zrobic w klasie FilePDF. Zazwyczaj jak sie czyms zasugeruje to ciezko mi spojrzec z innego punktu widzenia. Dlatego napisalem ten post :)

0
mlp99 napisał(a):

Hmm. W sumie nie wiem.

Jeśli ty nie wiesz, to my tym bardziej wiedzieć nie będziemy. Jeśli tworząc jakieś narzędzie nie jesteś w stanie określić po co piszesz dany kod/klasę/moduł to tracisz czas wykonując zbędną pracę.

Chcialem kazdy blok zrobic jako oddzielna klasa ale jak najbardziej moge to samo zrobic w klasie FilePDF.

Problemy dzieli się na mniejsze jeśli problem jest złożony i wygodniej jest operować na niejszych jednostkach, bo każdą trzeba traktować w zupełnie odmienny sposób, lub składać z tych klocków jakieś większe całości na różne sposoby. Czy te sekcje różnią się od siebie aż tak znacznie, by każdą traktować inaczej niż pozostałe? Czy będą one poddawane jakimś złożonym działaniom, by był sens je wyodrębniać w ogóle?

Zazwyczaj jak sie czyms zasugeruje to ciezko mi spojrzec z innego punktu widzenia. Dlatego napisalem ten post :)

Czym się zasugerowałeś? Generowanie raportów można realizować na setki sposobów w zależności od wymagań wobec tego raportu i ewentualnego przetwarzania danych przed umieszczeniem ich w treści. Pytanie tylko, czy rozwiązanie, którym się sugerowałeś, ma wystaczająco wiele wspólnego z tym co planujesz napisać.

0

Sugerowalem sie jednozadaniowoscia klasy. Ale teraz widze, ze bez sensu potworzylem te klasy bo wszystkie sekcje beda podobnie tworzone i przetwarzane. Wlasnie to jest najwiekszy problem pisania programow dla mnie.Co i kiedy stosować. Ksiazki zazwyczaj opisuja tylko jak cos stosowac.

0
mlp99 napisał(a):

Sugerowalem sie jednozadaniowoscia klasy. Ale teraz widze, ze bez sensu potworzylem te klasy bo wszystkie sekcje beda podobnie tworzone i przetwarzane. Wlasnie to jest najwiekszy problem pisania programow dla mnie.Co i kiedy stosować. Ksiazki zazwyczaj opisuja tylko jak cos stosowac.

Stosować coś, kiedy widzisz, że pasuje i ma sens. Nie stosować czegoś, jeśli widzisz, że sensu to nie ma. Najlepszym narzędziem jest zadawanie sobie pytania "po ch*j ja to piszę w ten sposób"? Jeśli nie umiesz na nie odpowiedzieć, nie ma kontynuowanie pisania w ten sposób sensu. Uświadom sobie, jakie części są w zadaniu najważniejsze, najczęściej wykonywane i warte wyodrębnienia. To podstawa dzielenia programu na części w jakimkolwiek paradygmacie.

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