Sunteți pe pagina 1din 61

Ingineria Programrii

Curs 8
Curs 8
Ovidiu Gheorghie, ogh@infoiasi.ro
Adriana Gheorghie, adrianaa@infoiasi.ro
D
e
s
ig
n
P
a
tte
rn
s
M
o
d
e
le
d
e
p
ro
ie
c
ta
re
IP
8
Bibliografie
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides.
Design Patterns. Elements of Reusable Object-Oriented Software.
Addison-Wesley, 1995
Pe scurt GOF = Gang of Four
n romn:
abloane de proiectare. Elemente de software
reutilizabil orientat pe obiecte
Editura Teora, 2002
IP
8
Design patterns capture solutions that have
developed and evolved over time
GOF
IP
8
Modele de proiectare - clasificare
modele structurale: se preocup de modul n care clasele i
obiectele sunt compuse pentru a forma structuri mai mari
(adapter, bridge, composite, decorator, faade, flyweight,
proxy)
modele comportamentale: se preocup de algoritmi i de
asignarea responsabilitilor ntre obiecte
(chain of responsibility, command, interpreter, iterator,
mediator, memento, observer, state, strategy, template
method, visitor)
modele creaionale: abstractizeaz procesul de instaniere
(abstract factory, builder, factory method, prototype, singleton)
IP
8
n cursul 7
Singleton: garanteaz existena unei singure instane a unei
clase. Se asigur o modalitate de a accesa instana respectiv.
Factory Method: definete o interfa pentru crearea unui
obiect, dar las n sarcina subclaselor alegerea tipului acestuia.
Strategy: definete o familie de algoritmi
Decorator: asignare de responsabiliti n mod dinamic
Composite: obiecte i grupuri tratate uniform
Iterator: ofer o modalitate de a accesa obiecte agregate n
mod secvenial fr a cunoate modul de agregare
Template Method: se definete scheletul unui algoritm
ntr-o metod, lsnd implementarea pailor algoritmului n
seama subclaselor
IP
8
n acest curs
Abstract Factory: ofer o interfa pentru crearea unei familii de
obiecte corelate, fr a specifica explicit clasele acestora.
Builder: separ construirea unui obiect complex de reprezentarea sa,
astfel ca procesul de construire s poat crea diferite reprezentri.
Proxy: ofer un nlocuitor pentru un obiect, prin care se controleaz
accesul la acel obiect
Adapter: convertete interfaa unei clase la interfaa pe care clienii
acesteia o ateapt
Bridge: decupleaz o abstraciune de implementarea sa astfel nct
cele dou s poat varia independent
Mediator: definete un obiect care ncapsuleaz modul de interaciune
al unui set de obiecte; promoveaz cuplarea slab
Observer: definete o dependen de tip 1-la-n ntre obiecte, astfel ca
atunci cnd un obiect se modific, cele care depind de el sunt notificate
i actualizate automat
Chain of Responsibility: evit cuplarea emitorului unei cereri de
receptorul acesteia dnd posibilitatea mai multor obiecte s trateze
cererea
IP
8
Abstract Factory / Fabric abstract
Scop: Ofer o interfa pentru crearea unei
familii de obiecte corelate, fr a specifica
explicit clasele acestora.
Motivaie: look-and-feel (pe tabl)
Aplicabilitate
Sistemul trebuie s fie independent de cum produsele
cu care lucreaz sunt create
Sistemul este configurat s lucreze cu mai multe
familii de produse
O familie de produse sunt proiectate s funcioneze
doar mpreun
IP
8
Abstract Factory (2)
Structura
AbstractFactory
interf ace
+CreateProductA()
+CreateProductB()
ConcreteFactory1
+CreateProductA()
+CreateProductB()
ConcreteFactory2
+CreateProductA()
+CreateProductB()
Client
AbstractProductA AbstractProductB
ProductA1 ProductA2 ProductB1 ProductB2
IP
8
Abstract Factory (java)
abstract class AbstractProductA{
public abstract void operationA1();
public abstract void operationA2();
}
class ProductA1 extends AbstractProductA{
ProductA1(String arg){
System.out.println("Hello "+arg);
}
// Implement the code here
public void operationA1() { };
public void operationA2() { };
}
class ProductA2 extends AbstractProductA{
ProductA2(String arg){
System.out.println("Hello "+arg);
}
// Implement the code here
public void operationA1() { };
public void operationA2() { };
}
IP
8
Abstract Factory (java)
abstract class AbstractProductB{
//public abstract void operationB1();
//public abstract void operationB2();
}
class ProductB1 extends AbstractProductB{
ProductB1(String arg){
System.out.println("Hello "+arg);
}
// Implement the code here
}
class ProductB2 extends AbstractProductB{
ProductB2(String arg){
System.out.println("Hello "+arg);
}
// Implement the code here
}
IP
8
Abstract Factory (java)
abstract class AbstractFactory{
abstract AbstractProductA createProductA();
abstract AbstractProductB createProductB();
}
class ConcreteFactory1 extends AbstractFactory{
AbstractProductA createProductA(){
return new ProductA1("ProductA1");
}
AbstractProductB createProductB(){
return new ProductB1("ProductB1");
}
}
class ConcreteFactory2 extends AbstractFactory{
AbstractProductA createProductA(){
return new ProductA2("ProductA2");
}
AbstractProductB createProductB(){
return new ProductB2("ProductB2");
}
}
IP
8
Abstract Factory (java)
//Factory creator - an indirect way of instantiating the factories
class FactoryMaker{
private static AbstractFactory pf=null;
static AbstractFactory getFactory(String choice){
if(choice.equals("a")){
pf=new ConcreteFactory1();
}else if(choice.equals("b")){
pf=new ConcreteFactory2();
}
return pf;
}
}
// Client
public class Client{
public static void main(String args[]){
AbstractFactory pf=FactoryMaker.getFactory("a");
AbstractProductA product=pf.createProductA();
//more function calls on product
}
}
IP
8
Builder
Scop: Separ construirea unui obiect complex
de reprezentarea sa, astfel ca procesul de
construire s poat crea diferite reprezentri.
Motivaie: (pagina urmtoare)
Aplicabilitate
Algoritmul de creare a unui obiect complex este
independent de prile care compun efectiv obiectul
Sistemul trebuie s permit diferite reprezentri
pentru obiectele care sunt construite.
IP
8
Builder (2)
Motivaie
RTFReader
+Parse()
while (t =get_next_token()) {
switch(t.Type)
case CHAR:
builder->ConvertCharacter(t.asChar); break;
case FONT:
builder->ConvertFontChange(t.asFont); break;
case PARAGRAPH:
builder->ConvertParagraph();
}
DocumentConverter
+ConvertParagraph( :char)
+ConvertFont( :Font)
+ConvertParagraph()
AsciiConverter TexConverter HtmlConverter
AsciiDocument TexDocument HtmlDocument
IP
8
Builder (3)
Structura
Director
+Construct()
Builder
+BuildPart()
ConcreteBuilder
+BuildPart()
+GetResult()
Product
for all objects in structure
builder->BuildPart()
IP
8
Builder (java)
//Abstract Builder
class abstract class TextConverter{
abstract void convertCharacter(char c);
abstract void convertParagraph();
}
// Product
class ASCIIText{
public void append(char c){ //Implement the code here }
}
//Concrete Builder
class ASCIIConverter extends TextConverter{
ASCIIText asciiTextObj;//resulting product
//converts a character to target representation and appends to the resulting
object void convertCharacter(char c){
char asciiChar = new Character(c).charValue();//gets the ascii character
asciiTextObj.append(asciiChar);
}
void convertParagraph(){}
ASCIIText getResult(){
return asciiTextObj;
}
}
IP
8
Builder (java)
//This class abstracts the document object
class Document{
static int value;
char token;
public char getNextToken(){
//Get the next token
return token;
}
}
//Director
class RTFReader{
private static final char EOF='0'; //Delimitor for End of File
final char CHAR='c';
final char PARA='p';
char t;
TextConverter builder;
RTFReader(TextConverter obj){
builder=obj;
}
void parseRTF(Document doc){
while ((t=doc.getNextToken())!= EOF){
switch (t){
case CHAR: builder.convertCharacter(t);
case PARA: builder.convertParagraph();
}
}
}
}
IP
8
Builder (java)
//Client
public class Client{
void createASCIIText(Document doc){
ASCIIConverter asciiBuilder = new ASCIIConverter();
RTFReader rtfReader = new RTFReader(asciiBuilder);
rtfReader.parseRTF(doc);
ASCIIText asciiText = asciiBuilder.getResult();
}
public static void main(String args[]){
Client client=new Client();
Document doc=new Document();
client.createASCIIText(doc);
system.out.println("This is an example of Builder
Pattern");
}
}
IP
8
Proxy / Substitut
Scop
Ofer un surogat sau nlocuitor pentru un obiect, prin care se
controleaz accesul la acel obiect.
Motivaie
Creare/iniializare la cerere a obiectelor
Aplicabilitate
Substitut pentru deprtat, ambasador
Substitut virtual
Substitut protector
Referin deteapt
Indicator detept
ncrcarea unui obiect persistent la prima accesare
Asigurearea exculderii mutuale
IP
8
Proxy (2)
Tipuri de obiecte proxy:
Cache Proxy: salveaz resurse memornd
rezultate temporare
Count Proxy: face i alte operaii nainte/dup
apelarea subiectului real
Protection Proxy: controleaz accesul la obiectul
real
Remote Proxy: reprezentant local al unui obiect
aflat la o alt adres
Virtual Proxy: creeaz obiecte la cerere (cnd
este nevoie de ele)
IP
8
Proxy (3)
Structura
Client
Subject
+Request()
RealSubject
+Request()
Proxy
+Request()
realSubject->Request
IP
8
Cache Proxy Example (java)
abstract class Generator{
public abstract double Get_PI();
public abstract double Get_e();
}
class RealGenerator extends Generator{
public RealGenerator(){}
public double Get_PI(){
return java.lang.Math.PI;
}
public double Get_e(){
return java.lang.Math.E;
}
}
IP
8
Cache Proxy Example (java)
class CacheProxy extends Generator{
RealGenerator realobj=null;
double Store=0;
int LastAccessed=0;
public CacheProxy(){
realobj=new RealGenerator();
}
public double Get_PI(){
if(LastAccessed!=1){
Store=realobj.Get_PI();
LastAccessed=1;
}
return Store;
}
public double Get_e(){
if(LastAccessed!=2){
Store=realobj.Get_e();
LastAccessed=2;
}
return Store;
}
}
IP
8
Cache Proxy Example (java)
public class cache{
public static void main(String args[]){
Generator calc=new CacheProxy();
double d=calc.Get_PI();
d=calc.Get_PI();
d=calc.Get_PI();
d=calc.Get_e();
d=calc.Get_e();
d=calc.Get_PI();
d=calc.Get_e();
}
}
IP
8
Adapter / Adaptor
Scop
convertete interfaa unei clase la interfaa pe care clienii
acesteia o ateapt.
permite inter-operabilitatea claselor care altfel nu ar fi
compatibile
Motivaie
O clas dintr-o bibliotec, proiectat s fie reutilizabil, nu este
reutilizabil din simplul motiv c interfaa acesteia nu se
potrivete cu una specific domeniului n care se dorete
utilizat.
Aplicabilitate
Se dorete utilizarea unei clase cu o interfa incompatibil
Se dorete crearea unei clase reutilizabile ce colaboreaz cu
clase neprevzute
(adaptor de obiecte) Se dorete folosirea a ctorva subclase, dar
adaptarea prin derivare este nepractic.
IP
8
Adapter (2)
Structura
Client
Target
+Request()
Adapter
+Request()
Adaptee
+Specif icRequest()
SpecificRequest()
Client
Target
+Request()
Adapter
+Request()
Adaptee
+Specif icRequest()
adaptee->SpecificRequest()
Adaptor de clasa
Adaptor de obiecte
IP
8
Adapter (java)
//Adaptee Class which is a local class
class CustomerInfo{
private int custId;
private float salary;
public float getSalary(int custId){
/*Write code here to fetch salary from database */
return salary;
}
}
//Target class is a remote class
interface IRemoteCustomerInfo extends java.rmi.Remote{
/* All remote methods throw java.rmi.RemoteException as
part of java RMI requirement. */
public float getSalary(int custId)
throws java.rmi.RemoteException;
}
IP
8
Adapter (java)
// Adapter class that adapts a local class to a remote
implementation
public class RemoteCustomerInfoAdapter extends
java.rmi.server.UnicastRemoteObject
implements IRemoteCustomerInfo{
protected CustomerInfo adaptee;
public RemoteCustomerInfoAdapter(CustomerInfo customerInfo)
throws java.rmi.RemoteException{
this.adaptee=adaptee;
}
public float getSalary(int custId)
throws java.rmi.RemoteException{
return adaptee.getSalary(custId);
}
}
IP
8
Bridge / Punte
Scop
Decuplarea unei abstraciuni de implementarea sa
astfel nct cele dou s poat varia independent
IP
8
Bridge (2)
Motivaie
3DShape
+Draw()
Cube
DirectX OpenGL
Prism Pyramid
CubeDX CubeOGL PrismDX PrismOGL PyramidDX PyramidOGL
IP
8
Bridge (4)
Motivaie: arhitectur mbuntit
3DShape
+Draw()
+DrawLine()
Cube Prism Pyramid
3DImplementation
DXImplementation OGLImplementation
DirectX OpenGL
IP
8
Bridge (3)
Motivaie
Cnd o abtraciune are cteva implementri
posibile, se folosete de obicei motenirea
Folosirea motenirii n aceast situaie duce la cod
greu de modificat i de extins.
Punerea abstraciunilor i a implementrilor n
ierarhii diferite duce la crearea de cod mai uor de
ntreinut
IP
8
Bridge (4)
Structura
Abstraction
+Operation()
RefinedAbstraction
Implementor
+OperationImpl()
ConcreteImplementorA ConcreteImplementorB
Client
IP
8
Bridge (java)
class Implementor{
public void operationImp(){
//Implement code here
}
}
class ConcreteImplementor extends Implementor{
//Override parent method
public void operationImp(){
//Implement the code here
}
}
IP
8
Bridge (java)
//Abstraction class
abstract class Abstraction{
protected Implementor imp;
public void operation()
{
//Default implementation is provided here;
imp = getImplementor();
imp.operationImp();
}
//Implementation is provided by child classes.
public abstract Implementor getImplementor();
}
class RefinedAbstraction extends Abstraction{
// Do the implementation here
public Implementor getImplementor(){
imp=new ConcreteImplementor();
return imp;
}
}
IP
8
Bridge (java)
public class Client{
public static void main(String args[]){
Abstraction abs=new RefinedAbstraction();
Implementor imp=abs.getImplementor();
abs.operation();
}
}
IP
8
Mediator
Scop. Definete un obiect care ncapsuleaz modul
de interaciune al unui set de obiecte. Promoveaz
cuplarea slab.
Motivaie. n aplicaiile reale,
putem ajunge n situaii n care
fiecare obiect este legat cu
fiecare (ceea ce e ru).
IP
8
Mediator (2)
Motivaie (2)
ListBox
Button
EntryField
RadioBox
RadioBox
FontDialogDirector
ListBox
Button
EntryField
RadioBox
RadioBox
IP
8
Mediator (3)
Aplicabilitate
Un set de obiecte interacioneaz ntr-un mod determinat dar
complicat
Reutilizarea unui obiect este dificil din cauza cumunicrii cu
multe alte obiecte.
Comportamentul distribuit prin multe clase s fie refolosit fr
folosirea excesiv a motenirii
Structura
Mediator Colleague
ConcreteColleague1 ConcreteColleague2 ConcreteMediator
IP
8
Mediator (exemplu)
IP
8
Mediator (exemplu)
IP
8
Mediator (exemplu)
IP
8
Mediator (java)
abstract class Colleague {
private Mediator aMediator;
public Colleague(Mediator m) {
aMediator = m;
}
public void changed() {
aMediator.colleagueChanged(this);
}
public Mediator getMediator(){
return(aMediator);
}
public abstract void Display();
}
IP
8
Mediator (java)
class OneColleague extends Colleague {
private String text;
public OneColleague(Mediator m, String t){
super( m );
text = t;
}
public void setText(String text){
text = text;
}
public String getSelection(){
return text;
}
public void Display(){
System.out.println("OneColleague = " + _text);
}
}
class NextColleague extends Colleague {
// similar implementation here
}
IP
8
Mediator (java)
abstract class Mediator {
public abstract void colleagueChanged(Colleague theChangedColleague);
}
class ConcreteMediator extends Mediator {
private OneColleague aOneColleague;
private NextColleague aNextColleague;
public void colleagueChanged( Colleague theChangedColleague ){
String theChangedColleagueSelection =
((OneColleague)theChangedColleague).getSelection();
String aOneCollegueSelection = aOneColleague.getSelection();
if (theChangedColleagueSelection.equals(aOneCollegueSelection)){
aNextColleague.setText( aOneCollegueSelection );
}
}
public void createConcreteMediator(){
aOneColleague = new OneColleague(this, "OneColleague");
aNextColleague = new NextColleague(this, "NextColleague");
}
IP
8
Mediator (java)
public class Client {
public static void main(String args[]){
ConcreteMediator aConcreteMediator = new ConcreteMediator();
aConcreteMediator.createConcreteMediator();
(aConcreteMediator.getOneColleage()).Display();
(aConcreteMediator.getNextColleague()).Display();
OneColleague newColleague =
new OneColleague(aConcreteMediator, "OneColleague");
aConcreteMediator.colleagueChanged((OneColleague)newColleague );
(aConcreteMediator.getOneColleage()).Display();
(aConcreteMediator.getNextColleague()).Display();
}
}
IP
8
Observer / Observator
Scop: definete o dependen de tip 1-la-n
ntre obiecte, astfel ca atunci cnd un obiect
se modific, cele care depind de el sunt
notificate i actualizate automat.
Motivaie
IP
8
Observer (2)
Aplicabilitate
Cnd o abstraciune are dou aspecte.
ncapsularea fiecruia n obiecte diferite permite
modificarea i refolosirea lor independent.
Cnd o schimbare a unui obiect are ca efect
schimbri ale altor obiecte, fr a ti de la nceput
cte obiecte sunt n aceast situaie.
Cnd se dorete decuplarea obiectelor notificate
de obiectul care se schimb.
IP
8
Observer (3)
Structura
Subject
+Attach(o:Observer)
+Detach(o:Observer)
+Notify()
Observer
interface
+Update()
ConcreteSubject
-subjectState
+GetState()
+SetState()
ConcreteObserver
-observerState
+Update()
subject #1
observerState =
subject->GetState()
forall o in observer
o->Update()
return subjectState
IP
8
Observer (4)
IP
8
Observer (5)
IP
8
public abstract class Subject {
public abstract void attach(Observer observer);
public abstract void detach(Observer observer);
public abstract void notify();
}
public class ConcreteSubject extends Subject {
private State state;
Vector observersVector;
public void attach(Observer observer){
observersVector.addElement(observer);
}
public void detach(Observer observer){
observersVector.removeElement(observer);
}
public void notify(){
java.util.Enumeration enumeration = observersVector.elements ();
while (enumeration.hasMoreElements()) {
((Observer)enumeration.nextElement()).update();
}
}
public void setState(State state) {
this.state = state;
notify();
}
public State getState() {
return state;
}
}
IP
8
public interface Observer {
void update();
}
public class ConcreteObserver implements Observer {
ConcreteSubject subject;
public void update(){
// Write your code here
subject.getState();
}
}
IP
8
Chain of Responsibility /
Lan de responsabiliti
Scop:
evit cuplarea emitorului unei cereri de
receptorul acesteia dnd posibilitatea mai multor
obiecte s trateze cererea.
obiectele sunt nlnuite, iar cererea este trimis
de-a lungul lanului din obiect n obiect pn cnd
un obiect o va trata.
IP
8
Chain of Responsibility (2)
Motivaie: help contextual
specific
general
b
u
t
o
a
n
e
SaveDialog
PrintDialog
Application
IP
8
Chain of Responsibility (3)
HelpHandler
+handleHelp()
handler
Application
Widget
handler->handleHelp()
Dialog
Button
+handleHelp()
+showHelp()
if (can handle) {
showHelp();
}else{
handler->handleHelp();
}
IP
8
Chain of Responsibility (4)
Structura
Client
Handler
+handleRequest()
succesor
ConcreteHandler1 ConcreteHandler2
+handleRequest()
IP
8
Chain of Responsibility (5)
Aplicabilitate
Mai multe obiecte pot trata o cerere, iar obiectul
care o va trata nu este cunoscut a priori, el va fi
determinat in mod automat.
Se dorete ca cererea s fie fcut unui grup de
obiecte fr a specifica n mod explicit receptorul
acesteia.
Mulimea obiectelor care pot trata cererea trebuie
specificat n mod dinamic.
IP
8
public abstract class Handler {
private Handler successor = null;
public int request = 0;
public void Handler(Handler s, int r) {
// set successor for this instance
successor = s;
// set the request that this instance is responsible for
request = r;
}
public void Handler() {
this.Handler(null,0);
}
public void SetSuccessor(Handler h) {
successor = h;
}
public String HandleRequest(int request) {
String returnValue = "";
if (successor != null){
returnValue = successor.HandleRequest(request);
}
return returnValue ;
}
}
IP
8
/* This is a Concrete Handler */
public class RequestHandler extends Handler {
String instanceName = "Not set";
public RequestHandler(String name, RequestHandler s, int r){
super.Handler(s, r);
instanceName = name;
}
public RequestHandler(String name){
super();
instanceName = name;
}
public String HandleRequest(int request) {
String returnValue = "";
if (request == this.request) {
returnValue = "Handled by " + this.instanceName;
} else {
returnValue = super.HandleRequest(request);
}
return returnValue;
}
}
IP
8
Chain of Responsibility (6)

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