Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
COSC2767: Object-Oriented Programming Haibin Zhu, Ph. D. Professor of CS, Nipissing University 1 Lecture 11 Design Patterns Class Objects, and Distributed Objects 2 Inspiration, and a Vocabulary Design patterns speed the process of finding a solution, by eliminating the need to reinvent well-known and proven solutions. Just as important, design patterns provide a vocabulary with which to discuss the space of possible design choices. This vocabulary is termed a pattern language. 3 Relationship to Dependency and Visibility Many patterns are involved with the concepts of dependency we introduced in the previous chapter. Determining where strong dependencies are necessary, and how to weaken dependencies whenever possible. 4 Why Use Patterns? They have been proven. They are reusable. Patterns provide a common vocabulary of solutions that can express large solutions succinctly. It is important to remember that patterns do not guarantee success. 5 Patterns provide a ready-made solution that can be adapted to different problems as necessary. They are expressive. Patterns reflect the experience, knowledge and insights of developers who have successfully used these patterns in their own work. A pattern description indicates when the pattern may be applicable, but only experience can provide understanding of when a particular pattern will improve a design. A Simple Example, The Adapter An adaptor is used to connect a client (an object that needs a service) with a server (an object that provides the service). The client requires a certain interface, and while the server provides the necessary functionality, it does not support the interface. The adapter changes the interface, without actually doing the work. 6 An Example Adapter class MyCollection implements Collection { public boolean isEmpty () { return data.count() == 0; } public int size () { return data.count(); } public void addElement (Object newElement) {data.add(newElement); } public boolean containsElement (Object test) { return data.find(test) != null; } public Object findElement (Object test) { return data.find(test); } private DataBox data = new DataBox(); 7 } DataBox is some collection that does not support the Collection interface. Adapters are often needed to connect software from different vendors. //IconAdapterTest.java Describing Patterns Patterns themselves have developed their own vocabulary for description: name. Contributes to the pattern vocabulary synopsis. Short description of the problem the pattern will solve. forces. Requirements, considerations, or necessary conditions solution. The essence of the solution counterforces. Reasons for not using the pattern. related patterns. Possible alternatives in the design. 8 Example Patterns We will briefly examine a number of common patterns: Iterator Software Factory Strategy Singleton Composite Decorator Proxy Facade Observer 9 Iterator 10 Problem: How do you provide a client access to elements in a collection, without exposing the structure of the collection. Solution: Allow clients to manipulate an object that can return the current value and move to the next element in the collection. Example, Enumerators in Java interface Enumerator { public boolean hasMoreElements(); public Object nextElement(); } Enumerator e = ...; while (e.hasMoreElements) { Object val = e.nextElement(); ... } The pattern applies, even if the interface is changed. //IteratorTest.java Software Factory 11 Problem: How do you simplify the manipulation of many different implementations of the same interface (i.e., iterators). Solution: Hide creation within a method, have the method declare a return type that is more general than its actual return type. class SortedList { ... Enumerator elements () { return new SortedListEnumerator(); } ... private class SortedListEnumerator implements Enumerator { ... } } The method is the “factory" in the name. Users don't need to know the exact type the factory returns, only the declared type. The factory could even return different types, depending upon circumstances. SimpleFacotory.cpp Facotory.java //FactoryClient.java 12 Strategy Problem: Allow the client the choice of many alternatives, but each is complex, and you don't want to include code for all. Solution: Make many implementations of the same interface, and allow the client to select one and give it back to you. Example: The layout managers in the AWT. Several different layout managers are implemented, and the designer selects and creates one. Gives the designer flexibility, keeps the code size down. 13 Strategy.java 14 Singleton 15 Problem: You want to ensure that there is never more than one instance of a given class. Solution: Make the constructor private, have a method that returns just one instance, which is held inside the class itself. class SingletonClass { public: static SingletonClass * oneAndOnly () { return theOne; } private: static SingletonClass * theOne; SingletonClass () { ... } }; // static initialization SingletonClass * SingletonClass::theOne = new SingletonClass(); //singleton.cpp, singleton.java Composite Problem: How do you facilitate creation of complex systems from simple parts? Solution: Provide a few simple components, and a system to compose components (simple or otherwise) into new components. Regular expressions are an example, are type systems, or the nesting of panels within panels in the Java AWT API. 16 Decorator (Filter, Wrapper) 17 Problem: Allow functionally to be layered around an abstraction, but still dynamically changeable. Solution: Combine inheritance and composition. By making an object that both subclasses from another class and holds an instance of the class, can add new behavior while referring all other behavior to the original class. Example Input Streams in the Java I/O System // a buffered input stream is-an input stream class BufferedInputStream extends InputStream { public BufferedInputStream (InputStream s) { data = s; } ...// and a buffered input stream has-an input stream private InputStream data; } An instance of BufferedInputStream can wrap around any other type of InputStream, and simply adds a little bit new functionality. Proxy Problem: How to hide unimportant communication details, such as a network, from the client. Solution: A proxy uses the interface that the client expects, but passes messages over the network to the server, gets back the response, and passes it to the client. The client is therefore hidden from the network details. Similar in some ways to adaptor, but here the intermediary and the server can have the same interface. //ProxyTest.java //download ../proxy/, create a project and import ../proxy. Client 18 Intermediary Server Facade Problem: Actual work is performed by two or more objects, but you want to hide this level of complexity from the client. Solution: Create a facade object that receives the messages, but passes commands on to the workers for completion. Also similar to adapter and proxy. Worker1 Client 19 Intermediary Worker2 Worker3 Observer Problem: How do you dynamically (at run time) add and remove connections between objects. Solution: An Observer Manager implements the following protocol: 20 ``I Want to Observe X'' -- the OM will keep track of who is watching who ``Tell Everybody who is Observing that I have Changed'' -the OM can then tell everybody that an object has changed. In this way neither the observer nor the observed object need know the existence of the other. //OberverTest/Driver.java http://sern.ucalgary.ca/courses/SENG/609.04/W98/lamsh/observerLib.html http://sern.ucalgary.ca/courses/SENG/609.04/W98/lamsh/observerEx.html 21 Java Pattern Examples http://www.patterndepot.com/put/8/JavaPatterns.htm Pattern Summary Speed the process of finding a solution Popular patterns 22 Iterator Software Factory Strategy Singleton Composite Decorator Proxy Facade Observer Reflection and Introspection ---Class Objects 24 Class Objects In most languages, introspection begins with an object that represents the class. Typically this object has class Class. C++ typeinfo aClass = typeid(AVariable); CLOS (class-of aVariable) Delphi Pascal aClass := aVariable.ClassType; Java Class aClass = aVariable.getClass(); Smalltalk aClass <- aVariable class 25 Things you can do with a Class Variable One operation that can be performed with a value of type class is to get its class Class aClass = anObject.getClass(); Another operation is to get the list of all subclasses for a class. aSet <- aClass subclasses " Smalltalk " You can also get the name of the class as a string 26 // Java: ClassName.java char * name = typeid(aVariable).name(); // C++: typeid.cpp Getting the Class from a String In some languages, you can take the name of a class (a string) and from this get the class object. Class aClass class.forName("classname"); // p1.java and p2.java The class does not even have to be loaded. The class will automatically be loaded for you. 27 Testing if an Object is an Instance of a Class 28 We have seen already that most languages provide a way to test if an object is an instance of a class if Member(aVariable, Child) then aChild = Child(aVariable) (* Object Pascal *) This is needed for downcasting. However, if you find yourself using this a lot, then you aren't thinking in an object-oriented way, since often such situations can be better written using polymorphism. Methods as Objects The next level of complexity is treating a method as an object. First step is to get a collection of methods from a class Method [ ] methods = aClass.getDeclaredMethods(); // Java: ClassName.java aSet <- aClass selectors. “Smalltalk” 29 Using a Method What can you do with a method object? You can do the usual things of getting its names, argument type signatures, so on. System.out.println(methods[0].getName()); Class c = methods[0].getReturnType(); //ClassName.java 30 Dynamic Execution 31 You can also invoke the method, passing it the receiver and an array of arguments: Class sc = String.class; Class [ ] paramTypes = new Class[1]; paramTypes[0] = sc; try { Method mt = sc.getMethod("concat", paramTypes); Object mtArgs [ ] = { "xyz" }; Object result = mt.invoke("abc", mtArgs); System.out.println("result is " + result); } catch (Exception e) { System.out.println("Exception " + e); }//ClassName.java Here we dynamically look up a method, based both on name and type signature, then create an array of arguments, then execute the method. Class Loading 32 Java has a class named ClassLoader that allows you to define a class from an array of bytes: class SimpleClassLoader extends ClassLoader { public Class getClass (String name) { Class theClass = null; try { File f = new File(name); InputStream is = new FileInputStream(f); int bufsize = (int) f.length(); byte buf [] = new byte[bufsize]; is.read(buf, 0, bufsize); is.close(); theClass = defineClass (null, buf, 0, buf.length); } catch (Exception e) { System.err.println("Error during load " + e); System.exit(1); } return theClass; } } // Loader.java and Sample.java, define argument[0] as Sample.class Once you have a class, you can create instances, or execute methods. Metaclasses -- Strange Loops You can get into some interesting places by asking the right questions. A class is an object. All objects are instances of a class. What is the class of a class? In Java this path circles back on itself very quickly; Class is an instance of itself. In Smalltalk, the path goes on a bit longer before it circles back on itself. 33 11 Class class a class 10 Class class 9 An object depends on a class. Class an object 8 Class 7 Metaclass 6 Metaclass 5 A metaclass 4 A metaclass 3 A class 1 An Object 34 2 A class A class A class A class can be taken as an object. Rational for Metaclasses Remember that by introducing new classes that represent classes, Smalltalk was able to solve the following problem How do you give unique behavior to just one instance of a class? (For example, the behavior to initialize newly created instances of a class). 35 The answer was, you don't. You add a new child class that defines the behavior you want, and put this between the object and the true parent. Relationship to Components Reflection and Introspection have taken on increasing importance as the field moves from object-based computing to component-based computing (COM, Corba, JavaBeans, etc). This is because components must often be dynamically loaded and executed. And reflection is the underlying mechanism that permits this. 36 Multi-threaded OOP 37 Threads 38 A thread is an identifiable flow of control within a process, with its own stack A sequential process without interrupts has a single thread A sequential process with interrupts has a single main thread and other notional short-lived threads Other types of process considered multithreaded Thread execution is also dependent on platform and program priorities and policies The states of a thread 39 New: A new thread begins its life cycle in the new state. It remains in this state until the program starts the thread. It is also referred to as a born thread. Runnable: After a newly born thread is started, the thread becomes runnable. A thread in this state is considered to be executing its task. Waiting: Sometimes a thread transitions to the waiting state while the thread waits for another thread to perform a task. A thread transitions back to the runnable state only when another thread signals the waiting thread to continue executing. Timed waiting: A runnable thread can enter the timed waiting state for a specified interval of time. A thread in this state transitions back to the runnable state when that time interval expires or when the event it is waiting for occurs. Terminated: A runnable thread enters the terminated state when it completes its task or otherwise terminates. 40 The Synchronization of Threads Unsynched.java Threads interference. After the threads are created, they are competing the CPU cycles to run. //ThreadTest->HelloThread.java 41 Distributed Objects 42 An Object Oriented Community Recall that we have been asserting that an object-oriented program is properly thought of as a member of a community if we relax the rules for membership in this community, we move the paradigm in different directions. 43 Relaxing the rules What are some of the ways we can relax the rules? Allowing objects to be written in different languages -- (corba, dcom) Allowing objects on the same machine to form connections dynamically -- (java beans) Allowing objects to reside on different computers - (distributed computing) Allowing objects on different computers to form connections dynamically -- (mobile computing) 44 All of these are conceptually easy, but the devil is in the details. Client-Server Computing The simplest type of interaction is allowing objects to reside on different computers, but with known interfaces. This is termed client/server computing. The book describes a simple client/server system. 45 Making it Easier to Write Client Server Systems Java simplifies the production of client/server systems by providing ready-made library routines for 46 Address -- IP addresses or domain names. Ports -- an address in a computer for creating connections Sockets -- a connection between one computer and an address/port on another computer Streams -- for reading from and writing to a socket. Doesn't mean it can't be done in other languages, but Java makes it a lot easier since they have spent a lot of time giving you simple interfaces for these activities. Major Problems in Distributed Objects Registration -- how do you find out what components exist out there? Interface Query -- how do you find out what interfaces these components use Connection -- how do you make a dynamic connection with a remote object Interaction -- how do you communicate with a remote object 47 The complexity The complexity is a general server who is ready to accept connections from many clients, perhaps many at one time. Allow the components to exist across the network. Allow the creation of components which can then be assembled even when they exist on widely separated computers. 48 Object Serialization Another useful feature is the ability to transfer objects across a network connection and regenerate them on the far side. Called object serialization, sometimes marshalling. http://java.sun.com/developer/technicalArticle s/Programming/serialization/ 49 Get the State of an Remote Object 50 Moving back to a single machine, there are systems that allow a program to dynamically inquire the capabilities of another class, and then add it into a running program. A good example is Java Beans, which is not described in the book. Again, this is built on the reflection facilities described in the previous chapter. The programmer collects a bunch of components, then assembles them into a new application. Often components have a visual interface, and can be assembled using a visual tool, without needing to write (much) programming. Summary Class Objects/Reflections What happens if you consider a class as an object? Java Thread State Concurrency Distributed Objects 52 Registration Interface Query Connection Interaction