2. Objektový model
(Poslední úprava: 5.3.1997, 9.4.1998, 5.3.2000,12.3.2000)

Obsah kapitoly:
2. Objektový model
2.1. Vývoj objektového modelu
2.1.1. Trendy softwarového inženýrství
2.1.1.1. Topologie jazyků 1. generace a začátků 2. gen. 2.1.1.2. Topologie pozdní druhé a počátku třetí generace 2.1.1.3. Topologie pozdní třetí generace
2.1.1.4. Topologie jazyků založených na objektech a OO orientovaných jazyků
2.1.2. Základy objektového modelu
2.1.3 OOP, OOD, OOA
2.1.3.1. Objektově orientované programování - OOP 
2.1.3.2.Objektově orientovaný návrh - OOD (OO Design) 
2.1.3.3. Objektově Orientovaná Analýza - OOA
2.2. Prvky objektového modelu
2.2.1. Druhy programovacích paradigmat (paradigma= vzorové řešení)
2.2.2. Abstrakce 
2.2.3. Zapouzdření 
2.2.4.Modularita 
2.2.5. Hierarchie 
2.2.6. Kontrola typu (Typing) 
2.2.6.1. Příklady silné a slabé typové kontroly
2.2.6.2. Příklady typové kontroly: Statická a dynamická vazba.
2.2.7 Paralelnost 2.2.8 Perzistence (persistence)
2.3. Použití objektového modelu
2.3.1. Výhody objektového modelu.
2.4. Souhrn kapitoly

2. Objektový model

 (Poslední úprava: 5.3.2000)

Co je to objektově orientovaný návrh a co není; čím se liší od ostatních návrhových metod.
2.1. Vývoj objektového modelu
2.1.1. Trendy softwarového inženýrství

Generace programovacích jazyků

•	První generace (1954-58) (matematické formule)
 Fortran I, Algol 58, Flowmatic, IPL V (Obr.2.1.)
•	Druhá generace (1959-61) ( algoritmické abstrakce, datové a řídicí  struktury)
 Fortran II, Algol 60, Cobol,Lisp (Obr.2.2)
•	Třetí generace (1962-70)
 PL/1, Algol 68, Pascal, Simula (Obr.2.3.)
•	Generační mezera (1970-80) (Obr.2.4.)
 Mnoho jazyků vytvořeno, málo přežilo.

(Obrázky 2.1.,2.2.,2.3. a 2.4. str 28)

2.1.1.1. Topologie jazyků 1. generace a začátků 2. gen.
 vyplývá, že jednotlivé programy mohou spolupracovat jen prostřednictvím společné datové oblasti (common). Chyba jednoho programu má devastující účinek na celek. (viz.obr.2.1.) 

2.1.1.2. Topologie pozdní druhé a počátku třetí generace 
vyplývá důraz na abstrakci. Procedury, vytvořené již dříve se začínají používat jako abstrakce spíše než práci šetřící nástroj pro opakované použití. Využívá se různých metod předávání parametrů a zanořování podprogramů.(viz.obr.2.2) 

2.1.1.3. Topologie pozdní třetí generace

 se zaměřuje na programování ve velkém. Objevují se programové moduly a samostatný překlad modulu. Objevuje se požadavek sémantické kontroly rozhraní mezi moduly.(viz obr.2.3.) 

2.1.1.4. Topologie jazyků založených na objektech a OO orientovaných jazyků

Pro topologii objektově založených a objektově orientovaných programovacích jazyků je charakteristické vytváření modulů, které zahrnují jak operace, tak data, nad kterými jsou operace definovány. Zatímco algoritmicky orientované jazyky vytvářejí program, který má tvar stromové struktury, objektově orientované jazyky vytvářejí program, který se spíše podobá grafu a ne stromové struktuře! Zatím co algoritmické jazyky se vyznačují procedurami a funkcemi, které vyjadřují slovesa činností a data vyjadřovaná podstatnými jmény, OOP je opřen především o podstatná jména objektů. V OOP se setkáváme s žádnými nebo s malým množstvím globálních dat! Technologie programování využívá prostředků pro "programování ve velkém" a začíná rozvíjet prostředky "pro programování v super-velkém". Pro velmi rozsáhlé programy přestávají být třídy a objekty dostatečnými prostředky pro zvládnutí složitosti a začínají se používat programové shluky (clusters) abstrakcí, vytvářející "vrstvy" (layers), které se na sebe skládají vertikálně. Uvnitř implementace každého shluku objevíme opět další skupinu kooperujících abstrakcí (viz.obr. 2.4 a 2.5). 

2.1.2. Základy objektového modelu

Objektový model byl ovlivněn řadou faktorů, ne pouze OO programováním. Je to sjednocující princip v počítačové problematice aplikovatelný nejen na programovací jazyky, ale také na uživatelská rozhraní, databázové systémy a počítačové architektury. Příčinou je vrozená složitost řady různých systémů, řešených počítačovými nástroji. OO návrh nepředstavuje revoluční vývoj a nezavrhuje výhody předcházející technologie. Je skutečností, že většina programátorů má zkušenosti z tvorby složitějších systémů s využitím především algoritmické dekompozice. Použití jazyků jako C++ nebo ADA bez znalosti OO přístupu může vést k výsledkům horším, než kdyby byly použity jazyky jako C nebo Pascal. Je to jako když dáte stolaři, který neví nic o elektřině elektrickou vrtačku. S největší pravděpodobností jí bude používat jako kladiva...

2.1.3 OOP, OOD, OOA

2.1.3.1. Objektově orientované programování - OOP 
je metoda implementace, v níž jsou programy organizovány jako spolupracující skupiny objektů, z nichž každý objekt představuje jistou instanci určité třídy a kde všechny třídy jsou členy hierarchie tříd spojené prostřednictvím vztahu dědičnosti. 
Zde je nutno zdůraznit tři aspekty:
•	základním stavebním kamenem je objekt a nikoli algoritmus
•	každý objekt je členem jisté třídy
•	mezi třídami může být vztah dědičnosti
Programování bez dědičnosti není OOP, ale programování s abstraktními typy dat! Tím se liší podle některých autorů objektově orientované jazyky od objektově založených jazyků (object-based languages).
Objektově orientované jazyky musí mít tři vlastnosti:
•	Podporují objekty, což jsou datové abstrakce s rozhraním s pojmenovanými operacemi a se skrytým lokálním stavem
•	Objekty patří určitému typu (třídě)
•	Typy (třídy) mohou dědit vlastnosti z nadřazených typů - nadtypů (tříd - nadtříd). Jazyk podporující dědičnost umožňuje operaci mezi typy jako: "patří do třídy" nebo "je typu" podobně jako "růže je květina" a "květina je rostlina". Jazyky, které neumožňují práci s dědičností budeme nazývat raději "objektově založené jazyky" než "objektově orientované".

2.1.3.2.Objektově orientovaný návrh - OOD (OO Design) 
je metoda návrhu, která zahrnuje objektově orientovanou dekompozici a notaci umožňující vyjádřit logický a fyzický a také statický a dynamický model navrhovaného systému. 
Definice zdůrazňuje:
•	OOD vede k OO dekompozici
•	OOD používá různé notace pro logický (struktura třídy a objektu) a fyzický (architektura modulu a procesu) návrh systému.

2.1.3.3. Objektově Orientovaná Analýza - OOA

 je metoda analýzy, která zkoumá požadavky zadání z perspektivy tříd a objektů ze slovníku problémové domény. 
