Programowanie obiektowe w C++ – System rezerwacji biletów w kinie cz. III
Gościnie autorem wpisu jest Adam Sawicki.
Właściciel kina jest bardzo zadowolony z naszego oprogramowania. Zyski ciągle rosną a zarząd już wydał plany rozbudowy budynku o cztery nowe sale. Dostaliśmy zlecenie modernizacji systemu, aby obsługiwał on wszystkie pięć seansów.
Wstępnie przeanalizujmy sytuację. Nie ma najmniejszej wątpliwosci, że klient chcący dokonać rezerwacji jest już zdecydowany na konkretny film. Dlatego system powinien umożliwić najpierw wybór filmu, dopiero potem miejsca.
Podobno dwie rzeczy są w życiu pewne – śmierć i podatki. Chciałbym zasugerować jeszcze trzecią sytuację – zmiany w kodzie :-)
Przyjrzyjmy się klasie Kino. Czyż nie stanowi ona dobego materiału na klasę Film? :-) W jednej sali wyświetlany jest jeden film (przeważnie :-)), dlatego Film może zawierać tytuł filmu oraz miejsca w sali, w której jest oglądany. Rozważmy klasę Film powstałą po modyfikacji klasy Kino:
class Film { private: char tytul[100]; // dodajemy prywatną własność tytuł static const int ilosc_miejsc = 30; // resza prywatnych własności bez zmin int wybrane_miejsce; Miejsce wszystkie_miejsca[ilosc_miejsc]; public: Film() // konstruktor domyślny { strcpy(tytul, ""); // uzupełniamy konstruktor domyślny o tytuł wybrane_miejsce = 0; // reszta bez zmian int i = 0; for(i = i; i < ilosc_miejsc; i++) { wszystkie_miejsca[i] = Miejsce("","",i+1,false); } } Film(char t_tytul[]) // przeładowanie konstruktora { strcpy(tytul, t_tytul); // przypisujemy konkretny tytuł wybrane_miejsce = 0; // dalsza część bez zmian int i = 0; for(i = i; i < ilosc_miejsc; i++) { wszystkie_miejsca[i] = Miejsce("","",i+1,false); } } void wybierz_miejsce() // bez zmian { cout << "Wybierz numer miejsca (lub 0 aby wyjsc):" << endl << endl; cin >> wybrane_miejsce; if(wybrane_miejsce < 0 || wybrane_miejsce > ilosc_miejsc) { if(wybrane_miejsce != 0) { wybrane_miejsce = 0; cout << "Nie ma takiego miejsca" << endl << endl; } } } void wyswietl_wszystkie_miejsca() // bez zmian { int i = 0; for(i = i; i < ilosc_miejsc; i++) { wszystkie_miejsca[i].wypisz(); } cout << endl << "Wszystkich miejsc: " << ilosc_miejsc << endl; } void wyswietl_wolne_miejsca() // bez zmian { int i = 0; int wolne = 0; for(i = i; i < ilosc_miejsc; i++) { if(!wszystkie_miejsca[i].jestZarezerwowane()) { wszystkie_miejsca[i].wypisz(); wolne++; } } cout << endl << "Wolnych miejsc: " << wolne << endl; } void wyswietl_zarezerwowane_miejsca() // bez zmian { int i = 0; int zarezerwowane = 0; for(i = i; i < ilosc_miejsc; i++) { if(wszystkie_miejsca[i].jestZarezerwowane()) { wszystkie_miejsca[i].wypisz(); zarezerwowane++; } } cout << endl << "Zarezerwowanych miejsc: " << zarezerwowane << endl; } void dodaj_rezerwacje() // bez zmian { cout << "Dodaj rezerwacje:" << endl << endl << endl; wyswietl_wolne_miejsca(); wybierz_miejsce(); if(wybrane_miejsce != 0) { wszystkie_miejsca[wybrane_miejsce-1].rezerwuj(); } czekaj_na_klawisz(); } void anuluj_rezerwacje() // bez zmian { cout << "Anuluj rezerwacje:" << endl << endl << endl; wyswietl_zarezerwowane_miejsca(); wybierz_miejsce(); if(wybrane_miejsce != 0) { wszystkie_miejsca[wybrane_miejsce-1].anuluj_rezerwacje(); } czekaj_na_klawisz(); } void sprawdz_miejsce() // bez zmian { cout << "Sprawdz rezerwacje:" << endl << endl << endl; wybierz_miejsce(); if(wybrane_miejsce != 0) { wszystkie_miejsca[wybrane_miejsce-1].wypisz(); wyczysc_miejsce(); } czekaj_na_klawisz(); } };
Klasę uzupełniliśmy jedynie o tytuł. Zmian jest niewiele, ale za to możliwości przybyło bardzo dużo. Wcześniejsza wersja programu zakładała, że dla jednej sali można zarezerwować miejsce tylko na jeden film. Nie jest to do końca prawda, ponieważ w jednej sali może odbyć się kilka seansów dzienne o wybranych godzinach. Aby nie komplikować kodu, poczyńmy takowe założenie również teraz. O nadaniu projektowi realizmu porozmawiamy później, obiecuję :-)
Aby menu naszego programu w dalszym ciągu działało, nie ominie nas napisanie nowej klasy Kino, będącej managerem wszystkich obiektów klasy Film.
class Kino { private: // klasa powinna zarządzać obiektami klasy Film public: Kino() { // konstruktor domyślny } void wyswietl_wszystkie_miejsca() { // wyświetl wszystkie miejsca ze wszystkich sal } void wyswietl_wolne_miejsca() { // wyświetl wolne miejsca ze wszystkich sal } void wyswietl_zarezerwowane_miejsca() { // wyświetl zarezerwowane miejsca ze wszystkich sal } void dodaj_rezerwacje() { // dodaj rezerwację na wybrany film i miejsce } void anuluj_rezerwacje() { // anuluj rezerwację na wybrany film i miejsce } void sprawdz_miejsce() { // sprawdz dostępność miejsca na wybrany film }; };
Dodatkowo bradzo pomocne będą następujące metody:
void dodaj_film(char t_tytul[]) { // utworzymy kolejny obiekt klasy Film i zainicjalizujemy tytuł } void wybierz_film() { // wybierzemy numer filmu } void wyswietl_wszystkie_filmy() { // wyświetliny numery i tytuły filmów w systemie }
Plan już jest. Teraz realizacja. Zacznijmy od podania składników prywatnych. Wiemy, że powinniśmy obsłużyć 5 sal kinowych, dlatego potrzebujemy 5 obiektów klasy Film. Dodatkowo, przyda się zmienna przechowująca numer wybranego filmu. Dodając kolejne filmy do systemu musimy wiedzieć czy nie przekroczyliśmy limitu pieciu sal, dlatego licznik filmów w systemie również zostanie użyty.
static const int ilosc_filmow = 5; // dopuszczalna ilość filmów w systemie int wybrany_film; // numer wybranego filmu Film wszystkie_filmy[ilosc_filmow]; // tablica obiektów klasy Film int ilosc_dodanych_filmow; // aktualna ilość dodanych filmów
W konstruktorze domyślnym przypiszemy wartości do wybrany_film
i ilosc_dodanych_filmow
:
Kino() { wybrany_film = 0; ilosc_dodanych_filmow = 0; }
Cóz nam z kina kiedy nie ma w nim filmów. Rozbudujmy metodę dodaj_film
:
void dodaj_film(char t_tytul[]) { if(ilosc_dodanych_filmow<ilosc_filmow) // sprawdźmy, czy mozemy dodać kolejny film { wszystkie_filmy[ilosc_dodanych_filmow] = Film(t_tytul); // dodajmy film o podanym tytule t_tytul ilosc_dodanych_filmow++; // zwiększmy licznik filmów o 1 cout << "Dodano film " << t_tytul << endl; } else { cout << "Maksymalna liczba filmow dodana" << endl; } }
Mając filmy w systemie, sprawdźmy stan miejsc poprzez uzupełnienie metod wyswietl_wszystkie_miejsca
, wyswietl_wolne_miejsca
i wyswietl_zarezerwowane_miejsca
.
Zanim to zrobimy, dodajmy do klasy Film
metodę wypisz
:
void wypisz() { cout << endl << "tytul: " << tytul << endl; }
Dzięki niej metoda wyswietl_wszystkie_miejsca
wygląda tak:
void wyswietl_wszystkie_miejsca() { int i = 0; for(i = i; i < ilosc_dodanych_filmow; i++) // dla wszystkich dodanych filmow { wszystkie_filmy[i].wypisz(); // wypisz tytuł filmu wszystkie_filmy[i].wyswietl_wszystkie_miejsca(); // wypisz wszystkie miejsca na sali } }
Filozofia żadna, ponieważ wykorzystujemy tutaj już wcześniej napisane funkcje. Idąc tym tropem, wyswietl_wolne_miejsca
:
void wyswietl_wolne_miejsca() { int i = 0; for(i = i; i < ilosc_filmow; i++) { wszystkie_filmy[i].wypisz(); wszystkie_filmy[i].wyswietl_wolne_miejsca(); } }
oraz funkcja wyswietl_zarezerwowane_miejsca
:
void wyswietl_zarezerwowane_miejsca() { int i = 0; for(i = i; i < ilosc_filmow; i++) { wszystkie_filmy[i].wypisz(); wszystkie_filmy[i].wyswietl_zarezerwowane_miejsca(); } }
Zanim dodamy pierwszą rezerwację, przygotujmy sobie metodę wybierającą film. Wyświetlenie ich listy okaże się badzo pomoce.
void wyswietl_wszystkie_filmy() { int i = 0; for(i = i; i < ilosc_filmow; i++) { cout << "Film nr. " << i+1 << ": "; wszystkie_filmy[i].wypisz(); cout << endl; } cout << endl << "Wszystkich filmow: " << ilosc_filmow << endl; } void wybierz_film() { wyswietl_wszystkie_filmy(); cout << "Wybierz numer filmu (lub 0 aby wyjsc):" << endl << endl; cin >> wybrany_film;// pobierz numer filmu if(wybrany_film < 0 || wybrany_film > ilosc_dodanych_filmow) // sprawdź czy jest poprawny { if(wybrany_film != 0) { wybrany_film = 0; cout << "Nie ma takiego filmu" << endl << endl; } } }
Dzięki tym funkcjom dodamy rezerwację :-)
void dodaj_rezerwacje() { cout << "Dodaj rezerwacje:" << endl << endl << endl; wyswietl_wszystkie_filmy(); wybierz_film(); if(wybrany_film != 0) { wszystkie_filmy[wybrany_film-1].dodaj_rezerwacje(); } }
Tutaj rownież używamy istniejacej metody. Bez najmniejszego problemu zaimplementujemy anuluj_rezerwacje
oraz sprawdz_miejsce
:
void anuluj_rezerwacje() { cout << "Anuluj rezerwacje:" << endl << endl << endl; wyswietl_wszystkie_filmy(); wybierz_film(); if(wybrany_film != 0) { wszystkie_filmy[wybrany_film-1].anuluj_rezerwacje(); } } void sprawdz_miejsce() { cout << "Sprawdz rezerwacje:" << endl << endl << endl; wyswietl_wszystkie_filmy(); wybierz_film(); if(wybrany_film != 0) { wszystkie_filmy[wybrany_film-1].sprawdz_miejsce(); } }
Doając kilka filmów do sytemu
kino.dodaj_film("film1"); kino.dodaj_film("film2"); kino.dodaj_film("film3"); kino.dodaj_film("film4"); kino.dodaj_film("film5");
czynimy z niego potężne narzędzie w rękach managera kina :-D
Strony: 1 2
Ciekawe, które kino chciałoby tego użyć…
W obecnej formie, żadne. To nie jest system produkcyjny dla klienta, tylko po to, żeby zrozumieć na czym polega programowanie zorientowane obiektowo. Dalej można ten program rozwijać, a to jest dobry początek ;)
Ciekawe, czy ktoś zrozumie na czym polega programowanie zorientowane obiektowo czytając Twojego bloga… ;)
Z takim nastawieniem jak twoje, na pewno nie ;)
Gdybym na prawdę potrzebował bardzo prosty program do sprzedaży miejsc numerowanych to dało by się ten adoptować ??
Adoptować w jakim sensie?
Dostosować do rzeczywistego wyglądu sali i drukować bilety zgodne z układem siedzeń.
Jeżeli funkcjonalności tego programu Panu odpowiadają to jak najbardziej tak. Moim zdaniem aby to użyć komercyjnie trzeba by dorobić jeszcze kilka rzeczy jak na przykład interfejs i zapis danych.