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
Practical Object-Oriented Design with UML 2e PRACTICAL OBJECT-ORIENTED DESIGN WITH UML 2e Chapter 14: Principles and Patterns ©The McGraw-Hill Companies, 2004 Slide 1/1 Practical Object-Oriented Design with UML 2e Principles and Patterns ● The activity of design can be informed by – principles: general statements of what properties a design ought to have – patterns: concrete examples of successful designs for particular purposes ©The McGraw-Hill Companies, 2004 Slide 1/2 Practical Object-Oriented Design with UML 2e Valid or Correct Models • A model is said to be valid (or legal) if it conforms to the UML rules. A model is correct if it faithfully represents reality. Assuming that the UML is correct, we can state that all correct models are valid models. However, the converse may not true – valid models are not necessarily correct models. For example, imagine that a hospital is being modeled, but the modeler fails to include a critical state, such as a WardFull state. In this case, the UML class diagram is valid (UML does not require a WardFull state , but merely allows it), but is incorrect, since it does not represent reality. However, if the UML required every model to include the a WardFull state, the model would be invalid. We can now consider good configurations or designs of valid models. ©The McGraw-Hill Companies, 2004 Slide 1/3 Practical Object-Oriented Design with UML 2e System Evolution ● How can we insulate modules from change? ● We would like to be able to change modules without affecting their clients – this will increase the maintainability of the system ©The McGraw-Hill Companies, 2004 Slide 1/4 Practical Object-Oriented Design with UML 2e Open and Closed Modules ● A module is said to be closed if it is not subject to further change – clients can then rely on the services the module provides ● A module is said to be open if it is still available for extension – this will make it possible to extend and modify the system ©The McGraw-Hill Companies, 2004 Slide 1/5 Practical Object-Oriented Design with UML 2e The Open-Closed Principle ● Open and closed modules both have advantages ● The open-closed principle states that developers should try to produce modules that are both open and closed ● This sounds like a paradox – to resolve it we need a way of making a module extendible without having to change it ©The McGraw-Hill Companies, 2004 Slide 1/6 Practical Object-Oriented Design with UML 2e Interface and Implementation ● The interface of a module is what is visible or available to clients ● The implementation is the internal details of the module that support the interface ● One approach to open-closed modules is to ensure that clients only depend on the interfaces of the modules they use – and make it possible to change the implementations freely ©The McGraw-Hill Companies, 2004 Slide 1/7 Practical Object-Oriented Design with UML 2e Data Abstraction ● Data abstraction assigns an access level to each feature in a class ● Clients can use only the public interface ● Private features - eg method bodies - can be freely changed ©The McGraw-Hill Companies, 2004 Slide 1/8 Practical Object-Oriented Design with UML 2e Limitations ● Even with data abstraction, Java classes are technically not closed – changes to method bodies affect the source code and entail recompilation of clients ● The interface actually used by clients is left implicit (no actual interface just concrete supplier or server) ©The McGraw-Hill Companies, 2004 Slide 1/9 Practical Object-Oriented Design with UML 2e Abstract Interface Classes ● An approach based on generalization (not pure interfaces) ● Abstract classes can provide a complete or partial implementation of a method(s). ©The McGraw-Hill Companies, 2004 Slide 1/10 Practical Object-Oriented Design with UML 2e How the Interface Works ● Clients access different concrete suppliers through the abstract supplier interface ● This is enabled by features of the objectoriented programming paradigm – polymorphism: a reference to the interface class can actually refer to any implementation class – dynamic binding: messages to the interface are passed on the appropriate implementation class ©The McGraw-Hill Companies, 2004 Slide 1/11 Practical Object-Oriented Design with UML 2e Dependencies ● The dependency structure indicates that the client is independent of the concrete suppliers ©The McGraw-Hill Companies, 2004 Slide 1/12 Practical Object-Oriented Design with UML 2e Open and Closed ● The abstract supplier class is – open in the sense that its functionality can be extended by adding further subclasses – closed in that this can be done without affecting clients ● However, the client is not protected against changes in the interface exported by the abstract supplier class ©The McGraw-Hill Companies, 2004 Slide 1/13 Practical Object-Oriented Design with UML 2e No Concrete Superclasses ● It has sometimes been recommended that all superclasses in a system should be abstract ● Often subclasses are added to concrete classes as a system evolves ©The McGraw-Hill Companies, 2004 Slide 1/14 Practical Object-Oriented Design with UML 2e A Dependency Problem ● The savings account class is now dependent on the current account class – changes to the current account - altering functionality or adding and removing operations will affect savings accounts ● This leads to problems – the changes may not apply to savings accounts – the code may become cluttered with checks for special cases ©The McGraw-Hill Companies, 2004 Slide 1/15 Practical Object-Oriented Design with UML 2e ‘Refactoring’ the Design ● A better approach is to introduce an abstract interface class – even if it initially seems unnecessary ©The McGraw-Hill Companies, 2004 Slide 1/16 Practical Object-Oriented Design with UML 2e Decoupling Interfaces ● Clients can be protected from interface change by defining separate interface and implementation hierarchies ● Make the abstract supplier an interface: ©The McGraw-Hill Companies, 2004 Slide 1/17 Practical Object-Oriented Design with UML 2e Separate Interface Hierarchy ● Extend the interface to add a new operation – abstract supplier can be extended without affecting existing clients ©The McGraw-Hill Companies, 2004 Slide 1/18 Practical Object-Oriented Design with UML 2e Liskov Substitution Principle ● States the conditions under which references to superclasses can safely be converted to references to subclasses – “it must be possible to substitute an instance of a subclass for an instance of a superclass without affecting client classes or modules” – this defines what generalization means in UML ©The McGraw-Hill Companies, 2004 Slide 1/19 Practical Object-Oriented Design with UML 2e Design Based on Structure ● It is sometimes tempting to base a design on the physical structure of the artefact being modelled – for example, a mobile phone ©The McGraw-Hill Companies, 2004 Slide 1/20 Practical Object-Oriented Design with UML 2e Realizing ‘Make a Call’ ● This interaction looks plausible: ● But the associations based on the phone structure do not support these messages ©The McGraw-Hill Companies, 2004 Slide 1/21 Practical Object-Oriented Design with UML 2e Design Based on Interactions ● A better model of the phone is derived from the interactions in the realization ©The McGraw-Hill Companies, 2004 Slide 1/22 Practical Object-Oriented Design with UML 2e Design Patterns ● Solutions to common design problems ● Catalogued and published to aid reuse ● A pattern consists of: – a name, for easy reference – a description of the problem being solved – a description of the solution proposed – a discussion of the consequences of adopting the pattern ©The McGraw-Hill Companies, 2004 Slide 1/23 Practical Object-Oriented Design with UML 2e Recursive Structures ● Many data structures are recursive, eg ©The McGraw-Hill Companies, 2004 Slide 1/24 Practical Object-Oriented Design with UML 2e The ‘Composite’ Pattern ● ‘Composite’ defines the essential properties of this sort of situation ©The McGraw-Hill Companies, 2004 Slide 1/25 Practical Object-Oriented Design with UML 2e Discussion of Composite ● The problem is how to implement tree-like structures ● The diagram shows only the solution – ‘Leaf’ and ‘Composite’ classes share a common interface, defined in ‘Component’ – ‘Composite’ implements this by iterating through all its components ©The McGraw-Hill Companies, 2004 Slide 1/26 Practical Object-Oriented Design with UML 2e Patterns in UML ● UML documents patterns as parameterized collaborations ©The McGraw-Hill Companies, 2004 Slide 1/27 Practical Object-Oriented Design with UML 2e Documenting Pattern Application ● When applying a pattern you must show what the its classes correspond to ©The McGraw-Hill Companies, 2004 Slide 1/28 Practical Object-Oriented Design with UML 2e The ‘State’ Pattern ● Problem: how to ‘allow an object to alter its behaviour when its internal state changes’ – applicable if a class is described by a statechart ● Solution: represent each state by a separate class – each state class will implement the behaviour appropriate for each operation in that state only ©The McGraw-Hill Companies, 2004 Slide 1/29 Practical Object-Oriented Design with UML 2e The ‘State’ Solution ● A consequence of this pattern is that the state classes need access to the internal details of the context class ©The McGraw-Hill Companies, 2004 Slide 1/30 Practical Object-Oriented Design with UML 2e The ‘Strategy’ Pattern ● Problem: how to allow different instances of a class to support different implementations of an operation ● Solution: separate out the implementation of the operation into a new class hierarchy – link each instance to a particular implementation object ©The McGraw-Hill Companies, 2004 Slide 1/31 Practical Object-Oriented Design with UML 2e The ‘Strategy’ Solution ● The structure is very similar to that of ‘State’ – treated as a different pattern because the problem being solved is different ©The McGraw-Hill Companies, 2004 Slide 1/32 Practical Object-Oriented Design with UML 2e Models, Views and Controllers ● MVC: a design proposal put forward for the Smalltalk language – to design programs with graphical interfaces – separates manipulation and presentation of data ● Now widely used in a variety of contexts – the model stores and maintains data – views display data in specific ways – controllers detect and forward user input ©The McGraw-Hill Companies, 2004 Slide 1/33 Practical Object-Oriented Design with UML 2e Models, Views and Controllers ©The McGraw-Hill Companies, 2004 Slide 1/34 Practical Object-Oriented Design with UML 2e Interactions in MVC ● User input detected by a controller ● The model is notified ● The views are updated ©The McGraw-Hill Companies, 2004 Slide 1/35 Practical Object-Oriented Design with UML 2e Document/View Architecture ● Widely used by Microsoft ● A simplification of MVC – ‘Views’ combine the functions of MVC views and controllers ©The McGraw-Hill Companies, 2004 Slide 1/36 Practical Object-Oriented Design with UML 2e Document/View Structure ©The McGraw-Hill Companies, 2004 Slide 1/37 Practical Object-Oriented Design with UML 2e Document/View Interactions ● Compare this with the MVC interaction ©The McGraw-Hill Companies, 2004 Slide 1/38 Practical Object-Oriented Design with UML 2e The ‘Observer’ Pattern ● Problem: to define a dependency between objects so that when one object changes state all its dependants are notified ● Solution: like MVC, separate ‘subject’ (ie model) from ‘observer’ (ie view) ©The McGraw-Hill Companies, 2004 Slide 1/39 Practical Object-Oriented Design with UML 2e ‘Observer’ Structure ©The McGraw-Hill Companies, 2004 Slide 1/40 Practical Object-Oriented Design with UML 2e ‘Observer’ Interactions ● This interaction is simpler because the initial message is sent straight to the ‘model’ class ©The McGraw-Hill Companies, 2004 Slide 1/41 Practical Object-Oriented Design with UML 2e Parts Explosion ● New requirement for the stock control program – print a listing of all the parts and subassemblies in an assembly ● Simple approach: – add an ‘explode’ operation to each class – call it recursively, like the existing ‘cost’ operation ©The McGraw-Hill Companies, 2004 Slide 1/42 Practical Object-Oriented Design with UML 2e Problems ● There are a number of problems with this – this approach involves changes to every class in the hierarchy – the code that controls the recursion is repeated in both ‘cost’ and ‘explode’ – model classes like ‘Part’ should not produce output ● Is there a pattern that can help? ©The McGraw-Hill Companies, 2004 Slide 1/43 Practical Object-Oriented Design with UML 2e The ‘Visitor’ pattern ● Problem: Visitor lets you define a new operation without changing the classes of the elements on which it operates ● Solution: define a ‘visitor’ class and an operation in each class to be visited to ‘accept’ a visitor ● Consequence: the design becomes more complex, but more extendible ©The McGraw-Hill Companies, 2004 Slide 1/44 Practical Object-Oriented Design with UML 2e Finding Costs with Visitor ● This illustrates Visitor with a single operation ©The McGraw-Hill Companies, 2004 Slide 1/45 Practical Object-Oriented Design with UML 2e The ‘CostVisitor’ Class ● ‘CostVisitor’ gets ‘called’ for each component and keeps track of the total cost of parts public class CostVisitor { private int total ; public void visit(Part p) { total += p.cost() ; } public void visit(Assembly a) {} } ©The McGraw-Hill Companies, 2004 Slide 1/46 Practical Object-Oriented Design with UML 2e Finding the Cost ● We no longer call a cost function belonging to an assembly ● Instead, we pass a cost visitor to it Assembly a ; CostVisitor visitor = new CostVisitor() ; a.accept(visitor) ; int cost = visitor.getTotal() ; ©The McGraw-Hill Companies, 2004 Slide 1/47 Practical Object-Oriented Design with UML 2e ‘Visitor’ Interactions ©The McGraw-Hill Companies, 2004 Slide 1/48 Practical Object-Oriented Design with UML 2e Adding Part Explosions ● Extend the design by defining a visitor hierarchy ©The McGraw-Hill Companies, 2004 Slide 1/49 Practical Object-Oriented Design with UML 2e Mediator Pattern ● The intent is to define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. The purpose of a Mediator is to manage the relationships between numerous objects so that they can each focus on their own behaviour independently of the others. ©The McGraw-Hill Companies, 2004 Slide 1/50 Practical Object-Oriented Design with UML 2e Mediator Pattern ©The McGraw-Hill Companies, 2004 Slide 1/51 Practical Object-Oriented Design with UML 2e Mediator Pattern with Java ©The McGraw-Hill Companies, 2004 Slide 1/52 Practical Object-Oriented Design with UML 2e Mediator Pattern in Java ● An Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. ● The mediator pattern centralises dependencies between objects. Instead of code being written in one (dependent) object to update the state of that object when another object that it depends on changes state, there is a separate mediator object which links them and performs the necessary logic to compute the change needed by the dependent object. ©The McGraw-Hill Companies, 2004 Slide 1/53 Practical Object-Oriented Design with UML 2e Mediator Pattern in Java ● An Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. ● This reduces the complexity of the objects and increases flexibility. For example, if rules connecting that objects need to change without the objects themselves changing. ©The McGraw-Hill Companies, 2004 Slide 1/54 Practical Object-Oriented Design with UML 2e Mediator Pattern in Java ● An Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. ● Aim: to simplify complex connections and dependencies between a set of objects by defining Mediator objects which centralize information about these dependencies. ● Implementation: based on the idea of event sources and event targets. ©The McGraw-Hill Companies, 2004 Slide 1/55 Practical Object-Oriented Design with UML 2e Mediator Pattern in Java ● An Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. ● The Mediator is more general than the Observer in that objects may be both event sources and event targets. Also the code for updating event targets on notification of an event is separated out from these targets. ● The Mediator enhances maintainability and flexibility because it removes knowledge of dependencies and the detail of the dependency management code from collaborating objects and puts it in the mediator object instead. When the rules of dependency change, only the mediator object needs rewriting ©The McGraw-Hill Companies, 2004 Slide 1/56 Practical Object-Oriented Design with UML 2e Mediator Pattern in Java ● An Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. ● In the following program the first action ca.credit(600), causes credit of 600 to be added to the current account, resulting in ca’s credit listener being activated, and this then trims as 100 from the current account balance and adds this to the deposit account. In the second action, cust.withdraw(550), the withdraw listener of the customer is activated and removes 500 units from the current account and 50 from the deposit. ©The McGraw-Hill Companies, 2004 Slide 1/57 Practical Object-Oriented Design with UML 2e Mediator Pattern in Java ● An Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. ● In the following program the first action ca.credit(600), causes credit of 600 to be added to the current account, resulting in ca’s credit listener being activated, and this then trims as 100 from the current account balance and adds this to the deposit account. In the second action, cust.withdraw(550), the withdraw listener of the customer is activated and removes 500 units from the current account and 50 from the deposit. ©The McGraw-Hill Companies, 2004 Slide 1/58 Practical Object-Oriented Design with UML 2e Mediator Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. ● interface WithdrawListener ● { void withdraw(int ammount); } ● interface CreditListener ● { void credit(int ammount); } ©The McGraw-Hill Companies, 2004 Slide 1/59 Practical Object-Oriented Design with UML 2e Mediator Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. class Customer { private String name; private Vector withdrawListeners = new Vector(); public Customer(String nme) { name = nme; } public void addWithdrawListener(WithdrawListener w) { withdrawListeners.add(w);} public void withdraw(int amount) { for (int i = 0; i < withdrawListeners.size(); i++) { WithdrawListener wl = (WithdrawListener) withdrawListeners.get(i); wl.withdraw(amount); }}} ©The McGraw-Hill Companies, 2004 Slide 1/60 Practical Object-Oriented Design with UML 2e Mediator Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. class Customer { private String name; private Vector withdrawListeners = new Vector(); public Customer(String nme) { name = nme; } public void addWithdrawListener(WithdrawListener w) { withdrawListeners.add(w);} public void withdraw(int amount) { for (int i = 0; i < withdrawListeners.size(); i++) { WithdrawListener wl = (WithdrawListener) withdrawListeners.get(i); wl.withdraw(amount); } } } ©The McGraw-Hill Companies, 2004 Slide 1/61 Practical Object-Oriented Design with UML 2e Mediator Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. class Account { private int accountNo; // unique account identifier private int balance=0; private Vector creditListeners = new Vector(); public Account (int ac) { accountNo = ac;} public void addCreditListener(CreditListener cl) { creditListeners.add(cl);} public int getBalance() {return balance;} public void credit(int amount) { balance += amount; for (int i = 0; i < creditListeners.size(); i++) { CreditListener cl = (CreditListener) creditListeners.get(i); cl.credit(amount); }} public void debit(int amount) { balance -= amount; } } ©The McGraw-Hill Companies, 2004 Slide 1/62 Practical Object-Oriented Design with UML 2e Mediator Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. class CurrentAccount extends Account { public CurrentAccount(int ac) { super(ac);} } class DepositAccount extends Account { public DepositAccount(int ac) { super(ac);} } ©The McGraw-Hill Companies, 2004 Slide 1/63 Practical Object-Oriented Design with UML 2e Mediator Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. class Mediator implements WithdrawListener, CreditListener { private CurrentAccount caccount; private DepositAccount daccount; public void registerCurrentAccount(CurrentAccount ac) { caccount = ac; } public void registerDepositAccount(DepositAccount ad) { daccount = ad; } ©The McGraw-Hill Companies, 2004 Slide 1/64 Practical Object-Oriented Design with UML 2e Mediator Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. /* business rule */ public void withdraw(int amount){ int caBal = caccount.getBalance(); int daBal = daccount.getBalance(); if (caBal >= amount) { caccount.debit(amount); } else if (caBal + daBal >= amount) {caccount.debit(caBal); daccount.debit(amount-caBal);} } ©The McGraw-Hill Companies, 2004 Slide 1/65 Practical Object-Oriented Design with UML 2e Mediator Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. /* business rule */ public void credit(int amount){ int caBal = caccount.getBalance(); if (caBal > 500) { caccount.debit(caBal - 500); daccount.credit(caBal - 500); }} ©The McGraw-Hill Companies, 2004 Slide 1/66 Practical Object-Oriented Design with UML 2e Mediator Example From “Software Design Using Java 2” By Lano, Fiadeiro & Andrade. public class MediatorTest { public static void main (String args[]) { Mediator med = new Mediator(); CurrentAccount ca = new CurrentAccount(1022); DepositAccount da = new DepositAccount(7565); Customer cust = new Customer("Felix"); cust.addWithdrawListener(med); ca.addCreditListener(med); med.registerCurrentAccount(ca); med.registerDepositAccount(da); ca.credit(600); System.out.println(ca.getBalance()); System.out.println(da.getBalance()); cust.withdraw(550); System.out.println(ca.getBalance()); ©The McGraw-Hill Companies, 2004 System.out.println(da.getBalance()); }} Slide 1/67 Practical Object-Oriented Design with UML 2e Patterns ● The use of patterns is essentially the reuse of well established good ideas. A pattern is a named well understood good solution to a common problem in context. Patterns describe how objects communicate without becoming entangled in each other’s data models and methods. Keeping this separation has always been an objective of good OO programming, objects should mind their own business, but obviously need the services of other objects as well. Definition from Gamma, et al., 1993 “Patterns identify and specify abstractions that are above the level of single classes and instances, or of components”. Patterns can exist at many levels from very low level specific solutions to broadly generalized system issues. Patterns are often described using UML together with a pattern template A template describes a pattern. Typical template may contain: Name, Intent, AKA, Motivation, Application, Structure, Participation, Collaborations, Consequences, Implementation, Sample Code, Known Uses, Related Patterns. Template not usually enough ned context and understanding (see Priestley). ©The McGraw-Hill Companies, 2004 Slide 1/68 Practical Object-Oriented Design with UML 2e Patterns ● Main advantages capture best practice, reuse, fairly standard way of describing patterns. ● Disadvantages: advanced topic, learning design patterns is a long multiple step process; Acceptance, Recognition, Internalisation, on the other hand they are worth learning. Role of experience. More geared to OO than other computing paradigms. ©The McGraw-Hill Companies, 2004 Slide 1/69