Výsledky OOA slouží jako modely na nichž může stavět OOD. Výsledky OOD slouží jako schema či plán pro plnou implementaci systému s použitím metod OOP.

2.2. Prvky objektového modelu

2.2.1. Druhy programovacích paradigmat (paradigma= vzorové řešení)
Programovací styl je definován jako způsob organizace programu na základě určitého principiálního modelu programování s použitím jazyka, který umožňuje jasný zápis tohoto stylu. Hovoří se o pěti hlavních stylech programování spolu s druhy abstrakcí, které se v nich využívají:
•	procedurově orientovené programování .... algoritmy
•	objektově orientované .... třídy a objekty
•	logicky orientované .... cíle, vyjádřené často  formou predikátového počtu
•	orientované na pravidla .... formule if-then
•	orientovaná na omezení .... invariantní vztahy
Neexistuje jeden styl, vhodný pro všechny aplikace. Každý styl je založen na vlastním principiálním rámci. Každý má svůj přístup k problému. Pro vše co označujeme objektově orientované je principiálním rámcem objektový model. Tento model má čtyři základní prvky:
•	abstrakce
•	zapouzdření - obalení (encapsulation)
•	modularita
•	hierarchie
Bez žádného z těchto prvků není model objektově orientovaný.
Existují další prvky, které jsou podpůrné, ale nikoli základní pro objektovou orientaci:
•	kontrola typů
•	paralelnost
•	persistence

2.2.2. Abstrakce (obr.2.6.)

Abstrakce je jedním ze základních nástrojů jak zvládat složitost. Hoare
říká, že: "abstrakce vychází s rozpoznání podobností mezi určitými objekty, situacemi a procesy reálného světa, zaměřuje se na tyto podobnosti a zanedbává, po jistý čas, vzájemné rozdíly". Definici abstrakce lze vyjádřit takto:
Abstrakce označuje základní charakteristiky objektu, které jej odlišují od ostatních objektů a které jsou relativní vzhledem k pohledu řešitele.
Existuje celé spektrum druhů abstrakcí, od nejdůležitějších až po málo významné:
•	abstrakce entit ... objekt representuje užitečný model entity  problémové domény
•	abstrakce akcí ... objekt poskytuje generalizovaný soubor operací,  z nichž každá provádí stejný druh funkce
•	abstrakce virtuálního stroje ... objekt, který sdružuje operace  použité na určité vyšší úrovni řízení  nebo operace, které všechny  používají určitý soubor nižších operací
•	koincidenční abstrakce ... objekt, který sdružuje do jednoho balíku  operace, které nemají žádný vzájemný vztah
Názvy některých objektů se odvozují přímo z problémové domény. Např. klient je libovolný objekt, který používá zdroje jiných objektů. Chování objektu posuzujeme podle operací, které může klient provádět nad objektem a podle operací, které mohou provádět nad jinými objekty. Množině operací, které může klient provádět nad objektem, se říká "protokol klienta". 
Všechny abstrakce mají statické a dynamické vlastnosti.

Příklad abstrakcí

Některé uvedené principy a pojmy demonstrujme na příkladu hydroponické skleníkové farmy. Automatické řízení jejího prostředí zahrnuje řízení teploty, vlhkosti, světla, pH roztoku a jeho nutriční složení a koncentrace.
Jednou ze základních abstrakcí je čidlo - senzor. Senzor je objekt, který má změřit veličinu, ke které je určeno. Daná veličina je hodnota - zřejmě s rozsahem daným konkrétní aplikací. Umístěním čidla se rozumí jisté místo, na němž je veličina (např. teplota) měří. Jde o identifikaci jistého čidla, která umožní jeho odlišení od jiných čidel téhož typu.
Nyní lze rozhodnout, jaké operace nad např. teplotním čidlem jsou možné. Uživatel je může kalibrovat a dále získávat teplotu. Pro zápis bude použito prostředků jazyka C++.  Abstrakce senzoru bude mít tvar bude mít tvar:

//Temperature in degrees Fahrenheit

typedef float Temperature;

// Number uniquely denoting the location of a sensor
typedef unsigned int Location;

class TemperatureSensor {
public:

  TemperatureSensor(Location);
  ~TemperatureSensor();

void calibrate(Temperature actualTemperature);

Temperature currentTemperature() const;

private:
…
};
Tento modul vyváží tři typy: teplotu, umístění a čidlo teploty vzduchu. Implementace typu TemperatureSensor je ukryta v těle třídy. Protože typ representuje třídu a ne jednotlivé objekty, musí se napřed vytvořit instance dané třídy:
Temperature temperature;

TemperatureSensor greenhouse1Sensor(1);
TemperatureSensor greenhouse2Sensor(2);

temperature=greenhouse1Sensor.currentTempeature();

...
end;

Takto definovaná abstrakce je pasivní. Jiný objekt s ní musí pracovat tak, aby určil teplotu čidla. Lze to ale definovat také tak, že učiníme senzor aktivním. Pak čidlo nebude pasivně ovládáno něčím jiným, ale naopak bude ovládat jiné objekty, kdykoliv se teplota změní. Zápis modulu bude podobný, ale rozhraní se musí obrátit zvnitřku ven:
class ActiveTemperatureSensor{
public
	ActiveTemperatureSensor(Location,
			void(*)(Location,Temperature)) ;
	~ActiveTemperatureSensor();
	
	void calibrate(Temperature actualTemperature);
	void establishSetpoint(Temperature setpoint,
						Temperature, delta);
	Temperature currentTemperature() const;

private:
 …
};

nad takto definovanými čidly provádíme pouze inicializaci a kalibraci. Inicializace nastavuje hodnotu delta,  při jejímž překročení od hodnoty setpoint se aktivuje procedura ActiveTemperatureSensor, která vrací hodnotu teploty a číslo umístění čidla  a klient tak dostává dostatek informací k tomu, aby na situaci reagoval.

 Ukažme další příklad s použitím C++. Pro každou sklizeň musí být pěstitelský plán, který popisuje teplotu, osvětlení, přísady vody jiní faktory, které se v průběhu růstu mění. Pěstitelský plán je sám o sobě abstrakcí, protože je částí slovníku problémové domény. Každá sklizeň má svůj plán, ale jednotlivé plány mají shodnou formu. Obecně, plán je tabulka akcí v čase. Např. podle plánu se může 15 den teplota vzduchu udržovat na 68 F po 16 hodin, z nichž 14 dní mají být zapnuta světla a po zbývající čas teplota klesne na 65 F. Z toho pohledu musíme umět plán detailně sestavit modifikovat a provádět. Může existovat objekt, který provádí kontakt "člověk/stroj", který zavádí pokyny uživatele do plánu. Existuje objekt, který "provádí" plán a čte jednotlivé detaily plánu v určených časech. Z toho je vidět, že objekty "nestojí samy o sobě" ale vzájemně spolupracují za účelem dosažení určitého chování. S použitím C++ pak můžeme napsat:
//Hodnoty označující pořadové číslo dne a hodinu
typedef int day;
typedef int hour;
// Hodnota teploty
typedef float temperature;
// Kyselost živné tekutiny v rozsahu od 1..14
typedef float ph;
// Koncentrace od 1..100
typedef float concentration;
// Stav osvětlení
enum Lights {OFF, ON};

