/** @mainpage Dekoratorius
*
* Pirmoji u�duotis objektini� technologij� kursui.
*
* Autorius: Marius Gedminas (mgedmin@@gedmin.as)
*
* VU MIF, informatika, 1M kursas, 1 grup�.
*
* 2002 m. ruduo.
*
* @section problem Problema
*
* Projektuokime dokument� tvarkymo sistem�. Dokumentai gali b�ti �vairi�
* r��i� (tekstas, paveiksliukai ir t.t.). Dokumentus galime per�i�rin�ti,
* spausdinti, redaguoti.
*
* Taip pat norime keisti ar papildyti kai kuri� konkre�i� dokument� elges�.
* Pavyzd�iui, u�drausti kai kuri� dokument� redagavim�, ar prikabinti prie
* dokument� anotacijas.
*
* Jei kiekvienam variantui kursime po atskir� klas�, gausime kombinatorin�
* sprogim� -- %TextDocument, ReadOnlyTextDocument, AnnotatedTextDocument,
* AnnotatedReadOnlyTextDocument ir t.t.
*
* @section solution Sprendimas
*
* Pritaikysime Dekoratoriaus �ablon�. Kiekvien� dokumento tip� atitinka
* atskira klas�. Visi dokumentai paveldi i� bendros astrak�ios bazin�s klas�s
* ir realizuoja t� pat� interfeis�, nusakant� bazin� dokument� funkcionalum�.
*
* Papildomas savybes suteiks dekoratoriai. Abstrakti dekoratoriaus klas�
* paveldi i� bazin�s dokument� klas�s ir realizuoja bendr� visiems
* dekoratoriams funkcionalum� -- metod� delegavim�.
*
* Tradiciniame Dekoratoriaus �ablono variante dokumentai nieko ne�ino apie
* dekoratorius, ne�ino net apie j� egzistavim�. Ta�iau tokiu atveju galime
* lengvai nuimti tik i�orin� dekoratori�, jei �inome jo tip�. Taip pat galime
* lengvai pasinaudoti tik i�orinio dekoratoriaus (jei �inome jo tip�)
* pateikiamomis papildomomis funkcijomis, nes dekoratoriai deleguoja tik
* dokument� interfeiso funkcijas. Nor�t�si ko nors lankstesnio.
*
* Tur�dami kok� nors objekt� (ne�inodami, ar jis dekoruotas, ar ne), mes
* nor�tum�me su�inoti (gauti nuorod�) � tam tikros konkre�ios klas�s
* dekoratori� (kad gal�tum�me pasinaudoti jo teikiamomis papildomomis
* funkcijomis). Taip pat nor�tum�me i�mesti i� dekoratori� grandin�s vien�
* ar visus nurodyto tipo dekoratorius.
*
* Kad pasiektum�me papildomai i�keltus tikslus turime kiek pakeisti tradicin�
* Dekoratoriaus �ablon� ir prid�ti kelias funkcijas � dokument� bazin� klas�
* (negalime j� prid�ti � dekoratori� bazin� klas�, nes norime ir nedekoruotus
* objektus traktuoti vienodai).
*
* @section implementation Realizacija
*
* @image html classdiagram.png "Klasi� diagrama"
* @image latex classdiagram.eps "Klasi� diagrama" width=12cm
*
* Klases galima sugrupuoti � tokias kategorijas:
* - @ref interfaces "Interfeisai" (@ref Document, @ref Decorator)
* - @ref documents "Konkret�s dokumentai" (@ref TextDocument, @ref Image)
* - @ref decorators "Konkret�s dekoratoriai" (@ref ReadOnly, @ref Annotation)
*
* Pagrindin�je programoje pateiktas @ref example "naudojimo pavyzdys".
*/
#include "decorator.h"
#include <iostream>
// Document
Document::~Document()
{}
// Decorator
Decorator::~Decorator()
{
delete next_;
}
// TextDocument
void TextDocument::view()
{
std::cout << "tekstinio dokumento per�i�ra\n";
}
void TextDocument::print()
{
std::cout << "tekstinio dokumento spausdinimas\n";
}
void TextDocument::edit()
{
std::cout << "tekstinio dokumento redagavimas\n";
}
// Image
void Image::view()
{
std::cout << "paveiksliuko per�i�ra\n";
}
void Image::print()
{
std::cout << "paveiksliuko spausdinimas\n";
}
void Image::edit()
{
std::cout << "paveiksliuko redagavimas\n";
}
// ReadOnly
void ReadOnly::edit()
{
std::cout << "negalima redaguoti �io dokumento!\n";
}
// Annotation
void Annotation::view()
{
Decorator::view();
std::cout << " anotacija: " << annotation() << '\n';
}
void Annotation::print()
{
Decorator::print();
std::cout << " anotacija: " << annotation() << '\n';
}
/**
* @addtogroup example Pavyzdys
* @{
*/
/**
* Pagrindin� programa, iliustruojanti dekoratori� panaudojim�. J� �vykd�ius
* tur�t� pasirodyti �itoks tekstas:
@verbatim
* Bazinis funkcionalumas
tekstinio dokumento per�i�ra
tekstinio dokumento spausdinimas
tekstinio dokumento redagavimas
paveiksliuko per�i�ra
paveiksliuko spausdinimas
paveiksliuko redagavimas
* Bazinis funkcionalumas su dekoratoriais
tekstinio dokumento per�i�ra
anotacija: �domus dokumentas
tekstinio dokumento spausdinimas
anotacija: �domus dokumentas
negalima redaguoti �io dokumento!
paveiksliuko per�i�ra
anotacija: gra�us paveiksliukas
anotacija: o man nepatiko
paveiksliuko spausdinimas
anotacija: gra�us paveiksliukas
anotacija: o man nepatiko
paveiksliuko redagavimas
* Papildomas funkcionalumas: pakeiskime anotacij�
tekstinio dokumento per�i�ra
anotacija: o gal ir nelabai �domus
* Pereikime per visus vieno tipo dekoratorius
radau anotacij�: o man nepatiko
radau anotacij�: gra�us paveiksliukas
* Nuimkime ReadOnly dekoratori�
tekstinio dokumento redagavimas
@endverbatim
*/
int main()
{
// Sukuriame plikus objektus
Document* txt = new TextDocument();
Document* img = new Image();
// Bazinis funkcionalumas
cout << "* Bazinis funkcionalumas\n";
txt->view();
txt->print();
txt->edit();
img->view();
img->print();
img->edit();
cout << '\n';
// Prikabiname dekoratorius
txt = new Annotation(txt, "�domus dokumentas");
txt = new ReadOnly(txt);
img = new Annotation(img, "gra�us paveiksliukas");
img = new Annotation(img, "o man nepatiko");
// Bazinis funkcionalumas su dekoratoriais
cout << "* Bazinis funkcionalumas su dekoratoriais\n";
txt->view();
txt->print();
txt->edit();
img->view();
img->print();
img->edit();
cout << '\n';
// Papildomas funkcionalumas
cout << "* Papildomas funkcionalumas: pakeiskime anotacij�\n";
if (Annotation* a = txt->decorator<Annotation>()) {
a->changeAnnotation("o gal ir nelabai �domus");
txt->view();
};
cout << '\n';
// Parodykime visas anotacijas
cout << "* Pereikime per visus vieno tipo dekoratorius\n";
for (Document* tmp = img;
Annotation* d = tmp->decorator<Annotation>();
tmp = d->next())
{
std::cout << "radau anotacij�: " << d->annotation() << '\n';
}
cout << '\n';
// Nuimkime dekoratori�
cout << "* Nuimkime ReadOnly dekoratori�\n";
txt = txt->unwrap<ReadOnly>(true);
txt->edit();
cout << '\n';
// Panaikinkime objektus ir visus dekoratorius
delete txt;
delete img;
}
/// @}
syntax highlighted by Code2HTML, v. 0.9.1