Sunteți pe pagina 1din 15

Capitolul 7

ablonul de proiectare Metoda Fabric


1. Obiective 2. ablonul creaional Metoda Fabric 3. Exemplu de implementare 4. Motenirea i polimorfismul 5. Aplicaii

1. Obiective
Obiectivele capitolului 7 sunt urmtoarele: Implementarea unui program dup ablonul de proiectare Metoda Fabric (engl. Factory Method); Precizarea unor noiuni privind motenirea i polimorfismul (clase abstracte, interfee, membri virtuali), utilizate n majoritatea abloanelor de proiectare.

2. ablonul creaional Metoda Fabric


ablonul Metoda Fabric definete o interfa pentru crearea unui obiect, dar las subclasele s decid ce clas s instanieze. Diagrama de clase este prezentat n figura 7.1.

Figura 7.1. Diagrama de clase a ablonului Metoda Fabric


151
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Florin Leon Aplicaii de ingineria programrii n C#

O alt diagram n care avem doi creatori i dou produse este prezentat n figura 7.2.

Figura 7.2. Diagrama de clase cu doi creatori i dou produse

Metoda Fabric se folosete n general atunci cnd o clas nu poate ti sau nu dorete s specifice din ce clas va fi creat un obiect i n consecin las clasele derivate s specifice clasa acestuia.

3. Exemplu de implementare
Codul C# corespunztor diagramei UML anterioare este prezentat mai jos. Clasele Produs
abstract class Product { } class ConcreteProductA : Product { } class ConcreteProductB : Product { }

152
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Capitolul 7. ablonul de proiectare Metoda Fabric