// Stavový záznam podmínek
struct Condition {
	Temperature temperature;
	Ligts lighting;
	ph acidity;
	Concentration concentration;
};

class GrowingPlan 
public:

 GrowingPlan (char* name);
 virtual ~GrowingPlan ();
 void clear ();
 virtual void establish (Day, Hour, const         Condition&);

 const *char name() const;
 const Condition& desiredConditions(Day, Hour) const;

protected:
…
};

Všimněme si zavedení nové vlastnosti abstrakce:  pěstitelský plán má jméno, které mu klient ustaví a může ho zpětně zjistit. Operace establish je virtuální, protože přepokládáme, že její implicitní činnost implicitně stanovena třídou GrowingPlan  bude přepsána možnými dědickými podtřídami.

2.2.3. Zapouzdření (Obr.2.7.)

Abstrakce objektu předchází jeho implementaci. Jakmile je implementace určena, měla by být skryta většině klientů. Souvisí to s výrokem, "že žádná část složitého systému nesmí záviset na vnitřních detailech jiné části". Zatímco abstrakce pomáhá uvažovat "co objektu dělají", zapouzdření umožňuje, aby změny v programu byly spolehlivé a vyžadovaly co nejmenší úsilí.
Abstrakce a zapouzdření se vzájemně doplňují. Abstrakce se zaměřuje na vnější chování, zatím co zapouzdření - nazývané také "ukrývání informace" - zabraňuje klientům, aby viděli, jak je chování objektu implementováno. Zapouzdření je explicitní hranicí mezi abstrakcemi. Z toho pohledu musí mít každý objekt dvě části: rozhraní a implementaci. Zatím co rozhraní popisuje vnější chování abstrakce, implementace popisuje způsob, kterým je toto chování realizováno. Definujme zapouzdření jako "způsob ukrytí všech detailů objektu, které nejsou součástí jeho vnější charakteristiky". 
V ideálním případě by snaha o přístup klienta k vnitřní části objektu měl být detekován v okamžiku kompilace klientova programu. K tomuto problému se různé programovací jazyky a také různé skupiny objektově orientovaných programátorů staví různě. Smalltalk zcela zabraňuje přístupu k vnitřním proměnným instance jiné třídy a v případě pokusu o takový přístup hlásí chybu. Objekt Pascal naopak neposkytuje žádné zapouzdření a podobnému přístupu nelze zabránit. CLOS poskytuje kompromisní řešení. Tvůrce může klientovi poskytnout jeden ze tří druhů přístupu: čtení, zápis, čtení/zápis. Není-li udělen žádný z těchto přístupů, je objekt zcela nepřístupný. C++ poskytuje ještě pružnější prostředek viditelnosti vnitřní struktury objektu. Prvky implementace mohou být deklarovány ve veřejné (public) sekci; pak jsou dostupné všem klientům. Jsou -li deklarovány v soukromé sekci (private), jsou zcela ukryty. Jsou-li deklarovány v chráněné sekci (protected), pak jsou viditelné jen z vlastní třídy a ze všech podtříd.
Ukrývání je relativní pojem. Co je pro jednu abstraktní vrstvu ukryto, může pro jinou vrstvu představovat vnější úroveň abstrakce. Ukrývání je záležitostí tvůrce a uživatele. Zapouzdření je nutno chápat především jako prevence proti náhodné chybě a ne jako zabezpečení proti přístupu ke chráněné informaci.
Příklady zapouzdření

Pro příklad zapouzdření se vraťme k hydroponickému pěstovatelskému systému. Další klíčovou abstrakcí je ohřívač.  Je to jednoduchá abstrakce, nad níž potřebujeme tři operace. Zapnout, vypnout a zjistit stav. Ohřívač nezodpovídá za teplotu. To sleduje jiná abstrakce. Toto chování má "vyšší úroveň", protože je postaveno na primitivní sémantice čidla a ohřivače a přináší novou sémantiku – hysterezi, která brání, aby byl ohřívač vypnut či zapnut příliš rychle, když se blíží hraniční hodnotě. Rozhodnutím o oddělení zodpovědnosti vytváříme jednotlivé abstrakce více soudržné (kohesivní). 
Začneme s dalším typem:
// Typ Boolean
enum Boolean {FALSE,TRUE};

Pro ohřívač musíme vedle základních operací poskytnout metaoperace  - kontruktor a destruktor, protože ohřívačů bude více.
class Heater {
public
 Heater(Location);
 ~Heater();
 void turnOn();
 void turnOff();

 Boolean isOn() const;

private:
 …
};
Rozhraní poskytuje veškerou informaci, kterou uživatel potřebuje.

Podívejme se dovnitř implementace třídy. Předpokládejme, že systémový inženýr rozhodl umístit počítač, který ovládá každý skleník vně budovy a propojil počítač se senzory a  ovladači sériovou linkou. Vhodným řešením pro ohřívač je elektromechanické relé ovládající silové napájení ohřívače spolu s relé, ovládaném zprávou vyslanou po sériové lince. Na příklad pro zapnutí ohřívače se vyšle speciální řetězec, následovaný číslem ohřívače následovaný kódem znamenajícím zapnutí. Předpokládejme  třídu, která vyjadřuje abstrakci pro sériový port:

class SerialPort {
public:
  SerialPort();
 ~SerialPort();

 void write(char*);
 void write(int);

 static SerialPort ports[10];

private:
 …
};

Tím máme k dispozici třídu, jejíž instance označují seriové porty, kterými můžeme zasílat znaky a čísla. Nyní můžeme dokončit třídu ohřívač přidáním dalších tří atributů:

class Heater {
public:
…
protected:
 const Location repLocation;
 Boolean repIsOn;
 SerialPort* repPort;
};
Tyto tři atributy představují zapouzdření této třídy. C++ způsobí sémantickou chybu, když se klientův kód snaží dosáhnout na tyto atributy.

Dokončeme implementaci dalších operací:
Heater::Heater(Location 1)
 : repLocation(1),
   repIsOn(FALSE),
   repPort(&SerialPort::ports[1]) {}

Heater:: ~Heater() {}

void Heater::turnOn()
{
  if (!repIsOn) {
    repPort ->write("*");
    repPort ->write("repLocation");
    repPort ->write(1);
    repIsOn=TRUE;
   }
}

