1 / 121

Java Advanced Level day 2 Part A

Java Advanced Level day 2 Part A. Athanasios Tsintsifas, LTR, University of Nottingham, email : azt@cs.nott.ac.uk, http: www.cs.nott.ac.uk/~azt. Design Patterns II. Aims. Design patterns part II : Null, Singleton, Observer, Strategy, Template. Quick review of the rest.

terena
Télécharger la présentation

Java Advanced Level day 2 Part A

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Java Advanced Level day 2 Part A Athanasios Tsintsifas, LTR, University of Nottingham, email : azt@cs.nott.ac.uk, http: www.cs.nott.ac.uk/~azt Design Patterns II

  2. Aims • Design patterns part II : • Null, • Singleton, • Observer, • Strategy, • Template. • Quick review of the rest. • Combining Design patterns.

  3. Interface Null Object Client request() • Provides a no-behaviour placeholder object to be used instead of language specific keywords like “null” and “nil”. RealObject NullObject request() request() do nothing

  4. Null Object Where it can be used : • Where an object requires a collaborator object which does nothing. • Where there is a need to ignore the difference between a collaborator that does nothing and a real collaborator. Examples of use : • Applications where null is to be handled as an object that does nothing. (AWT’s layout policy?) • Smalltalk’s MVC (Model-View-Controller). Benefits : • Code doesn’t have to specifically handle a null reference. • Null behaviour is reusable and the null object can be shared.

  5. Null Object Example (1/2) public interface Logger { public void log(String msg); } import java.io.*; class FileLogger implements Logger { File myLogFile = new File("Applog.txt"); public void log(String msg) { try { FileWriter myFW = new FileWriter(myLogFile); myFW.write(msg); myFW.close(); } catch(IOException e) { System.out.println("Exception while writing to log"); } } }

  6. Null Object Example (2/2) class NullLogger implements Logger { public void log(String msg) { //log nothing } } public class Example { static Logger myLogger; public static void main(String argv[]) { myLogger = new FileLogger(); myLogger.log("Application Started"); myLogger = new NullLogger(); myLogger.log("Application about to terminate"); } }

  7. Observer Subject while (e.hasMoreElements()) { Observer o = (Observer) e.nextElement(); o.update(this); } Observer attach() detach() notify() observers update() • A one-to-many dependency between objects so that when an object changes its state. It notifies its dependent objects. ConcreteSubject subject getState() setState() state = newState; notify(); update()

  8. Observer Where it can be used : • Where an abstraction has two aspects depending on each other. • Where a change to one object requires changing others. • Where an object should notify others without knowing what these other objects are. Examples of use : • Java’s JFC. • Smalltalk’s MVC (Model-View-Controller). Benefits : • Subject and observers may vary independently. • Any number of observers can be defined and added. • Different observers provide different views of the change.

  9. Observer Example (1/4) public interface FileSystemObserver { public final static int FILE_ADDED = 1; public final static int FILE_REMOVED = 2; public void notify(int application, int event); } import java.util.*; class FileSystemNotifier { private Vector myObservers = new Vector(); public void addObserver(FileSystemObserver observer) { myObservers.addElement(observer); } public void removeObserver(FileSystemObserver observer) { myObservers.removeElement(observer); } public void notify(int application, int event) { for (Enumeration e = myObservers.elements(); e.hasMoreElements();) { ((FileSystemObserver)e.nextElement()).notify(application, event); } } }

  10. Observer Example (2/4) class FileSystemAdapter implements FileSystemObserver { private FileSystemMonitor myFSMonitor; FileSystemAdapter(FileSystemMonitor fsMonitor) { myFSMonitor = fsMonitor; } public void notify(int application, int event) { switch (event) { case FILE_ADDED: case FILE_REMOVED: myFSMonitor.refresh(application); break; } } }

  11. Observer Example (3/4) import java.util.*; public class FileSystemMonitor { private Vector myApps = new Vector(); public void addApplication(int app) { myApps.addElement(new Integer(app)); } public void removeApplication(int app) { myApps.removeElement(new Integer(app)); } public void refresh(int application) { for (Enumeration e = myApps.elements(); e.hasMoreElements();) { Integer tempApp = (Integer)e.nextElement(); if (tempApp.intValue() == application) { System.out.println("Sending refresh message to application " + application); } } } }

  12. Observer Example (4/4) public class Example { public static void main(String argv[]) { int app1 = 101; int app2 = 203; int app3 = 405; FileSystemMonitor fsmonitor = new FileSystemMonitor(); fsmonitor.addApplication(app1); fsmonitor.addApplication(app2); fsmonitor.addApplication(app3); FileSystemNotifier fsnotifier = new FileSystemNotifier(); FileSystemObserver fsobserver = new FileSystemAdapter(fsmonitor); fsnotifier.addObserver(fsobserver); fsnotifier.notify(app1,FileSystemObserver.FILE_ADDED); fsnotifier.notify(app3,FileSystemObserver.FILE_REMOVED); } }

  13. Singleton Singleton static instance • Ensures that a class has one instance only and provides an access point to it for all other classes. method() method() static instance()

  14. Singleton Where it can be used : • Where there must be only one instance of a specific class. • Where that only one instance should be extensible by subclassing. Examples of use : • Monitoring the usage of a class and its objects. • Ensure a single instance - Security Manager. • All kind of registries/managers. Benefits • Security - Robustness - Reduced name space pollution.

  15. Singleton Example (1/2) public class ObjectMonitor { private static ObjectMonitor instance = new ObjectMonitor(); private int acceptedRQs = 0; private int deniedRQs = 0; private boolean inUse = false; private ObjectMonitor() {} public static ObjectMonitor getInstance() { return instance; } public int numOfAcceptedRequests() { return acceptedRQs; } public int numOfDeniedRequests() { return deniedRQs; }

  16. Singleton Example (2/2) public boolean requestLock() { if (inUse == false) { acceptedRQs++; inUse = true; return true; } else { deniedRQs++; return false; } } public void releaseLock() { inUse = false; } }

  17. Strategy Strategy StrategyContext algorithm() strategy() algorithm() • Defines a family of algorithms (as objects) and makes them interchangeable so that clients can vary their execution. ConcreteStrategyA ConcreteStrategyB

  18. Strategy Where it can be used : • Where an object should be configurable with one of several algorithms. Examples of use : • Layout Policy for AWT/JFC containers. Benefits • Greater flexibility and reuse; easy to add new algorithms/behaviours. • Dynamic switching of algorithms. • Strategies encapsulate private data of algorithms.

  19. Strategy Example (1/4) public abstract class Compilation { abstract public String getCompilationCommand(String program); }

  20. Strategy Example (2/4) public class JavaCompilation extends Compilation { public String getCompilationCommand(String program) { String cmd; String prop; prop = System.getProperty("os.name"); String NTjavaCompiler = "c:\\jdk1.2\\bin\\javac.exe"; String UNIXjavaCompiler = "/usr/bin/jdk1.2/bin/javac"; if (prop.equals("Windows NT")) { cmd = new String(NTjavaCompiler + " " + program); } else { //Presumes UNIX cmd = new String(UNIXjavaCompiler + " " + program); } return cmd; } }

  21. Strategy Example (3/4) public class CppCompilation extends Compilation { public String getCompilationCommand(String program) { String cmd; String prop; prop = System.getProperty("os.name"); String NTcppCompiler = "c:\\gnu\\bin\\g++.exe"; String UNIXcppCompiler = "/usr/bin/gnu/gcc"; if (prop.equals("Windows NT")) { cmd = new String(NTcppCompiler + " " + program); } else { //Presumes UNIX cmd = new String(UNIXcppCompiler + " -o " + program); } return cmd; } }

  22. Strategy Example (4/4) public class Example { public static void main(String argv[]) { String program = "Example.java"; String compilationCommand = getCommand(program); System.out.println(compilationCommand); program = "Example.cpp"; compilationCommand = getCommand(program); System.out.println(compilationCommand); } public static String getCommand(String program) { Compilation comp; if (program.endsWith("java")) { comp = new JavaCompilation(); return comp.getCompilationCommand(program); } if (program.endsWith("cpp")) { comp = new CppCompilation(); return comp.getCompilationCommand(program); } return null; } }

  23. Template Method AbstractClass method1() method2() method3() primitive1() primitive2() … Primitive1(); … Primitive2(); • Defines a skeleton of an algorithm in an operation while deferring some steps to subclasses. DerivedClass() primitive1() primitive2()

  24. Template Method Where it can be used : • Where a portion of an algorithm to be used in a class is dependant on the type of an object of its subclasses. • In systems that go through a re-factoring stage. Examples of use • Any algorithm that depends on the type of object it is applied to. Benefits • Greater flexibility and reuse. • Easy to modify an algorithm to take into account other types of objects (of the same hierarchy).

  25. Template Method Example (1/7) import java.io.*; public abstract class Compilation { String[] myFiles; public boolean setupEnvironment(String[] files) { myFiles = files; // check that files exist for (int i=0; i<myFiles.length; i++) { File testFile = new File(myFiles[i]); if (!testFile.exists()) { return false; } } return true; }

  26. Template Method Example (2/7) abstract public String getCompilationCommand(String program); public void compile() { for (int i=0; i< myFiles.length; i++) { String compilationCommand = getCommand(myFiles[i]); System.out.println(compilationCommand); // now compile } } private String getCommand(String program) { return getCompilationCommand(program); } }

  27. Template Method Example (3/7) public class JavaCompilation extends Compilation { private String program; public JavaCompilation(String prg) { program = prg; } public JavaCompilation() { } public String getCompilationCommand(String prg) { program = prg; return getCompilationCommand(); }

  28. Template Method Example (4/7) public String getCompilationCommand() { String cmd; String prop; prop = System.getProperty("os.name"); String NTjavaCompiler = "c:\\jdk1.2\\bin\\javac.exe"; String UNIXjavaCompiler = "/usr/bin/jdk1.2/bin/javac"; if (prop.equals("Windows NT")) { cmd = new String(NTjavaCompiler + " " + program); } else { //Presumes UNIX cmd = new String(UNIXjavaCompiler + " " + program); } return cmd; } }

  29. Template Method Example (5/7) public class CppCompilation extends Compilation { private String program; public CppCompilation(String prg) { program = prg; } public CppCompilation() { } public String getCompilationCommand(String prg) { program = prg; return getCompilationCommand(); }

  30. Template Method Example (6/7) public String getCompilationCommand() { String cmd; String prop; prop = System.getProperty("os.name"); String NTcppCompiler = "c:\\gnu\\bin\\g++.exe"; String UNIXcppCompiler = "/usr/bin/gnu/gcc"; if (prop.equals("Windows NT")) { cmd = new String(NTcppCompiler + " " + program); } else { //Presumes UNIX cmd = new String(UNIXcppCompiler + " -o " + program); } return cmd; } }

  31. Template Method Example (7/7) public class Example { public static void main(String argv[]) { String[] javaApp =new String[2]; javaApp[0] = "TestExample.java"; javaApp[1] = "TestMain.java"; Compilation javacomp = new JavaCompilation(); if (javacomp.setupEnvironment(javaApp)) { javacomp.compile(); } String[] cppApp = new String[3]; cppApp[0] = "TestMain.cpp"; cppApp[1] = "TestIO.cpp"; cppApp[2] = "TestLog.cpp"; Compilation cppcomp = new CppCompilation(); if (cppcomp.setupEnvironment(cppApp)) { cppcomp.compile(); } } }

  32. The Rest of the Design Patterns • Flyweight, allows large number of small objects to be shared. • Chain of Responsibility, gives a chance to many handlers to handle a request. • Visitor, allows to append operations to an object structure without changing its class structure. • Mediator, encapsulates the way a set of objects interact. • Façade, provides a single interface to a set of classes or to a subsystem. • Builder, separates the building of a complex object from its representation. • Bridge, separates an abstraction from its implementation. • Prototype, provides a cheaper alternative to object creation. • Proxy, plays the role of a placeholder for other objects. • Interpreter, uses inheritance and composition to build the syntax tree. • Iterator, encapsulates the traversal of a structure. • State, encapsulates an object’s state in a separate object. • Memento, captures an object’s state without violating encapsulation. • Generation Gap, provides a clean way to customise generated source code.

  33. Combining Design Patterns Proxy Decorator Observer Mediator Memento Command Chain Adapter Iterator Composite Flyweight Visitor Builder Prototype Interpreter Strategy Factory Template Abstract Factory State Bridge Singleton Facade

  34. Summary • Design Patterns part II : • Null, • Singleton, • Observer, • Strategy, • Template. • Quick review of the rest 13 design patterns. • Combining design patterns.

  35. Figure Line Circle Rectangle Quiz java.lang java.util Object Vector figures app Printable Drawable TestProgram • Can you detect anywhere a need for any of the following patterns : Null, Singleton, Observer, Strategy,Template ?

  36. Exercises • Choose one of the design patterns presented in this section and implement it in the context of yesterday’s figure drawing example. What would you have used instead, to provide the same functionality? Can you detect the advantages and disadvantages of using the pattern in that context? • Design and implement a simple thermometer class that uses the Observer pattern to register its views. On change, the thermometer object should notify its dependent views to update accordingly. You can use the command pattern to change the temperature value of the thermometer. 15.3 15.3 observers observable Thermometer fTemperature 15.3 15.3C notifies on change

  37. Java, Advanced Level day 2 Part B Athanasios Tsintsifas, LTR, University of Nottingham, email : azt@cs.nott.ac.uk, http: www.cs.nott.ac.uk/~azt OO Frameworks and Design patterns in Java’s APIs

  38. Aims • Introduction to OO Frameworks. • Design patterns in Java’s API’s : • 1.java.awt : • Composite, • Strategy, • Abstract Factory, • Template, • 2.java.io : • Decorator, • 3.java.util : • Iterator, Observer.

  39. OO Frameworks • “A Framework is a reusable, semi-complete application that can be specialised to produce custom applications. [Johnson - Foote 1988] • In contrast with Class Libraries, frameworks contain design decisions for : • particular business units, • application domains. • Frameworks invert the control of the application and promote the Hollywood principle : “Don’t call us, we’ll call you!” • Famous Frameworks : • MacApp, InterViews, Unidraw, ET++, MFC, DCOM, RMI, CORBA.

  40. OO Frameworks • Frameworks are represented by a set of interfaces, abstract classes and collaboration specifications of their instances. • Applications can get built on a framework by : • Overriding, • Parameterising, • Configuring, • Modifying. • Benefits : • Modularity, Reusability, Extensibility, Control Inversion.

  41. White Box Override to Customise, Internal structure exposed, Easier to design, Harder to learn, More implementation. Black Box Configure to Customise, Interfaces exposed, Complex to design, Easier to learn, Less implementation. OO Framework Types Flexibility - Extendibility Encapsulation

  42. Learning to use a Framework • Frameworks are complex. • Can’t learn one class at a time. • The important classes are the abstract classes and interfaces. • Learning by example and using a Cookbook seem to work best.

  43. Creating Frameworks • Highly iterative process that requires a deep understanding on the application domain : • domain analysis needs to mature, • anticipating change needs experience, • it’s often not feasible to use a large number of application examples to test the framework’s exploitability.

  44. Using Patterns to Document Frameworks • Patterns are used in a Framework : • to document design decisions, • to aid the communication of design, • to reuse proven solutions.

  45. Application Instantiation F r a m e w o r k Application 1 • Applications need to subclass or use Framework classes to suit their needs. • Polymorphism is heavily used. • Frequently used patterns that allow framework based application customisation include : • Template, Factory, State, Strategy, Command, Decorator, Adapter, Visitor, Mediator, Proxy, Iterator. Application 2 Application 3

  46. AWT Architecture • (1) Design for containment, • (2) Design for layout management, • (3) Design for platform independence, • (4) Design for embedding Applets in html.

  47. (1) Design for Containment • Arbitrary deep containment hierarchy. Component paint() deliverEvent() getParent() Container add() remove() getComponent()

  48. (2) Design for Layout Management • Positioning components by specifying absolute coordinates is problematic. • We need to empower Containers with algorithms that layout their components relatively. Container borderLayout() Naive Solution : flowLayout() gridLayout()

  49. Design for Layout Management • Another Naive solution : Component Container layout() FlowContainer GridContainer BorderContainer layout() layout() layout()

  50. Design for Layout Management • Java’s Solution (Strategy Design Pattern) : Component LayoutManager addLayoutComponent() removeLayoutComponent() layoutContainer() minimumLayoutSize() preferredLayoutSize() Container layout() - When we need absolute Coordinates we set the layout to null. FlowLayout BorderLayout GridLayout Does LayoutManager reference its Container?

More Related