Upload
elena-florina
View
40
Download
0
Embed Size (px)
Citation preview
CURS 5
Bridge , Template Method, Strategy
design patterns Tratarea exceptiilor
Clasificarea sabloanelor (GoF)
Scop- Pentru ce se foloseste? Creational Patterns Structural Patterns Behavioral Patterns
Mod de realizare Class Patterns
Focus pe relatii intre clase Presupune reutilizare prin mostenire
Object Patterns Focus pe relatii intre obiecte Presupune reutilizare prin compozitie
Sursa: http://www.codeproject.com/Articles/12183/Design-Your-Soccer-Engine-and-Learn-How-To-Apply-D
Clasificare sabloane Riehle and Zullighoven: Understanding and Using
Patterns in Software Development Conceptual Pattern
Descriere bazata pe termeni si concepte din domeniul aplicatiei
Design Pattern
descriere bazata pe constructii specifice proiectarii software: obiecte, clase, mostenire, agregare
Programming Pattern (Programming Idiom)
descriere bazata pe constructii ale unui limbaj de programare.
References
Design Patterns: Elements of Reusable Object-Oriented Software, Gamma, Helm, Johnson and Vlissides, Addison-Wesley, 1995 Design Patterns for Object-Oriented Software
Development,Wolfgang Pree, Addison-Wesley/ACM Press, 1995 Patterns of Software: Tales From The Software Community,Richard
P. Gabriel, Oxford University Press, 1996 Pattern Oriented Software Architecture : A System of Patterns,Frank
Buschmann (Editor), Wiley, 1996 Analysis Patterns: Reusable Object Models, Martin Fowler,Addison-
Wesley, 1997 AntiPatterns, Brown, Malveau, McCormick and Mowbray,Wiley,
1998 Design Patterns Explained, Alan Shalloway and James R. Trott,
Addison-Wesley, 2001
Core J2EE Patterns: Best Practices and Design Strategies, Alur,Crupi and Malks, 2001
Design Patterns Java Workbook, Steven John Metsker, Addison-Wesley, 2002
Applied Java Patterns, Stephen Stelting and Olav Maassen,Prentice Hall, 2002
EJB Design Patterns: Advanced Patterns, Processes, and Idioms, Floyd Marinescu, Wiley, 2002
Patterns Of Enterprise Application Archictecture, Martin Fowler, Addison-Wesley, 2002
C# Design Patterns - A Tutorial, James W. Cooper, Addison-Wesley, 2002
Design Patterns In C#, Steven John Metsker, Addison-Wesley,2004
Head First Design Patterns, Freeman and Freeman, O'Reilly,2004
Core Security Patterns - Best Practices and Strategies for J2EE(TM), Web Services, and Identity Management, Christopher Steel, Ramesh Nagappan and Ray Lai, Prentice Hall, 2005
Refactoring To Patterns, Joshua Kerievsky, Addison-Wesley,2005
Bridge
Decupleaza o abstractie de posibilele ei implementari astfel incat sa poata varia independent.
Context
Cand o anumita abstractiune poate avea mai multe variante de implementare, de obicei se utilizeaza mostenirea: o clasa abstracta defineste interfata abstractiunii, iar subclasele concrete o implementeaza in diverse moduri.
Aceasta abordare nu este intotdeauna suficient de flexibila.
Prin mostenire o implementare este legata permanent de abstractiune si acest lucru face foarte dificila modificarea independenta a abstractiunii si a implementarii.
Structura
Abstraction: defineste interfata abstractiunii; detine o referinta spre un obiect de tip Implementor.
RefinedAbstraction: extinde interfata Abstraction Implementor: defineste interfata pentru clasele ce contin implementari. Aceasta interfata nu trebuie neaparat sa corespunda exact cu interfata Abstraction. De fapt, cele 2 pot fi total diferite. De obicei Implementor ofera doar operatii primitive, iar Abstraction defineste operatii de nivel mai inalt, bazandu-se pe acele primitive; ConcreteImplem: implementeaza interfata Implementor.
Aplicabilitate:
se doreste evitarea legarii unei abstractiuni de implementarea sa. Acest lucru se intampla de exemplu cand implementarea trebuie aleasa sau
modificata pe durata executiei;
atat abstractiunea cat si implementarea trebuie sa poata fi extinse prin adaugarea de subclase. In aces caz sablonul bridge permite combinarea dupa dorinta a diferitelor
abstractiuni si implementari.
schimbarile aduse implementarii nu trebuie sa afecteze clientii, adica nu trebuie sa necesite recompilarea codului acestora;
se doreste ascunderea completa a implementarii fata de clienti; se constata ca extensiile care trebuie aduse unei abstractiuni duc la o
crestere prea mare a numarului de subclase. In acest caz se indica "spargerea" obiectelor in 2 parti, creindu-se 2 ierarhii
separate. Asemenea ierarhii se mai numesc "generalizari incuibate";
se doreste partajarea unei implementari intre mai multe obiecte si acest fapt trebuie ascuns fata de client.
Exemplu
12
Template Method
Defineste schema unui algoritm lasand anumiti pasi a fi rezolkvati in subclase. Template Method leasa subclasele sa redifineasca anumiti pasi al unui algoritm fara sa schimbe structura algoritmului.
Structura:
13
Aplicabilitate
Pentru a implementa partile invariante ale unui algoritm doar odata si a alasa subclasele sa implementeze comportamenul care difera.
Atunci cand comportamenul comun mai multor clase trebuie sa fie evidentiat si localizat intr-o clasa comuna pentru a evita duplicarea de cod.
Pentru a controla extinderea subclasarii.
14
Template Method (exemplu)
abstract class AppFramework { public ApplicationFramework() { templateMethod(); } abstract void customize1(); abstract void customize2(); // "private" means automatically "final": private void templateMethod() { for(int i = 0; i < 5; i++) { customize1(); customize2(); } } }
class TemplateMethodApp { MyApp app = new MyApp(); public void test() { // The MyApp constr. does all the work. // This just makes sure it will complete // without throwing an exception. } public static void main(String args[]) { new
TemplateMethodApp().test(); } }
// Create a new "application": class MyApp extends AppFramework { void customize1() { System.out.print("Hello "); } void customize2() { System.out.println("World!"); } }
15
Template Method Exemplu (1)
import java.util.*;
abstract class OperAllCollEl {
public void applyOper(Collection c) {
Iterator i = c.iterator();
while ( i.hasNext()){
Object e = i.next();
operation(e);
}
}
abstract public void operation(Object e);
}
class Real{
private double r;
Real(double r){ this.r =r;}
void pow(int n){
for(int i=0;i
16
Template Method Example (2)
class Print extends OperAllCollEl{
public void operation(Object e){
System.out.print(e+";");
}
}
class OperOnStrings extends OperAllCollEl{
public void operation(Object e){
StringBuffer s = (StringBuffer) e;
s.toUpperCase();
}
}
class OperOnReals extends OperAllCollEl{
public void operation(Object e){
Real r = (Real) e ;
r.pow(2);
}
}
17
Template Method Example (3)
public class Application{
public static void main(String args[]){
Collection c1 = new HashSet();
c1.add(new StringBuffer("unu"));
c1.add(new StringBuffer("doi"));
OperAllCollEl op = new OperOnStrings();
op.applyOper(c1);
System.out.println();
OperAllCollEl p = new Print();
p.applyOper(c1);
Collection c2 = new HashSet();
c2.add(new Real(1.0));
c2.add(new Real(2.0));
op = new OperOnReals();
op.applyOper(c2);
p.applyOper(c2);
}
}//:~
19
Aplicatii ale Template Method in JFC:
AbstractCollection : A Collection that is neither a Set nor a List, such as a bag. At a minimum, you must
provide the iterator and the size method.
AbstractSet : A Set. Use is identical to AbstractCollection.
AbstractList : A List backed by a random-access data store (such as an array). At a minimum, you must provide the positional access methods (get(int) and, optionally, set(int), remove(int), and add(int)) and the size method. The abstract class takes care of listIterator (and iterator).
(public abstract class AbstractList extends AbstractCollection implements List )
AbstractSequentialList : A List backed by a sequential-access data store (such as a linked list). At a minimum, you must provide the listIterator and size methods. The abstract class takes care of the positional access methods. (This is the opposite of AbstractList.)
AbstractMap : A Map. At a minimum you must provide the entrySet view. This is typically implemented with the AbstractSet class. If the Map is modifiable, you must also provide the put method.
20
Strategy
Strategy este un obiect care reprezinta un algoritm.
Este folositor atunci cand :
se doreste inlocuirea unui algoritm static sau chiar dinamic;
exista mai multe variante ale algoritmului,
sau atunci cand un algoritm are structuri de date complicate pe care doreste sa le incorporeze.
21
Strategy Structura
22
Strategy - Aplicabilitate
Cand mai multe clase difera doar in comportament. Strategy furnizeaza
un mod de a configura o clasa cu una sau mai multe functionalitati.
Cand este nevoie de mai multe variante ale unui algoritm. Strategy este folosit atunci cand aceste variante sunt implementate ca o ierarhie de clase de algoritmi.
Cand un algoritm foloseste date pe care clientii nu ar trebui sa le cunoasca. Strategy se foloseste pentru a evita expunerea structurilor de date complexe specifice unui algoritm.
Cand o clasa defineste mai multe comportamente si acestea apar in multiple instructiuni conditionale. In loc de a folosi instructiuni conditionale complexe, ramurile conditionale corespunzatoare se muta in clase Strategy.
Exemplu: sursa- http://a3ab771892fd198a96736e50.javacodegeeks.netdna-cdn.com/wp-
content/uploads/2013/08/Strategy-Pattern.png
24
Tratarea exceptiilor
25
Exceptii
Exceptie = un obiect care ncapsuleaza informatie despre o situatie anormala.
Scop: pentru a semnala contextul n care apare situatia deosebita
exceptie != bug
Exceptiile nu sunt gandite pentru a preveni bugurile ci situatiile de executie anormale
exemple:
incercarea de a deschide un fisier pentru care s-a introdus un nume eronat.
impartire cu 0 pt numere intregi
conditii speciale:
language semantic violation
program-defined errors
26
Exception Handling Tratarea exceptiilor (Java)
Daca JVM sau mediul de executie detecteaza o cond. speciala, se arunca o exceptie implicit !
Un program poate arunca o exceptie explicit prin instructiunea throw.
Clauza catch = exception handler
27 27
try statement
try {
out.write(b);
}
catch (IOException e) {
System.out.println("Output Error");
}
finally {
out.close();
}
28 28
Exception Hierarchy
class java.lang.Throwable
class java.lang.Error
. . . class java.lang.VirtualMachineError
class java.lang.InternalError
class java.lang.OutOfMemoryError
class java.lang.StackOverflowError
class java.lang.UnknownError
class java.lang.Exception
29
Throwable class
Method Summary
Throwable fillInStackTrace() Fills in the execution stack trace.
Throwable getCause() Returns the cause of this throwable or null if the cause is nonexistent or unknown.
String getLocalizedMessage() Creates a localized description of this throwable.
String getMessage() Returns the detail message string of this throwable.
StackTraceElement[] getStackTrace() Provides programmatic access to the stack trace information printed by printStackTrace().
Throwable initCause(Throwable cause) Initializes the cause of this throwable to the specified value.
void printStackTrace() Prints this throwable and its backtrace to the standard error stream.
void printStackTrace(PrintStream s) Prints this throwable and its backtrace to the specified print stream.
void printStackTrace(PrintWriter s) Prints this throwable and its backtrace to the specified print writer.
void setStackTrace(StackTraceElement[] stackTrace) Sets the stack trace elements that will be returned by getStackTrace() and printed by printStackTrace() and related methods.
String toString() Returns a short description of this throwable.
30
Clasa Exception
Constructor Summary Exception()
Constructs a new exception with null as its detail message. Exception(String message)
Constructs a new exception with the specified detail message. Exception(String message, Throwable cause)
Constructs a new exception with the specified detail message and cause.
Exception(Throwable cause) Constructs a new exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause).
31
Cauza unei exceptii
chained exception facility
Cauza unei exceptii:
O alta excepotie
O situatie speciala in program.
"chain" of exceptions
32 32
class java.lang.Exception . . .
class java.lang.RuntimeException
class java.lang.ArithmeticException
class java.lang.ArrayStoreException
class java.lang.ClassCastException
class java.lang.IllegalArgumentException
class java.lang.IllegalThreadStateException
class java.lang.NumberFormatException
class java.lang.IllegalMonitorStateException
class java.lang.IllegalStateException
class java.lang.IndexOutOfBoundsException
class java.lang.ArrayIndexOutOfBoundsException
class java.lang.StringIndexOutOfBoundsException
class java.lang.NegativeArraySizeException
class java.lang.NullPointerException
class java.lang.SecurityException
class java.lang.UnsupportedOperationException
33 33
class java.lang.Exception class java.io.IOException
class java.io.CharConversionException
class java.io.EOFException
class java.io.FileNotFoundException
class java.io.InterruptedIOException
class java.io.ObjectStreamException
class java.io.SyncFailedException
class java.io.UnsupportedEncodingException
class java.io.UTFDataFormatException
34
Declararea exceptiilor
If a method is expected to throw any exceptions, the method declaration must declare that fact in a throws clause.
There are certain types of exceptions that do not have to be listed in a throws clause (Error, RunTimeException, or a subclass of one of those classes).
checked,
unchecked (RuntimeExceptions)
35
throws and overiding The overriding method must NOT throw checked exceptions that are new or broader
than those declared by the overridden method.
class A { public void foo() throws IOException {..} } class B extends A { @Override public void foo() throws SocketException {..} // allowed @Override public void foo() throws SQLException {..} // NOT allowed } //SocketException extends IOException, but SQLException does not.
36 36
import java.io.IOException;
class throwsExample {
char[] a; int position;
...
//explicitly throws an exception
int read() throws IOException {
if (position >= a.length)
throw new IOException();
return a[position++];
}
//implicitly throws an exception
String readUpTo(char terminator)
throws IOException {
StringBuffer s =
new StringBuffer();
while (true) {
int c = read();
// Can throw IOException
if (c == -1 || c == terminator) {
return s.toString(); }
s.append((char)c);
}
return s.toString();
}
//catches an exception internally
int getLength() {
String s;
try {
s = readUpTo(':');
}
catch (IOException e) {
return 0;
}
return s.length();
}
//can throw a RunTimeException
int getAvgLength() {
int count = 0;
int total = 0;
int len;
while (true){
len = getLength();
if (len == 0) break;
count++; total += len;
}
return total/count;
// Can throw ArithmeticException
}
} //:~
37 37
Generare Exceptii
Instructiunea throw este folosita pentru a creea si a arunca o exceptie. obiectul aruncat trebuie sa fie o instanta a unei subclase a clasei Throwable.
Uzual : crearea unei clase specifice problemei de semnalat, derivate din clasa Exception.
Example:
class WrongDayException extends Exception {
public WrongDayException () {}
public WrongDayException(String msg) {
super(msg);
}
}
38 38
public class ThrowExample { void doIt() throws WrongDayException{ int dayOfWeek =(new
java.util.Date()).getDay(); if (dayOfWeek != 2 && dayOfWeek != 4) throw new WrongDayException("Tue. or
Thur."); // The rest of doIt's logic goes here System.out.println("Did it"); } public static void main (String [] argv) { try { (new ThrowExample()).doIt(); } catch (WrongDayException e) { System.out.println("Sorry, can do it
only on " + e.getMessage()); } } }
39 39
Printing Stack Traces
java.lang.ArithmeticException: / by zero
at t.cap(t.java:16) at t.doit(t.java:8) at t.main(t.java:3)
Afisarea urmei de apel stack trace prin apelul printStackTrace()
int cap (int x) {return 100/x;} try { cap(0); } catch(ArithmeticException e) { e.printStackTrace(); }
sau direct fara aruncarea unei exceptii: new Throwable().printStackTrace();
40 40
Rethrowing Exceptions Rearuncarea exceptiilor
Dupa ce o exceptie este prinsa aceasta poate fi rearuncata (dupa eventuala ei modificare/ adaugare de informatii).
Ex1: simpla rearuncare pastreaza sursa originala:: try { cap(0); } catch(ArithmeticException e) { throw e; }
Ex2: se poate rearanja stack trace: try { cap(0); } catch(ArithmeticException e) { throw
(ArithmeticException)e.fillInStackTrace(); }
Tratarea exceptiilor C#
42
In C# se pot arunca ca exceptii obiecte de tip System.Exception sau derivate ale acestuia.
Metode si proprietati relevante ale clasei Exception:
public Exception(), public Exception(string), public Exception(string, Exception) - constructori;
public virtual string HelpLink {get; set;} obtine sau seteaza o legatura catre un fisier help asociat acestei exceptii; poate fi de asemenea o adresa Web (URL)
public Exception InnerException {get;} returneza exceptia care este ncorporata n exceptia curenta
public virtual string Message {get;} obtine un mesaj care descrie exceptia curenta
public virtual string Source {get; set;} obtine sau seteaza numele aplicatiei sau al obiectului care a cauzat eroarea
public virtual string StackTrace {get;} otine o reprezetare string a apelurilor de metode care au dus la aparitia acestei exceptii
public MethodBase TargetSite {get;} obtine metoda care a aruncat exceptia curenta
43
Crearea propriilor exceptii
Se recomanda ca acestea sa fie derivate din System.ApplicationException, care este derivata direct din System.Exception.
Se indica aceasta derivare deoarece astfel se face distinctie ntre exceptiile aplicatie si cele sistem (cele aruncate de catre CLR).
44
Exemplu using System; public class MyCustomException :
System.ApplicationException {
public MyCustomException(string message): base(message)
{} } public class Test { public static void Main( ) {
Test t = new Test( ); t.TestFunc( );
} public void TestFunc( ) { try { double a = 0; double b = 5; Console.WriteLine ({0} / {1} = {2}, a, b, DoDivide(a,b)); Console.WriteLine (This line may or may not print); } catch (System.DivideByZeroException e) { Console.WriteLine(DivideByZeroException! Msg: {0}, e.Message); Console.WriteLine(HelpLink: {0}, e.HelpLink); }
catch (MyCustomException e) {
Console.WriteLine(\nMyCustomException! Msg: {0},
e.Message); Console.WriteLine(\nHelpLink: {0}\n, e.HelpLink);
} catch { Console.WriteLine(Unknown exception caught); }} public double DoDivide(double a, double b) { if (b == 0) { DivideByZeroException e = new
DivideByZeroException( ); e.HelpLink= http://www.greselifatale.com; throw e;
} if (a == 0) { MyCustomException e = new MyCustomException(
Cant have zero divisor); e.HelpLink =
http://www.greselifatale.com/NoZeroDivisor.htm;
throw e; } return a/b; }
45
Rearuncarea exceptiilor - exemplu
public class MyCustomException : System.ApplicationException
{ public MyCustomException(string message,Exception
inner): base(message,inner) {}} public class Test { public static void Main( ) {
Test t = new Test( ); t.TestFunc( );
} public void TestFunc( ) {
try{ DangerousFunc1( ); } catch (MyCustomException e) { Console.WriteLine(\n{0}, e.Message); Console.WriteLine(Retrieving exception history...); Exception inner = e.InnerException; while (inner != null) { Console.WriteLine({0},inner.Message); inner = inner.InnerException; }} }
public void DangerousFunc1( ) { try { DangerousFunc2( );}
catch(System.Exception e) {
MyCustomException ex = new MyCustomException(E3 -Custom
Exception Situation!,e); throw ex;
}} public void DangerousFunc2( ) { try { DangerousFunc3( ); } catch (System.DivideByZeroException e) { Exception ex = new Exception(
E2 - Func2 caught divide by zero,e); throw ex; } } public void DangerousFunc3( ) { try { DangerousFunc4( ); } catch (System.ArithmeticException) { throw; } catch (System.Exception) { Console.WriteLine(Exception handled here.); }} public void DangerousFunc4( ) { throw new DivideByZeroException("E1 - DivideByZero
Exception"); }}
46
Checked exceptions
In Java, o metoda trebuie sa declare toate exceptiile pe care le poate arunca.
Efect: compilatorul poate sa verifice daca o anumita exceptie este tratata sau nu in interiorul metodei.
In Java exceptiile sunt parte din signatura metodei.
In C# nu exista aceasta cerinta.
Comparatie
In Java, programatorii trebuie sa declare ca o metoda poate arunca o exceptie si sa o declare explicit astfel incat un apelant sa stie ca se poate se poate astepta la primirea ei.
Aceasta cunoastere in avans permite conceperea unui plan de lucru cu fiecare dintre ele, preferabil decat sa se prinda oricare dintre ele cu un catch generic.
In cazul .NET se sugereaza sa se mentina o documentatie cu exceptiile care pot fi aruncate de fiecare metoda.
47
48
Analiza checked exceptions
O problema importanta legata de exceptiile verificate este faptul ca se restringe dezvoltarea claselor derivate la suprascrierea metodei folosind doar lista de exceptii specificata pentru metoda clasei de baza.
In Java:
interface Movie{
void Enjoy() throws PeopleTalkingException;
}
Implementarile metodei Movie.Enjoy( ) pot sa nu arunce nici o exceptie dar daca arunca atunci singurul tip de exceptii verificate este PeopleTalkingException.
Avantaj : orice cod care foloseste interfata Movie si care trateaza exceptii de tip PeopleTalkingExceptionse este garantata sa continue sa functioneze indiferent de cum este aceasta interfata implementata.
Dezavantaj: uneori presupunerea initiala despre ce constituie o exceptie valida este eronata.
49
Problema...
Sa presupunem ca dorim sa implementam o interfata HomeMovie specializata, unde oamenii pot vorbi tot ceea ce doresc , dar atunci suna telefon sa se creeaze o circumstanta de exceptie.
In Java este necesar:
Sa se rescrie specificatia exceptiilor interfetei de baza
sa se deriveze PhoneRingingException din PeopleTalkingException,
Constructors, inheritance and exceptions
public class A{
public A() throws Exceptie1{
}
public A(int i){ }
//...
}
public class B extends A{
public B() throws Exceptie1{ }
public B(int i){
super(i);
}
public B(char c) throws Exceptie1, ExceptieNoua{
}
//...
}
The derived class constructor have to specifies all the exceptions thrown by the base class constructor.
The derived class constructor may
throw new other exceptions.
50
Exceptions in overridden methods
public class AA {
public void f() throws Exceptie1, Exceptie2{ }
public void g(){ }
public void h() throws Exceptie1{ }
}
public class BB extends AA{
public void f() throws Exceptie1{ } //doesnt specify Exceptie2
public void g() throws Exceptie2{ }
public void h() throws Exceptie3{ }
}
public class Exceptie3 extends Exceptie1{...}
An overridden method doesnt have to specify all the exceptions thrown by the same method in the super-class definition.
An overridden may specify a new exception or a specialized form of an exception thrown by the same method in the super-class definition.
51