void Heater::turnoff()
{
  if (repIsOn) {
     repPort ->write("*");
     repPort ->write(repLocation);
     repPort ->write(0);
     repIsOn=FALSE;
   }
}
Boolean Heater::isOn() const
{
   return repIsOn
}
Tato implementace je typická pro dobře strukturovaný objektově orientovaný systém. Implementace jednotlivých tříd jsou relativně malé, protože systém je stavěn ze tříd na nízké úrovni.
Kdyby se ale návrhář rozhodl použít paměťově mapovaný V/V systém místo sériové komunikační linky, nic by se ba rozhraní abstrakcí nezměnilo. Změnila by se jen jejich implementace.
Zamysleme se ještě nad pěstitelským plánem. Je to v podstatě proces s časovým mapováním plánu. Zdá se, že nejjednodušší representace této abstrakce by byl kalendář ve formě seznamu dvojic čas/akce, s použitím otevřené tabulky s rozptýlenými položkami. Nemusíme ukládat akci pro každou hodinu, protože proces růstu není tak rychlý. Můžeme akce uchovávat pouze pro případ změny a nechat implementaci extrapolovat mezi časy. Tímto způsobem implementace ukrývá dvě tajemství: použití otevřené hashovací tabulky (což je problémem implementační a nikoliv problémové domény) a použití extrapolace, která ušetří mnoho paměti pro dvojice čas/akce, které by se musely uchovávat pro celou dobu pěstění. 
Inteligentní návrh zapouzdřuje a ukrývá detaily, jejichž změna neovlivní vnější chování abstrakce. 
V ideálním případě by se snaha o přístup k zapouzdřeným detailům měla detekovat již v době kompilace.  Způsob zapouzdření i způsob překonání této obrany je věčným námětem na diskuse mezi programátory a jednotlivé jazyky se s tímto fenoménem vypořádávají různým způsobem. Smalltalk takovému přístupu brání důsledně a rozezná ho již v době kompilace. Na druhé straně Object Pascal to nedělá a nedovede důsledně zabránit, aby klient nepřistupoval k vnitřním složkám objektů. CLOS zaujíma pozici někde mezi těmito přístupy. Každá "zásuvka" (slot) má jednu ze tří možností: reader-writer-accessor pro čtení, zápis nebo obojí. C++ nabízí flexibilnější ovládání viditelnosti prostřednictvím části třídy vyhrazených jako "public", "private" nebo "protected". Části "public" jsou dostupné (viditelné) pro všechny klienty. Část označená jako "private" je plně chráněna a nedostupná. Část označená jako "protected" je viditelná pouze ze třídy samé a z jejich podtříd. C++ podporuje také princip "friends" – přátel, kterým dovoluje přístup do své části "private".

Ukrývání je relativní pojem. To co se jeví jako ukryté na jisté úrovni abstrakce, může pro jinou úroveň představovat vnější pohled. Snad nejdůležitější je tvrzení Stroustrupa, že ukrývaní je obrana před nehodou a ne před zlodějem.
2.2.4.Modularita (obr.2.7.)

Rozdělení velkého programu na menší části může do jisté míry snížit celkovou složitost. Důležitým aspektem modularity je skutečnost, že se vytvoří řada dobře definovaných a dokumentovaných hranic mezi částmi programu. Podle Liskova je modul část programu, kterou lze kompilovat odděleně, ale má při tom vazby na ostatní části programu.
V té souvislosti se hovoří o "samostatné" (nezávislé) kompilaci a o "oddělené" kompilaci. Zatím co samostatná kompilace nekontroluje žádné vazby kompilovaného úseku k ostatním úsekům téhož programu, "oddělená" kompilace zjišťuje, zda všechny vzájemné vazby mezi kompilovaným úsekem a ostatními úseky programu jsou pokryty s ohledem na "nabídku/poptávku" a eventuálně provádí silnou/volnou kontrolu jejich typu. 
Většina programovacích jazyků podporuje modulární výstavbu prostřednictvím konstrukce rozhraní a implementace. Modularita a zapouzdření je opět ve velmi úzkém vztahu. Různé jazyky jazyky podporují modulární výstavbu různými způsoby. Ve světě C/C++ se rozhraní modulů označují jako soubory s příponu ".h" (header) a implementace modulů v souborech s příponou ".c". Vzájemná závislost se naplní prostřednictvím makroinstrukce #include. V tomto případě nejde o více než samostatnou kompilaci! Tento přístup je pouhou konvencí a syntax a sémantika jazyka samotného ji nevyžaduje. Object Pascal je v tomto ohledu formálnější. Pro modul zavádí syntaktický pojem "unit", který obsahuje část pro rozhraní a pro implementaci. Ada jde ještě dále. Rozhraní a implementace modulu (package) jsou samostatné a jejich vzájemné vazby modulu lze ustavit oddělenou specifikací v rozhraní a v těle modulu. Tak lze dosáhnout situace; že tělo modulu závisí na modulu, který pro rozhraní modulu není viditelný.
Moduly slouží jako fyzické kontejnery pro třídy a objekty logického návrhu programového systému. V malých problémech se často deklaruje každá třída ve svém modulu. Ve větších, netriviálních projektech se do jednoho modulu sestavují objekty a třídy, které mají nějakou vzájemnou souvislost a na venek dát k dispozici jen to co je nezbytně nutné. Tento způsob modularizace lze pochopit na extrému. Představme si aplikaci, která pracuje na distribuované soustavě procesorů a pro koordinaci aktivit různých programů používá mechanismus předávání zpráv. Ve velkém systému není neobvyklá existence mnoha stovek až několika tisíc různých zpráv. Naivní strategie vede k samostatnému modulu pro každou zprávu. Podobné rozhodnutí je zásadně chybné. Způsobí zmatek v dokumentaci, protože bude obtížné v dlouhém seznamu najít potřebnou třídu. Při změně některého rozhodnutí bude nutno překompilovat stovky modulů. Z toho vyplývá, že ukrývání informace má také zpětný dopad. Náhodná modularizace je někdy horší než žádná modularizace. 
V tradičním strukturovaném návrhu se pozornost soustředí primárně na smysluplné seskupení podprogramů do jednoho celku, při čemž se sleduje především jejich soudržnost a zpřaženost. V objektově orientovaném návrhu je přístup značně odlišný. Úkolem je rozhodnout, kde fyzicky umístit a obalit třídy a objekty podle logické struktury návrhu; to se výrazně liší od přístupu z pohledu podprogramů. Podle Britona a Parnase je hlavním cílem modularizace snížení nákladů na tvorbu a údržbu programu. Struktura každého modulu musí být natolik jednoduchá, aby byla pochopitelná vcelku. Změna implementace jednoho modulu musí být proveditelná bez znalosti detailů jiného modulu a nesmí se ho dotknout. Má to praktický dopad. Zatím co rekompilace jednoho modulu je nenákladnou záležitostí, cena rekompilace rozhraní je relativně vysoká a to zvláště u jazyků se silnou typovou kontrolou. Proto musí být rozhraní modulu tak úzké, jak je možné, aby ještě uspokojovalo potřeby ostatních modulů. V tomto stylu je vhodné ukrýt co nejvíce do implementace modulu. 
Návrhář musí stále vyvažovat dva protichůdné principy: snahu pro zapouzdření abstrakcí a snahu o zviditelnění určitých abstrakcí ostatním modulům. Parnas, Clements a Weis navrhují: Detaily systému, které se mohou změnit, musí být tajemstvím jednotlivých modulů; viditelné může být mezi moduly jen to, co se nejspíše nebude měnit. Všechny datové struktury musí být soukromé vzhledem k modulu. Mohou být dostupné programům jednoho modulu, ale nikoli programům vně modulu. Každý jiný program musí pro získání hodnot z datových struktur použít volání programů modulu.
Modularita je tedy vlastnost systému, který byl dekomponován do souboru soudržných a volně zpřažených modulů. Principy jako je abstrakce, zapouzdření a modularita vzájemně úzce souvisí.
Existují dva další technické aspekty modularizace. Jedním je znovupoužitelnost modulu v podobné aplikaci. Druhým aspektem je segmentace. Velmi často vytvářejí kompilátory cílový program ve segmentech - jeden segment pro každý modul. Velikost segmentu může být praktickou hranicí pro rozsah modulu.
Příklad na modularitu bude opět z oblasti pěstitelského plánu.  Předpokládejme, že návrhář nepoužije specializovaný hardware, ale komerčně dostupný počítač s dodaným systémem s uživatelským grafickým rozhraním. Uživatel musí mít k dispozici možnost změny nebo tvorby nového pěstovatelského plánu. Protože zde je klíčovou abstrakcí pěstovatelský plán, potřebujeme vytvořit modul, jehož účelem je shromáždit všechny třídy pro určitý daný pěstovatelský plán. V C++ napíšeme hlavičku pro takový plán s jménem gplan.h :

