Using UML, Patterns, and Java Object-Oriented Software Engineering Art for Chapter 8, Object Design: Reusing Pattern Solutions System Figure 8-1, Object design closes the gap between application objects identified during requirements and off-the-shelf components selected during Problem system design. Application objects Requirements gap Solution objects Custom objects Object design gap Off-the-shelf components System design gap Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java Machine 2 Figure 8-2, Activities of object design (continued on next slide). Select Subsystem Specification Identifying missing attributes & operations Reuse Identifying components Specifying visibility Adjusting components Specifying types & signatures Identifying patterns Specifying constraints Specifying exceptions Bernd Bruegge & Allen Dutoit Adjusting patterns Object-Oriented Software Engineering: Conquering Complex and Changing Systems 3 Figure 8-2, Continued. Check Use Cases Restructuring Optimization Revisiting inheritance Optimizing access paths Collapsing classes Caching complex computations Realizing associations Delaying complex computations Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 4 Figure 8-3, An example of implementation inheritance (continued on next slide). Object design model before transformation Object design model after transformation Hashtable Hashtable put(key,element) get(key):Object containsKey(key):boolean containsValue(element):boolean put(key,element) get(key):Object containsKey(key):boolean containsValue(element):boolean table 1 1 MySet MySet put(element) containsValue(element):boolean put(element) containsValue(element):boolean Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 5 Figure 8-3, continued. /* Implementation of MySet using inheritance */ class MySet extends Hashtable { /* Constructor omitted */ MySet() { } void put(Object element) { if (!containsKey(element)){ put(element, this); } } boolean containsValue(Object element){ return containsKey(element); } /* Other methods omitted */ } Bernd Bruegge & Allen Dutoit /* Implementation of MySet using delegation */ class MySet { private Hashtable table; MySet() { table = Hashtable(); } void put(Object element) { if (!containsValue(element)){ table.put(element,this); } } boolean containsValue(Object element) { return (table.containsKey(element)); } /* Other methods omitted */ } Object-Oriented Software Engineering: Conquering Complex and Changing Systems 6 Figure 8-4, Inheritance meta-model. Inheritance Inheritance detected during specialization Bernd Bruegge & Allen Dutoit Taxonomy Inheritance for Reuse Inheritance detected during generalization Specification Inheritance Object-Oriented Software Engineering: Conquering Complex and Changing Systems Implementation Inheritance 7 Figure 8-5, An example of design pattern: Adapter. Client ClientInterface LegacyClass Request() ExistingRequest() adaptee Adapter Request() Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 8 Figure 8-6, Applying the Adapter design pattern to the Set problem of Figure 8-3. Client Set Hashtable add(element) put(key,element) adaptee MySet add(element) Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 9 Figure 8-7, Applying the Bridge design pattern for abstracting database vendors. Arena LeagueStore Stub Store Implementor Bernd Bruegge & Allen Dutoit imp LeagueStoreImplementor XML Store Implementor Object-Oriented Software Engineering: Conquering Complex and Changing Systems JDBC Store Implementor 10 Figure 8-8, Applying the Adapter design pattern for sorting Strings in an Array. See source code in Figure 8-9. Array Comparator MyString compare() greaterThan() equals() adaptee MyStringComparator compare() Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 11 Figure 8-9, Adapter design pattern example. /* Existing target interface */ interface Comparator { int compare(Object o1, Object o2); /* ... */ } /* Existing client */ class Array { static void sort(Object [] a, Comparator c); /* ... */ } /* Existing adaptee class */ class MyString extends String { boolean equals(Object o); boolean greaterThan (MyString s); /* ... */ } Bernd Bruegge & Allen Dutoit /* New adapter class */ class MyStringComparator implements Comparator { /* ... */ int compare(Object o1, Object o2) { int result; if (o1.greaterThan(o2)) { result = 1 } else if (o1.equals(o2)) { result = 0; } else { result = -1; } return result; } } Object-Oriented Software Engineering: Conquering Complex and Changing Systems 12 Figure 8-10, Applying the Strategy pattern for encapsulating multiple implementations of a NetworkInterface. Application NetworkConnection LocationManager open() close() send() receive() send() receive() setNetworkInterface() Ethernet open() close() send() receive() Bernd Bruegge & Allen Dutoit NetworkInterface WaveLAN open() close() send() receive() UMTS open() close() send() receive() Object-Oriented Software Engineering: Conquering Complex and Changing Systems 13 Figure 8-12, Applying the Abstract Factory design pattern to different intelligent house platforms TheftApplication HouseFactory createBulb() createBlind() EIBFactory createBulb() createBlind() LuxmateFactory createBulb() createBlind() LightBulb EIBBulb Bernd Bruegge & Allen Dutoit LuxmateBulb Blind EIBBulb Object-Oriented Software Engineering: Conquering Complex and Changing Systems LuxmateBulb 14 Figure 8-13, Applying the Command design pattern to Matches in ARENA. Match * play() replay() Move execute() «binds» GameBoard TicTacToeMove execute() ChessMove execute() Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 15 Figure 8-14, Anatomy of a preference dialog. Aggregates, called Panels, are used for grouping user interface objects that need to be resized and moved together. Top panel Main panel Button panel Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 16 Figure 8-15, UML object diagram for the user interface objects of Figure 8-14. prefs:Window top:Panel title:Label main:Panel c1:Checkbox buttons:Panel ok:Button c2:Checkbox cancel:Button c3:Checkbox c4:Checkbox Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 17 Figure 8-16, Applying the Composite design pattern to user interface widgets. Component * move() resize() Label Button Checkbox Composite move() resize() Window Panel Applet Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 18 Figure 8-17, An example of dynamic site with WebObjects. WebBrowser WebServer StaticHTML WebObjectsApplication WOAdaptor WoRequest WORequest Template EOF RelationalDatabase Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 19 Figure 8-18, WebObject’s State Management Classes. The HTTP protocol is inherently stateless. WOAdaptor WORequest WebServer WOSessionStore * WOApplication * WOSession Bernd Bruegge & Allen Dutoit * WOComponent * DynamicElement * Object-Oriented Software Engineering: Conquering Complex and Changing Systems 20 Figure 8-19, ARENA analysis objects related to Game independence. Arena LeagueOwner Statistics League Game Tournament Player Move TicTacToe Match Chess Result Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 21 Figure 8-20, Applying the Abstract Factory pattern to Games Tournament Game createMatch() createStatistics() TicTacToe createBulb() createBlind() Match TTTMatch Bernd Bruegge & Allen Dutoit Chess createBulb() createBlind() Statistics ChessMatch TTTStats Object-Oriented Software Engineering: Conquering Complex and Changing Systems ChessStats 22 Figure 8-21, Applying the Command design pattern to Matches and ReplayedMatches in ARENA. Match ReplayedMatch nextMove() previousMove() * play() replay() «binds» GameBoard Move execute() TicTacToeMove ChessMove Bernd Bruegge & Allen Dutoit Object-Oriented Software Engineering: Conquering Complex and Changing Systems 23 Figure 8-22, Applying the Observer design pattern to maintain consistency across MatchViews. observers Subject 1 subscribe(Subscriber) unsubscribe(Subscriber) notify() GameBoard state getState() playMove() Bernd Bruegge & Allen Dutoit Observer * update() MatchView gameBoard update() Object-Oriented Software Engineering: Conquering Complex and Changing Systems 24