Clasele Creator
abstract class Creator { // Metode abstract public Product FactoryMethod(); }

class ConcreteCreatorA : Creator { // Metode override public Product FactoryMethod() { return new ConcreteProductA(); } } class ConcreteCreatorB : Creator { // Metode override public Product FactoryMethod() { return new ConcreteProductB(); } }

Clientul
class Client { public static void Main( string[] args ) { // FactoryMethod returneaz ProductA Creator c = new ConcreteCreatorA(); Product p = c.FactoryMethod(); Console.WriteLine("A fost creat {0}", p ); // FactoryMethod returneaz ProductB c = new ConcreteCreatorB(); p = c.FactoryMethod(); Console.WriteLine("A fost creat {0}", p ); } }

153
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Florin Leon Aplicaii de ingineria programrii n C#

4. Motenirea i polimorfismul
4.1. Polimorfismul
Cu ajutorul motenirii, o clas poate fi folosit ca i cum ar reprezenta mai multe tipuri. Ea poate fi folosit ca propriul su tip, ca un tip de clas de baz, sau un tip de interfa pe care o implementeaz. Acest comportament este numit polimorfism. n C#, orice tip este polimorfic. Un tip poate fi folosit aa cum este sau ca o instan de object, pentru c orice tip consider automat tipul object ca tip de baz. Polimorfismul este important nu numai pentru clasele derivate, ci i pentru clasele de baz. Cnd se folosete o clas de baz, se poate folosi de fapt orice clas derivat. Proiectanii unei clase de baz pot anticipa aspectele claselor care se vor modifica prin derivare. De exemplu, o clas de baz pentru maini poate conine membri care se modific dac maina este o dubi sau o main decapotabil. O clas de baz poate marca acei membri ca virtuali, dnd posibilitatea claselor derivate care reprezint maina decapotabil i dubia s suprascrie comportamentul respectiv. Cnd o clas derivat motenete o clas de baz, ea primete toate metodele, cmpurile, proprietile i evenimentele clasei de baz. Pentru a modifica datele i metodele unei clase de baz exist dou posibiliti: se poate nlocui clasa de baz cu una derivat sau se poate suprascrie un membru virtual din clasa de baz.

4.2. Clase abstracte


Cuvntul cheie abstract ofer posibilitatea crerii claselor i membrilor de clase doar pentru a putea fi motenii: pentru a defini trsturi ale claselor derivate, neabstracte.
public abstract class A { // membrii clasei }

O clas abstract nu poate fi instaniat. Scopul su este s ofere o definiie comun pentru mai multe clase derivate. De exemplu, o bibliotec de clase poate defini o clas abstract care este folosit ca parametru n mai

154
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Capitolul 7. ablonul de proiectare Metoda Fabric

multe funcii din bibliotec i necesit ca dezvoltatorii care o folosesc s asigure o implementare proprie prin crearea unei clase derivate. Clasele abstracte pot de asemenea s defineasc metode abstracte, prin adugarea cuvntului cheie abstract n faa tipului returnat de metod. De exemplu:
public abstract class A { public abstract void Method(int i); }

Metodele abstracte nu au implementare i deci definiia metodei este urmat de ; n locul unui bloc normal de cod. Clasele derivate neabstracte trebuie s implementeze toate metodele abstracte.

4.3. Interfee
Interfeele sunt definite cu ajutorul cuvntului cheie interface. De exemplu:
interface IComparable { int CompareTo(object obj); }

Interfeele descriu un grup de funcionaliti asemntoare care pot s aparin oricrei clase sau structuri. Interfeele pot conine metode, proprieti, evenimente sau indeci, ns nu pot conine cmpuri. Membrii unei interfee sunt implicit publici. Clasele i structurile pot moteni interfee ntr-un mod asemntor claselor care motenesc clase sau structuri, cu dou excepii:

O clas sau structur poate moteni mai multe interfee; Cnd o clas sau structur motenete o interfa, motenete doar numele metodelor i semnturile acestora, deoarece interfeele nu conin implementri.

n exemplul urmtor, clasa Minivan este derivat din clasa Car i implementeaz interfaa IComparable.

155
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Florin Leon Aplicaii de ingineria programrii n C# public class Minivan : Car, IComparable { public int CompareTo(object obj) { // implementarea metodei CompareTo return 0; // dac obiectele sunt egale } }

Pentru a implementa un membru al unei interfee, membrul respectiv trebuie s fie public, nestatic i s aib acelai nume i semntur cu membrul interfeei. Interfeele pot moteni alte interfee. Este posibil ca o clas s moteneasc o interfa de mai multe ori, printr-o clas sau interfa motenit. n acest caz, clasa poate implementa interfaa doar o dat. O interfa are urmtoarele caracteristici:

Este similar unei clase de baz abstracte: orice tip neabstract care motenete o interfa trebuie s i implementeze toi membrii; O interfa nu poate fi instaniat direct; Interfeele pot conine metode, proprieti, evenimente i indeci; Interfeele nu conin implementri ale metodelor; Clasele i structurile pot moteni mai multe interfee; O interfa poate ea nsi s moteneasc mai multe interfee.

4.4. Membri virtuali


Pentru ca o clas derivat s reimplementeze un membru al unei clase de baz, clasa de baz trebuie s defineasc membrul ca virtual iar clasa derivat s foloseasc cuvntul cheie override pentru a nlocui implementarea membrului. De exemplu:
public class BaseClass { public virtual void Method() { ... }

156
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Capitolul 7. ablonul de proiectare Metoda Fabric public virtual int Property { get { ... } } } public class DerivedClass : BaseClass { public override void Method() { ... } public override int Property { get { ... } } }

Cmpurile nu pot fi virtuale, doar metodele, proprietile i indecii. Cnd o clas derivat suprascrie un membru virtual, acel membru este apelat chiar i atunci cnd o instan a acelei clase este accesat ca o instan a clasei de baz. De exemplu:
DerivedClass B = new DerivedClass(); B.Method (); // Apeleaz metoda nou BaseClass A = (BaseClass)B; A.Method (); // Apeleaz tot metoda nou

Un membru virtual rmne astfel n toat ierarhia de clase, indiferent de numrul de niveluri dintre clasa de baz i cea curent. Dac n clasa A este declarat un membru virtual i clasa B este derivat din clasa A iar clasa C este derivat din clasa B, atunci clasa C motenete membrul virtual i poate s l suprascrie, chiar dac n clasa B el a fost deja suprascris. De exemplu:
public class A { public virtual void Method() { ... } } 157
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Florin Leon Aplicaii de ingineria programrii n C# public class B : A { public override void Method() { ... } } public class C : B { public override void Method() { ... } }

4.5. Clase sigilate i membri sigilai


Sigilarea mpiedic motenirea claselor sau suprascrierea membrilor virtuali. O clas pot fi declarat ca sigilat, punnd cuvntul cheie sealed naintea cuvntului class la definirea acesteia:
public sealed class A { // membrii clasei }

O clas sigilat nu poate fi folosit drept clas de baz. Din aceast cauz, ea nu poate fi nici abstract. Clasele sigilate sunt folosite, n principiu, pentru a preveni derivarea. Neputnd fi folosite ca i clase de baz, unele optimizri n timp real pot face apelul membrilor acestora mai rapid. Un membru, o metod, o proprietate sau un eveniment al unei clase derivate care suprascrie un membru virtual al clasei de baz poate declara acel membru ca sigilat. Astfel se elimin aspectul virtual al membrului pentru orice clas viitoare derivat. De exemplu:

158
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Capitolul 7. ablonul de proiectare Metoda Fabric public class B { public virtual void Method() { ... } } public class C : B { public sealed override void Method() { ... } }

n exemplul anterior, metoda Method nu mai este virtual pentru nicio clas derivat din C. Dar este nc virtual pentru instanele clasei C.

4.6. nlocuirea unui membru cu ajutorul cuvntului cheie new


nlocuirea unui membru din clasa de baz cu unul nou, derivat, necesit folosirea cuvntului cheie new. Dac o clas de baz definete o metod, un cmp sau o proprietate, cuvntul cheie new se utilizeaz pentru a crea o nou definiie n clasa derivat. Cuvntul cheie new trebuie pus naintea tipului returnat al membrului clasei. De exemplu:
public class BaseClass { public void Method() { ... } public int Property { get { ... } } }

159
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Florin Leon Aplicaii de ingineria programrii n C# public class DerivedClass : BaseClass { public new void Method() { ... } public new int Property { get { ... } } }

Cnd se folosete cuvntul cheie new, noul membru este apelat n locul celui vechi, nlocuit. Membrii respectivi ai clasei de baz sunt numii membri ascuni. Ei mai pot fi apelai doar dac o instan a clasei derivate este convertit prin cast la o instan a clasei de baz. De exemplu:
DerivedClass B = new DerivedClass(); B.Method (); // Apeleaz metoda nou BaseClass A = (BaseClass)B; A.Method (); // Apeleaz metoda veche

4.7. Accesarea clasei de baz cu ajutorul cuvntului cheie base


O clas derivat care a nlocuit sau suprascris o metod sau proprietate poate nc accesa metoda sau proprietatea din clasa de baz folosind cuvntul cheie base. De exemplu:
public class A { public virtual void Method() { ... } }

160
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Capitolul 7. ablonul de proiectare Metoda Fabric public class B : A { public override void Method() { ... } } public class C : B { public override void Method() { // apeleaz Method din B pentru a utiliza comportamentul lui B base.Method(); // comportamentul specific lui C urmeaz n continuare ... } }

Se recomand ca un membru virtual s utilizeze cuvntul cheie base pentru a apela implementarea membrului din clasa de baz n implementarea proprie. Prin aceasta este lsat clasa derivat s se axeze pe implementarea propriilor funcionaliti. Dac nu este apelat implementarea din clasa de baz, atunci clasa derivat va trebui s se ocupe de implementarea unor funcionaliti similare cu acelea ale clasei de baz. Cuvntul cheie base este folosit:

Pentru a apela o metod din clasa de baz care a fost suprascris de o alt metod; Pentru a specifica clasa de baz al crei constructor s fie apelat la instanierea clasei derivate.

Din metodele statice nu este permis accesul la clasa de baz prin cuvntul cheie base.

5. Aplicaii
5.1. Realizai o aplicaie care deschide i afieaz fiiere text i grafice (figura 7.3). Testul se va efectua dup extensia fiierului (txt, rtf, bmp, jpg). Se va utiliza ablonul de proiectare Metoda fabric.
161
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Florin Leon Aplicaii de ingineria programrii n C#

Figura 7.3. Exemplu de rezolvare: interfaa cu utilizatorul

Figura 7.4. Exemplu de rezolvare: fiierele de test


162
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Capitolul 7. ablonul de proiectare Metoda Fabric

Aplicaia deschide fiiere index cu extensiile txd, pentru fiiere text, respectiv grd, pentru fiiere grafice. Aceste fiiere index conin cile ctre mai multe fiiere cu extensiile txt sau rtf, respectiv bmp sau jpg. Un exemplu privind structura de directoare i fiiere, precum i coninutul fiierelor index este prezentat n figura 7.4. Diagrama de clase este prezentat n figura 7.5.

Figura 7.5. Exemplu de rezolvare: diagrama de clase

Indicaii. Pentru citirea fiierelor text se poate utiliza clasa StreamReader din System.IO. Pentru fiierele text i rtf se poate utiliza clasa RichTextBox din System.Windows.Forms cu metoda LoadFile. Pentru
163
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Florin Leon Aplicaii de ingineria programrii n C#

fiierele grafice se poate utiliza clasa Bitmap unde numele fiierului este primit n constructor sau proprietatea ImageLocation din clasa PictureBox. Pentru deschiderea unui fiier se utilizeaz un control OpenFileDialog. Pentru a se deschide doar tipurile de fiiere cu extensiile txd sau grd, se seteaz proprietatea Filter cu valoarea "Text documents (*.txd)|*.txd|Graphic documents (*.grd)|*.grd". n evenimentul corespunztor butonului Open, se poate prelucra un fiier doar dac utilizatorul a ales un fiier i a dat OK n fereastra de deschidere de fiiere.
if (openFileDialog.ShowDialog() != DialogResult.OK) return;

Apoi se testeaz valoarea proprietii FilterIndex din obiectul openFileDialog, care indic tipul de fiier deschis (index text sau index grafic). Indexul pleac de la 1, nu de la 0. n continuare, se instaniaz un obiect TextDocument sau un GraphicDocument. Afiarea paginilor n obiectul tabControl se poate face n modul urmtor:
Document doc; ... // crearea obiectului document (creatorul concret) tabControl.Controls.Clear(); foreach (Page p in doc.Pages) { TabPage tp = new TabPage(p.Name); p.Content.Dock = DockStyle.Fill; tp.Controls.Add(p.Content); tabControl.TabPages.Add(tp); }

Secvena de cod de mai sus se recomand a fi inclus ntr-un bloc de tratare a excepiilor, deoarece pot aprea probleme referitoare la deschiderea unui fiier care s nu conin ci valide sau fiierele indicate de aceste ci s nu aib coninutul ateptat. n produsele concrete se creeaz controalele corespunztoare iar numele paginilor afiate n tabControl se determin din numele fiierului ncrcat:
_name = Path.GetFileNameWithoutExtension(fileName);

164
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

Capitolul 7. ablonul de proiectare Metoda Fabric

n constructorul creatorului abstract (Document) se citete fiierul index linie cu linie i se creeaz paginile corespunztoare:
StreamReader sr = new StreamReader(indexFileName); string line; while ((line = sr.ReadLine()) != null) { if (line != string.Empty) _pages.Add(CreatePage(line)); } sr.Close();

ns deoarece metoda CreatePage este abstract, deciziile privind tipul efectiv al paginii vor fi luate de clasele derivate din Document. 5.2. Tem pentru acas. Adugai n proiect un nou tip de pagin care s afieze un document Microsoft Word i/sau un document PDF.

165
Florin Leon (2012). Aplicatii de ingineria programarii in C#, Tehnopress, Iasi, ISBN 978-973-702-909-6 http://florinleon.byethost24.com

S-ar putea să vă placă și