// gplan.h
#ifdef  _GPLAN_H
#define GPLANH 1

#include "gtypes.h"
#include "except.h"
#include "actions.h"

class GrowindPlan…

class FruintGrowingPlan

class GrainGrowingPlan
…

#endif

Zde importujeme tři hlavičkové soubory (gtypes.h, except.h a actions.h) se známým rozhraním.
Implementace tříd těchto pěstovatelských plánů se objeví v implementaci tohoto modulu v souboru, který má (podle konvence) jméno gplan.cpp.
 
Podobně můžeme definovat modul, který bude shromažďovat všechny kódy pro dialogové boxy jednotlivých aplikací. Tato jednotka závisí více na třídách deklarovaných v rozhraní  gplan.h stejně jako soubory, které zapouzdřují určitá rozhraní GUI a tak musí naopak inkludovat hlavičkový soubor gplan.h stejně jako jiné hlavičkové soubory odpovídajících GUI.

Náš systém bude zřejmě obsahovat mnoho dalších modulů, z nichž každý bude  dovážet rozhraní nižších modulů. Samozřejmě musíme mít také nějaký hlavní program, který spustí danou aplikaci v daném operačním systému. V OOP je tento program nejméně významným úkolem, zatím co v tradičním programování to byl vlastně hlavní problém.

2.2.5. Hierarchie (Obr.2.8.)

Abstrakce je důležitý princip, ale s výjimkou triviálních problémů nacházíme současně v systému velmi různé abstrakce. Zapouzdření dovoluje ukrýt detaily abstrakcí. Modularita dovoluje sdružovat logicky související abstrakce do větších celků. To vše ale u velkých systému nestačí. Množina abstrakcí vytváří určitou hierarchii. Rozpoznání a ustavení takových hierarchií velmi usnadňuje pochopení celého problému. 
Hierarchii můžeme tedy chápat jako rozdělení abstrakcí do různých úrovní a jejich seřazení. Ve složitém systému nacházíme dvě důležité hierarchie: je to struktura tříd ("druh hierarchie") a struktura objektů ("část hierarchie").
Jedním z nejdůležitějších způsobů hierarchie je dědičnost. Dědičnost definuje vztah mezi třídami, kde jedna třída sdílí strukturu nebo chování definované v jedné jiné resp. v několika jiných třídách (jednoduchá dědičnost resp. mnohonásobná dědičnost). Dědičnost pak representuje hierarchii, v níž podtřída dědí vlastnosti jedné nebo více nadtříd. Většinou podtřída rozšiřuje nebo mění existující strukturu nebo chování své nadtřídy. 
Mezi principy abstrakce, zapouzdření a hierarchií je dynamický rozpor, který nutí programátora hledat správný poměr mezi důsledky zdůraznění toho či onoho principu. Zatím co abstrakce se snaží zavést nepřehlednou barieru skrývající stav a implementaci metod, dědičnost požaduje otevření této bariery a dosažení stavu i metody. Daná třída má obvykle dva typy klientů: objekty, které vyvolají operace nad instancemi třídy a podtřídy, které zdědí vlastnosti své nadtřídy. Dědičnost umožňuje trojí porušení zapouzdření: a) Podtřída může přistoupit k instanční proměnné své nadtřídy , b) může vyvolat privátní operaci své nadtřídy, c) prostřednictvím své nadtřídy získává přístup k nadtřídám své nadtřídy. Této možnosti čelí různé programovací jazyky různým způsobem. C++ například zavedením sekcí private, public a protected.
Hirerarchie je klasifikace nebo seřazování abstrakcí

Dvě nejdůležitější hierarchie složitých systémů jsou hierarchie tříd ( "is a" – "je druhem čeho" hierarchie) a její objektová struktura (" is part of"- "je čásstí čeho" hierarchie).

Příklad jednoduché dědičnosti

Dědičnost je nejdůležitější hierarchie typu "is a" a je to základní vlastnost OOP. Dědičnost representuje hierarchii abstrakcí, v níž  podtřída dědí od jedné nebo více nadtříd. Podtřída pak nejčastěji rozšiřuje nebo modifikuje zděděné vlastnosti. Dědičnost sémantický vyjadřuje vztah typu "is a", například: "medvěd je savec", "Quick-sort je druh řadicího algoritmu". Dědičnost tak reprezentuje hierarchii typu zobecnění/specializace, kde podtřída specializuje obecnější chování své nadtřídy.
Předpokládejme, že pěstitelský plán ovoce, zeleniny a květin se v některých detailech liší. Pak můžeme z obecnější nadtřídy pěstitelského plánu odvodit speciální plán pro ovoce. V C++ lze napsat:
// Yield type
typdef unsigned int Yield;

class FruitGrowingPlan : public GrowingPlan {
public:
  FruitGrowingPlan (char* name);
  virtual ~FruitGrowingPlan();

  virtual void establish(Day, Hour, Condition);
  void scheduleHarvest() const;
  Yield estimatedYield() const;

protected
  Boolean repHarvested;
  Yield repYield;
};
Definice této třídy postihuje dva aspekty: FruitGrowingPlan je speciálním druhem GrowingPlan s určitou dodatečnou strukturou (repHarvested a repYield) a chováním (čtyři nové členské funkce a modifikující-přepisující operace establish). S použitím tto třídy můžeme vytvořit ještě speciálnější plán např. AppleGrowingPlan. 

Příklad vícenásobné dědičnosti

Předcházející příklad ukazoval jednoduchou dědičnost. Podtřída FruitGrowingPlan měla právě jednu nadtřídu GrowingPlan. Představme si, že chceme definovat třídu reprezentující druh rostliny. 

class Plant {
public:
  Plant (char* name, char* species);
  virtual ~Plant();

  void setDatePlanted(Day);
  virtual establishGrowingConditions(const Condition&);

  const char* name() const;
  const char* soecies() const;
  Day datePlanted() const;

protected:
  char* repName;
  char* repSpecies;
  Day repPlanted;
private:
  …
};

Podle této definice má každá instance této třídy Plant jméno, druh a datum sadby. Dodatečně mohou být pro každý druh stanoveny jiné podmínky, je operace establishGrowingCondition virtuální, aby mohly být v podtřídě modifikovány. Z analýzy problémové domény může vyplynout význam doby, kdy rostlina kvete, kdy se rostlina sklízí, seje apod. Může nastat případ, kdy rostlina která kvete, poskytuje jako produkt květy a později i plody a tak může vzniknout třída, která dědí vlastnosti od třídy kvetoucího rostlin i od třídy rostlin s plody.

class FlowerMixin {
public:
  FlowerMixin}Day timeToFlower, Day timeToSeed);
  virtual ~FlowerMixin();

  Day timeToFlower() const;
  Day timeToSeed() const;

protected:
 …
};

class FruitVegetableMixin {
public:

  FruitVegetableMixin(Day timeToHarvest);
  virtual ~FruitVegetableMixin();

  Day timeToHarvest() const;

protected:
…
};

Tyto dvě třídy nemají žádné nadtřídy. Jsou to "směsné" třídy (mixin), které se obě mají použít pro vytvoření podtřídy. Pak můžeme např. třídu Rose vutvořit takto:

 class Rose : public Plant, public FlowerMixin …

Podobně mrkev může být definována jako:

class Carrot: public Plant, public FruitVegetableMixin {};
Vytvoření třídy rostliny, u níž se sklízí květy i ovoce, jako je třeba třešeň, má podobu:

class Cherry : 	public Plant,
				public FlowerMixin,
				public FruitVegetableMixin …

Vícenásobní dědičnost je zdánlivě přímočará, má však některé problémy. Musí se vypořádat s kolizí jmen zděděných od dvou rodičovských tříd a s  opakovaným zděděním téhož atributu. V C++ musí být  problém kolize jmen řešen explicitní kvalifikací. Opakované dědění je v C++ ovládáno podle toho, zda je metoda virtuální nebo ne. Básová virtuální metoda sdílí opakované struktury, zatím co nevirtuální metody duplikují kopie a musí se použít explicitní kvalifikace k jejich rozlišení.

Agregace

Zatím co hierarchie typu "je druhem čeho" vyjadřuje zobecnění/specializaci, hierarchie typu "je částí čeho" vyjadřuje vztah agregace. Např. třída "Zahrada" je sloučením různých rostlin spolu s jejich pěstitelskými plány.

class Garden {
public:
  
  Garden();
   virtual ~Garden();
...
protected:
  Plant* repPlants[100];
  GrowingPlan repPlan;
};
Agregace je obdoba struktury typu record. Kombinace agregace s dědičností je velmi účinná. Agregace dovoluje  fyzické shlukování struktur s logickou vazbou a dědičnost umožňuje aby tyto skupiny byly snadno znovupoužitelné v různých abstrakcích.

 
2.2.6. Kontrola typu (Typing) (Obr.2.8.) 

Princip kontroly typu se primárně odvozuje od teorie abstraktních typů. V objektově orientovaném světě se často pojem "typ" a "třída" zaměňuje. Existují jazyky, které tyto pojmy odlišují. I teoreticky to však přináší málo výhod. Kontrola typu je však poněkud specifičtější pojem. 
Kontrola typu je vlastnost třídy objektů, která způsobuje, že objekty různých typů nemohou být zaměnitelné, nebo mohou být zaměnitelné za zvláštních omezujících podmínek. Podle toho se hovoří o silné nebo o slabé kontrole typů.

2.2.6.1. Příklady silné a slabé typové kontroly

Vraťme se k příkladu skleníku a jeho uživatelskému rozhraní a předpokládejme tyto (neúplné) třídy pro různé nádoby, které mohou mít různé tvary a mohou být určeny pro různý obsah, jako např. tekutý, sypký apod.
//Number denoting level from 0 to 100 %
typedef float Level;

V C++ neuvádí definice typedef nový typ. V uvedených příkladech např. Level nebo Concetracion jsou obě čísla v pohyblivé čárce a mohou být vzájemně směšována. Z tohoto pohledu je C+ jazyk se slabou kontrolou typů. Hodnoty primitivních typů jako int a float jsou nerozlišitelné, na rozdíl od Pascalu nebo Ady. 

class StorageTank  {
public:
 StorageTank();
 virtual ~StorageTank();

 virtual void fill();
 virtual void startDraining();
 virtual void stopDraining();

 Boolean isEmpty() const;
 Level level() const;

protected:
 …
};

class WaterTank: public StorageTank {
public:
  WaterTank();
  virtual ~WaterTank();
 
  virtual void fill();
  virtual void startDraining();
  virtual void stopDraining();
  void startHeating();
  void stopHeating();

  Temperature currentTemperature() const;

protected:
 …
};

class NutrientTank : public StorageTank {
public:
  NutrientTank();
  virtual ~NutrientTank();

 virtual void startDraining();
 virtual void stopDraining();

protected:
…
};

Třída StorageTank je v této hierarchii bázoví třída a poskytuje strukturu a chování společné pro všechny nádoby, jako je možnost jejich plnění, vyprazdňování atd. WaterTank a NutrientTank jsou podtřídy, které dědí vlastnosti nadtřídy a WaterTank zavádí novou vlastnost týkající se teploty obsahu.

Předpokládejme, že máme následující deklarace:

StorageTank s1, s2;
WaterTank w;
NutrientTank n;

Proměnné s1, s2, w, n nepředstavují objekty ale pouze jména objektů, které npatří do příslušných tříd. Tato skutečnost bude vysvětlena později.

Z toho pohledu má jazyk C++ poněkud silnější typovou kontrolu, což znamená, že výrazy, které vyvolávají operace jsou kontrolovány v době kompilace. 

Můžeme napsat příkazy:
Level l= s1.level();
w.startDraining();
n.stopDraining();

ale nemůžeme napsat:
s1.startHeating();
n.stopHeating();

Je ale možno napsat:

n.fill();

i když fill není definováno ve třídě NutrientTank.

Silné typování, které poskytuje programovací jazyk, dovoluje  zdůraznit některá návrhová rozhodnutí, což je tím významnější, čím je složitost a rozsáhlost programu větší.  Má však i svou stinnou stránku. Silná typová kontrola vnáší sémantickou závislost, která vynucuje rekompilaci všech podtříd i při malé změně v rozhraní bázové třídy.  
Silně typované jazyky vyžadují typovou konzistenci ve výrazech  i v přiřazovacím příkazu. Následující přiřazovací příkazy jsou legální:
	s1=s2;
	s1=w;

První příkaz je v pořádku, protože na obou stranách přiřazovacího příkazu jsou objekty téže třídy StorageTank. Druhý příklad je také korektní, protože na levé straně přiřazovacího příklazu je objekt, který patří nadtřídě (StorageTank) vzhledem k objektu na pravé straně (WaterTank). Při té příležitosti však dojde k redukci přiřazované informace, které se u jazyka C++ říká "slicing". 
V některých případech je nutné konvertovat hodnotu z jednoho typu do druhého. Mějme např. následující funkci:
	void checkLevel(const StorageTank& s);

Pouze v tom případě, že jsme si jisti, že skutečný parametr je  člen třídy WaterTank, můžeme explicitně vnutit hodnotu objektu bázové třídy (s patří do StorageTank) podtřídě (WaterTank), jako např:
	if (((WaterTank&)s).currentTemperature() <  32.0 …
Tento výraz je typově konzistentní, ale není zcela bezpečný. Kdyby se náhodou stalo, že s je objekt třídy NutrientTank, pak by vnucení hodnoty přineslo nepředvídatelné výsledky v době výpočtu. Obecně se podobné konverze nedoporučují, protože vždy představují určité násilí na abstrakci.
Silná kontrola typů je významnou pomůckou pro dosažení spolehlivého programu. Velmi často je však překážkou tvořivému a málo ukázněnému programátorovi. Mezi významné výhody silné kontroly typů lze vyjmenovat:
•	Bez použití silné typové kontroly se často stává, že program se zhroutí v době výpočtu z neznámých nebo obtížně zjistitelných důvodů.
•	Ve většině systémů je vývojový cyklus "editace-překlad-ladění" natolik jednotvárný, že co nejvčasnější nalezení chyb je nezbytné.
•	Povinné deklarace všech typů zlepšují dokumentační vlastnosti programu.
•	Většina kompilátorů generuje lepší cílový kód, může-li využít deklarací typů.

Jazyky bez typové kontroly nabízejí větší flexibilitu a variabilitu, ale i v těchto jazycích většinou programátor ví, jaký typ objektu je očekáván jako argument zprávy a jaký typ bude na výstupu. Z praxe vyplývá, že bezpečnost, která vyplývá z použití typové kontroly více než kompenzuje ztrátu flexibility. Tato zkušenost sílí se zvětšujícím se rozsahem navrhovaného programového systému. 

2.2.6.2. Příklady typové kontroly: Statická a dynamická vazba.

Pojmy silné kontroly typů a dynamické kontroly typů jsou odlišné. Silná kontrola typů se vztahuje k typové konzistenci, zatím co statická kontrola typů - známá také pod názvem "včasná vazba" (early binding)- se vztahuje k okamžiku, kdy je identifikátor svázán s typem - v době kompilace. Dynamická vazba, nazývaná také "pozdní vazba" (late binding), znamená, že typ všech proměnných není znám v době kompilace, ale až v době výpočtu. Protože jde o různé pojmy, mohou existovat v různých kombinacích: ADA má silnou a statickou kontrolu typů; Object Pascal a C++ má silnou kontrolu typů a podporuje dynamickou (pozdní) vazbu. Smalltalk nemá silnou kontrolu a podporuje pozdní vazbu, apod. 
Důsledkem dynamické vazby typů je polymorfismus - který znamená, že operace s daným jménem se chová různě podle parametrů, se kterými pracuje (tak se např. chová příkaz read v Pascalu; jinak se chová, při čtení vstupní proměnné typu real, jinak při čtení integer). Opakem polymorfismu je monomorfismus, který je typický pro všechny jazyky se silnou a statickou kontrolou typů.
Zatímco silná kontrola typů se týká konzistence dvou typů, statická vazba (včasná) nebo dynamická vazba (pozdní) se týkají doby, kdy jsou dva typy provázány. Dynamická vazba říká, že hodnota proměnné není známa dříve, než v době výpočtu. 
Ilustrujme princip na příkladu z C++. Mějme následující nečlenskou funkci. (Pozn. – nečlenská funkce není přímo spjata s třídou a říká se jí také "volný podprogram". V některých čistě OOJ jako např. Smalltalk volné podprogramy neexistují). 
void balanceLevel(StorageTank& s1, StorageTank& s2);
Volání operace balanceLevel s instancemi StorageTank  nebo s instancemi libovolné podtřídy na linii dědičnosti je typově konzistentní, protože bázovým typem je StorageTank. Uvnitř implementace této funkce můžeme mít výraz jako:
	if (s1.level() > s2.level())
             s2.fill();
Jaká je skutečná sémantika selektoru "level"? Tato operace je deklarována pouze v bázové třídě StorageTank, a tak bez ohledu na podtřídu instance, pro formální parametr s1 se vyvolá oprace bázové třídy, což se rozhodne v době kompilace.
Na druhé straně uvažujme o sémantice vyvolání modifikátoru "fill", který je svázán dynamicky. Tato operace je definována v bázové třídě a pak je předefinována pouze v podtřídě WaterTank. Je-li s1 instance třídy  WaterTank, pak se vyvolá WaterTank::fill. Tomuto jevu se říká polymorfismus  a jeho principem v teorii typů je, že jedno jméno může označovat mnoho objektů různých tříd, které mají společnou nadtřídu. Opakem polymorfismu je monomorfismus, který je typický pro jazyky se silnou kontrolou typů se statickou vazbou. Polymorfismus se vyskytuje tam, kde dědičnost spolupracuje s dynamickou (pozdní) vazbou a patří k nejmocnějším nástrojům, kterým odlišuje objektově orientované programování od tradičního. 

2.2.7 Paralelnost ("Souběžnost" - Concurrency) (Obr.2.9.)

Některé problémy jsou typické tím, že ovládají několik událostí současně. Některé jiné problémy mají tolik výpočtových aktivit, že jejich množství přesahuje kapacitu jednoho procesoru. V takových případech je přirozené uvažovat o použití distribuované množiny počítačů, nebo o použití procesoru, který umožňuje zpracovávat (rozpracovat) několik procesů současně v režimu zvaném "multitasking". Jednomu procesu se také říká "linie řízení" ("thread of control"). Každý program má jednu linii řízení; systém s paralelismem má takových linií mnoho. Víceprocesorový systém umožňuje skutečné zpracování více linií řízení současně. Systém pracující na jednom procesoru umožňuje ilusi paralelnosti tím, že rozpracovává několik linií, a každé přiděluje určitý krátký úsek času jednoho procesoru. 
Objektově orientovaný přístup nepřináší nové pohledy na paralelní chování systému. Při řešení násobných linií řízení musíme i nadále řešit problémy typické pro paralelní systémy, jako je uváznutí (deadlock), vzájemné vylučování (mutual exclusion), stav nedostatečného přidělování času (starvation), pravidla soupeření o přidělování času (race condition) atd. Objektově orientovaný přístup může na nejvyšší úrovni abstrakce pomoci paralelnosti tím, že ji skryje uvnitř opakovaně použitelné abstrakce. Objektově orientovaný přístup je použitelný pro distribuované systémy protože implicitně definuje jednotky distribuovanosti, pohybu a entit, které komunikují. Zatímco objektově orientované programování se soustřeďuje na abstrakci dat, zapouzdření a dědičnost, paralelnost se zaměřuje na abstrakci procesů a synchronizaci. Objekt je princip, který může sjednocovat oba přístupy; každý objekt (vzatý z reálného světa) může reprezentovat jednu oddělenou linii řízení (abstrakce procesu). Takovým objektům říkáme, že jsou aktivní. V systému založeném na OO principech chápeme svět tak, jako by se skládal z množiny spolupracujících objektů, z nichž některé jsou aktivní a slouží jako centra nezávislé aktivity. Pak lze paralelnost chápat jako vlastnost, která rozlišuje aktivní objekt od neaktivního. 
Příklad paralelnosti:
 
V předcházejícím textu jsme zavedli třídu ActiveTemperatureSensor.  Prvek této třídy periodicky snímal teplotu a v případě že vybočila ze stanoveného intervalu, vyvolala funkci klientského objektu. Nevysvětlili jsme princip tohoto chování, které bylo ukryto v iplementaci, ale je zřejmé, že jde o jistý způsob paralelismu (angl. concurency).  Obecně lze říci, že v OOD jde o tři možné přístupy k paralelismu. 
•	Paralelnost je vnitřní vlastností programovacího jazyku a každý z nich poskytuje různé nástroje pro jejich realizaci.
•	Lze použít knihovnu tříd pro některé jednoduché procesy. To je příklad knihovny AT&T pro C++, která poskytuje třídy Sched, Timer, Task a jiné. Implementace knihovnu je pochopitelně implementačně závislé, ale rozhraní je poměrně přenosné. 
•	Pro ilusi paralelnosti lze využít přerušení. To ale vyžaduje trochu více znalosti na hardwarové úrovni.  Např. pro náš případ můžeme mít hardwarový časovač, který periodicky přerušuje aplikaci a zjišťuje teplotu ze senzorů a v případě vybočení z intervalu  vyvolává klientskou funkci. Nezáleží na tom, jak druh paralelnosti zavedeme do našeho problému, ale podstatné je, jak budeme synchronizovat činnosti aktivních objektů s ostatními aktivními objekty i s objekty, které jsou čistě sekvenční. Pokouší-li se např. dva objekty zaslat současně zprávu objektu třetímu, musíme zajistit, např. principem vzájemného vyloučení, že třetí objekt nebude porušen v důsledku nekoordinované intervence dvou zájemců.

2.2.8 Perzistence (persistence)

Objekt jako součást programu zabírá určitý paměťový prostor a existuje po určitý čas. Doba existence se může pohybovat od přechodnosti mezivýsledků při vyčíslování výrazu až po data, která trvají i po ukončení programu. Spektrum trvání dat lze vyjádřit následujícími příklady:
•	mezivýsledky vyčíslování výrazů
•	lokální proměnné při aktivaci procedury
•	globální proměnné 
•	data, která existují mezi dvěma spuštěními programu
•	data, která existují mezi různými versemi programu
•	data, která přežijí program

Tradiční jazyky používají většinou typy podobné prvním třem příkladům. Perzistence - přetrvání - je charakteristickým rysem především v databázové technologii. Potřeba perzistence vede často k programátorské lidové tvořivosti, ve které jsou vytvářeny nejrůznější struktury pro uchování objektů, které mají být uchovány pro následující spuštění programu a k databázím, v nichž perzistentní data musí spolupracovat s dočasnými objekty.
Sjednocení principu paralelnosti a objektů vede k paralelním objektově orientovaným jazykům. Podobně sloučení principů perzistence a objektů vede k objektově orientovaným databázím. V praxi jsou takové databáze založeny na určité technologii struktury, ať již jde o sekvenční, indexový, hierarchický, síťový nebo relační model, v němž jsou databázové dotazy a jiné operace realizovány nad objekty, které trvají déle, než provedení jejich programu. 
Persistence však zahrnuje více než dobu života objektu. V objektově orientované databázi musí přežít nejen stav objektu, ale i jeho třída, aby každý program interpretoval uchovaný stav objektu stejným způsobem. S tím roste i složitost úkolu, jak zachovat integritu databázového systému s jeho postupným nárůstem, zejména, musíme-li měnit třídu objektu.
Na perzistenci jsme se zatím dívali pouze z pohledu času. Lze ale na ni nazírat také z pohledu prostoru. Zatím se objekt jevil jako entita zabírající určitý prostor od svého vzniku do svého zániku. V distribuovaných systémech se však objekt může přesunovat z procesoru na procesor, na  každém musí zabírat stejný prostor a dokonce i stejnou representaci.
Perzistenci můžeme definovat jako vlastnost objektu, která dovoluje objektu přetrvat v čase (objekt trvá déle než jeho "stvořitel") a/nebo v prostoru (objekt se může přesunout z prostoru, v němž vzniknul do jiného prostoru). 

2.3. Použití objektového modelu
2.3.1. Výhody objektového modelu

Model navrhovaného systému založený na OO přístupu se základně liší od modelů, vytvořených na základě tradičních metod strukturované analýzy, strukturovaného návrhu a strukturovaného programování. To neznamená, že by objektový přístup nepoužíval nejvýznamnější principy předcházejících metod. Doplnil je o některé nové principy, a nabízí možnosti, které předchozí metody neměly. Objektový model vede ke konstrukci systému, který má pět základních vlastností dobře strukturovaného složitého systému, jak byly uvedenu v odst.1.2. Má i některé další praktické výhody:
•	Umožňuje využívat výrazné vlastnosti OO jazyků. Stroustrup říká, že: " Není vždy jasné, jak využít vlastností jazyka jako je C++. Zlepšení produktivity se projevuje s použitím C++ jako lepší verze C s použitím datových abstrakcí tam, kde je to jasně užitečné. Mnohem významnější zlepšení se ale projeví využije-li se tříd a jejich hierarchií již v etapě návrhu. Tomu se říká OO návrh a pak lze účinně využít vlastností, které má C++. Naše zkušenost říká, že bez použití principů objektového modelu se silné vlastnosti jazyků jako je Smalltalk, Object Pascal, C++, CLOS a Ada buď ignorují, nebo používají špatně."
•	Objektový model podporuje znovupoužití nejen části programu ale také principu návrhu. Prokázalo se, že objektově orientované systémy jsou co do implementace menší než ekvivalentní implementace neobjektové. 
•	Objektový model produkuje systémy, které jsou postaveny na stabilních meziformách a tím jsou přístupnější ke změnám. To znamená, že tyto systémy dovolují snadný vývoj s postupem času a není nutné je opustit a provést nový návrh při první výraznější změně požadavků.
•	Objektový model snižuje riziko vytvoření příliš složitých systémů, protože jejich tvorba a růst je začleněn do celého životního cyklu spíše, než do první explosívní fáze návrhu ve stylu velkého třesku.
•	Objektový přístup je přirozený pro lidské myšlení. Mnoho lidí, kteří vůbec nevědí jak pracuje počítač, shledají principy objektově orientovaného modelu systému zcela přirozené.

Mezi typické aplikace objektového modelu lze uvést např. tyto oblasti:

Řízení letového provozu
Animace
Avionika
Software pro bankovnictví a pojišťování
Zpracování hromadných obchodních dat
Řízení chemických procesů
Ovládací a řídicí systémy
Návrh za podpory počítače (CAD)
Vyučování za podpory počítače (CAE)
Výroba s podporou počítače
Databázové systémy
Příprava dokumentů
Expertní systémy
Filmové a divadelní aktivity s podporou počítače
Hypermedia
Rozlišování obrazců
Investiční strategie
Matematické analýzy
Biomedicínská elektronika
Hudební kompozice
Automatizace kancelářských prací
Operační systémy
Naftařské inženýrství
Znovupoužitelné programové komponenty
Robotika
Programové vývojové prostředky
Kosmické aplikace
Kosmická a letecká simulace
Telemetrické systémy
Návrh uživatelského rozhraní
Návrh VLSI 
aj.

2.4. Souhrn kapitoly

Vývoj softwarového inženýrství dospěl k objektově orientované analýze, návrhu a programování. Tyto metody jsou vhodné především pro "programování ve velkém" - tedy pro vytváření rozsáhlých programových systémů.
Existuje několik základních programovacích paradigmat (přístupů):
Procedurově-orientované, objektově orientované, logicky orientované, orientované na pravidla a orientované na omezení.
Objektový model poskytuje principiální rámec pro OO metody. Používá principů abstrakce, zapouzdření, modularity, hierarchie, kontroly typů, paralelnosti a perzistence.
Abstrakce se vyznačuje zdůrazněním základních vlastností objektu, kterými se objekt liší od ostatních. Vytváří jasně definované principiální hranice, které jsou relativní s ohledem na pozorovatele.
Zapouzdření je proces ukrývání detailů objektu, které nepřispívají k charakteristice jeho základních vlastností.
Hierarchie je uspořádání objektů do různých úrovní abstrakce.
Kontrola typů je vlastnost třídy a jejích objektů, která nedovoluje vzájemnou záměnu objektů různých typů, nebo ji povoluje za přesně vymezených pravidel.
Paralelnost je vlastnost, která dovede rozlišit aktivní objekty od neaktivních.
Persistence je vlastnost objektů, která dovoluje jejich existenci překonávající čas a/nebo prostor.
Aplikace objektově orientovaného modelu vede k systémům, které mají 5 základních vlastností dobře strukturovaného složitého systému.