SOE bottom-up design - refactoring and patterns
Transcription
SOE bottom-up design - refactoring and patterns
SOE bottom-up design - refactoring and patterns the design problem: • the software design inadequately solves the problem, creating issues such as performance, usability, maintainability, adaptivity, portability, security, …………… • software erosion • leads to: (the quality problem: the system is delivered with bugs, service and usability problems that make it difficult to use) SOE: refactoring and patterns 2 architecture components modules architecture screen sketch object model ERM design as model design as code screen code object code database tables design style algorithm design data validation exception handling detailed design abstraction level SOE: refactoring and patterns 3 top-down v. evolutionary design architecture traditional agile design as model design as code detailed design SOE: refactoring and patterns 4 top down design - MDA (Model Driven Architecture) executable UML compiler J2EE .NET archetype SOE: refactoring and patterns 5 bottom-up design – refactoring ‟Refactoring: improving the design of existing code‟ Marting Fowler, Addison Wesley bottom up design: refactoring • refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior • refactor (verb): to restructure software by applying a series of refactorings • refactoring is not: • debugging • mending business logic • adding new functionality Martin Fowler (and Kent Beck, John Brant, William Opdyke, Don Roberts), Refactoring - Improving the Design of Existing Code, Addison Wesley, 1999 SOE: refactoring and patterns 7 simple refactoring example case 0: activePiece = RightHookgetRightHook(); case 0: activePiece = RightHookgetRightHook(); ml = new MoveListener(activePiece); gameBoardaddKeyListener(ml); break; case 1: case 1: activePiece = LeftHookgetLeftHook(); activePiece = RightRisegetRightRise(); activePiece = RightRisegetRightRise(); activePiece = LeftRisegetLeftRise(); case 3: break; case 4: activePiece = HillgetHill(); case 5: break; activePiece = StraightPiecegetStraightPiece(); break; ml = new MoveListener(activePiece); gameBoardaddKeyListener(ml); break; break; case 3: gameBoardaddKeyListener(ml); break; case 2: break; case 2: activePiece = LeftHookgetLeftHook(); ml = new MoveListener(activePiece); break; case 6: activePiece = SquaregetSquare(); break; } activePiece = LeftRisegetLeftRise(); ml = new MoveListener(activePiece); ml = new MoveListener(activePiece); gameBoardaddKeyListener(ml); gameBoardaddKeyListener(ml); break; //more SOE: refactoring and patterns 8 why refactor? refactoring improves design without refactoring, even a well designed program will decay („go sour‟) as programmers make changes refactoring makes software easier to understand understandable code is easier to update and maintain refactoring helps find bugs refactoring involves clarification and re-shaping through better understanding refactoring speeds up programming good design ensures comprehensibility and fewer changes as new functionality is added SOE: refactoring and patterns 9 bad smells • • • • • • • • • • • • duplicate code: identical or very similar code exists in more than one location large method: a method, function, or procedure that has grown too large large class: a class that has grown too large (god object) feature envy: a class that uses methods of another class excessively inappropriate intimacy: a class that has dependencies on implementation details of another class data clumps: a set of variables that seem to “hang out” together – e.g. often passed as parameters, changed/accessed at the same time primitive obsession: all subparts of an object are instances of primitive types (int, string, bool, double, etc) refused bequest: a class that overrides a method of a base class in such a way that the contract of the base class is not honored by the derived class lazy class: a class that does too little duplicated method: a method, function, or procedure that is very similar to another contrived complexity: forced usage of overly complicated design patterns where simpler design would suffice ………… SOE: refactoring and patterns 10 refactoring (n): a standard way of improving poor code bad smell SOE: refactoring and patterns Add Parameter Change Bidirectional Association to Unidirectional Change Reference to Value Change Unidirectional Association to Bidirectional Change Value to Reference Collapse Hierarchy Consolidate Conditional Expression Consolidate Duplicate Conditional Fragments Convert Dynamic to Static Construction by Gerard M. Davison Convert Static to Dynamic Construction by Gerard M. Davison Decompose Conditional Duplicate Observed Data Eliminate Inter-Entity Bean Communication (Link Only) Encapsulate Collection Encapsulate Downcast Encapsulate Field Extract Class Extract Interface Extract Method Extract Package by Gerard M. Davison Extract Subclass Extract Superclass Form Template Method Hide Delegate Hide Method Hide presentation tier-specific details from the business tier (Link Only) Inline Class Inline Method Inline Temp Introduce A Controller (Link Only) Introduce Assertion Introduce Business Delegate (Link Only) Introduce Explaining Variable Introduce Foreign Method Introduce Local Extension Introduce Null Object Introduce Parameter Object Introduce Synchronizer Token (Link Only) Localize Disparate Logic (Link Only) Merge Session Beans (Link Only) Move Business Logic to Session (Link Only) Move Class by Gerard M. Davison Move Field Move Method Parameterize Method Preserve Whole Object Pull Up Constructor Body Pull Up Field Pull Up Method Push Down Field Push Down Method Reduce Scope of Variable by Mats Henricson Refactor Architecture by Tiers (Link Only) Remove Assignments to Parameters Remove Control Flag Remove Double Negative by Ashley Frieze and Martin Fowler Remove Middle Man Remove Parameter Remove Setting Method Rename Method Replace Array with Object Replace Assignment with Initialization by Mats Henricson Replace Conditional with Polymorphism Replace Conditional with Visitor by Ivan Mitrovic Replace Constructor with Factory Method Replace Data Value with Object Replace Delegation with Inheritance Replace Error Code with Exception Replace Exception with Test Replace Inheritance with Delegation Replace Iteration with Recursion by Dave Whipp Replace Magic Number with Symbolic Constant Replace Method with Method Object Replace Nested Conditional with Guard Clauses Replace Parameter with Explicit Methods Replace Parameter with Method Replace Record with Data Class Replace Recursion with Iteration by Ivan Mitrovic Replace Static Variable with Parameter by Marian Vittek Replace Subclass with Fields Replace Temp with Query Replace Type Code with Class Replace Type Code with State/Strategy Replace Type Code with Subclasses Reverse Conditional by Bill Murphy and Martin Fowler Self Encapsulate Field Separate Data Access Code (Link Only) Separate Query from Modifier Split Loop by Martin Fowler Split Temporary Variable Substitute Algorithm Use a Connection Pool (Link Only) Wrap entities with session (Link Only) 11 very simple example title titleText titleX titleY titleColour bad smell: data clump refactoring: extract class SOE: refactoring and patterns 12 class Customer extends DomainObject { public Customer(String name) { _name = name; } public String statement() { double totalAmount = 0; int frequentRenterPoints = 0; Enumeration rentals = _rentals.elements(); String result = "Rental Record for " + name() + "\n"; while (rentals.hasMoreElements()) { double thisAmount = 0; Rental each = (Rental) rentals.nextElement(); //determine amounts for each line switch (each.tape().movie().priceCode()) { case Movie.REGULAR: thisAmount += 2; if (each.daysRented() > 2) thisAmount += (each.daysRented() - 2) * 1.5; break; case Movie.NEW_RELEASE: thisAmount += each.daysRented() * 3; break; case Movie.CHILDRENS: thisAmount += 1.5; if (each.daysRented() > 3) thisAmount += (each.daysRented() - 3) * 1.5; break; Fowler’s video shop example } totalAmount += thisAmount; // add frequent renter points frequentRenterPoints ++; // add bonus for a two day new release rental if ((each.tape().movie().priceCode() == Movie.NEW_RELEASE) && each.daysRented() > 1) frequentRenterPoints ++; //show figures for this rental result += "\t" + each.tape().movie().name()+ "\t" + String.valueOf(thisAmount) + "\n"; refactor: replace condition with polymorphism points"; } //add footer lines result +=Movie "Amount owed is " + String.valueOf(totalAmount) Price + "\n"; result += "You earned " + String.valueOf(frequentRenterPoints) + " frequent renter 1 return result; charge() } public void addRental(Rental arg) { _rentals.addElement(arg); } public static Customer get(String name) { <<code>> 1 return (Customer) Registrar.get("Customers", name); ChildrensPrice return} priceCode.charge() public void persist() { Registrar.add("Customers", this); charge() } private Vector _rentals = new Vector(); SOE: refactoring and patterns charge() RegularPrice charge() 1 NewRelease 1 Price charge() 13 common refactorings • push down method - behaviour on a super class is relevant only for some of its subclasses‟ - the method is moved to those subclasses • extract subclass - „a class has features that are used only in some instances‟ - a subclass is created for that subset of features • encapsulate field - the declaration of a field is changed from public to private • hide method - „a method is not used by any other class‟ - the method should be made private • pull up field - „two subclasses have the same field‟ - the field in question should be moved to the super class • extract super class – „two classes with similar features‟ - in this case, create a super class and move the common features to the super class SOE: refactoring and patterns 14 common refactorings • push down field - a field is used only by some subclasses‟ - the field is moved to those subclasses • pull up method - methods with identical results in subclasses‟ - methods should be moved to the super class • move method - a method is, or will be, using or used by more features of another class than the class on which it is defined‟ • move field - a field is, or will be, used by another class more than the class on which it is defined‟ • rename method - a method is renamed to make its purpose more obvious. • rename field - field is renamed to make its purpose more obvious SOE: refactoring and patterns 15 refactoring principles • make changes small and methodical • follow design patterns • have your test suites ready • refactoring introduces new bugs • sometimes in unrelated parts of the programme • run test suites each time you refactor • clean before you add new functionality SOE: refactoring and patterns 16 two dubious refactoring practices refactoring the architecture refactoring: „extract package‟, „refactor architecture by tiers‟ • large scale decisions about the organisation of the program taken too late in the construction because of insufficient overview • liable to cause chaos unless extremely well thought out the refactoring sprint(s) • some weeks in the life of the project, paid for by the customer, where the only purpose is to rectify relatively serious design problems caused by lack of real understanding of the user domain and too early commitment to programming SOE: refactoring and patterns 17 traditional view of refactoring • refactoring reflects poor analysis and design work – do it right first time • refactoring is expensive – all prior documentation must be altered • refactoring introduces new errors in unpredictable places • refactoring threatens architectural integrity • customers expect new functionality and will not pay for rework • refactoring does not extend value – if it ain‟t broke don‟t fix it SOE: refactoring and patterns 18 bottom-up design: patterns the pattern movement pattern • • • • • • • • a pattern addresses a recurring problem that arises in specific situations patterns document existing, well-proven design experience patterns identify and specify abstractions that are above the level of single classes and instances patterns provide a common vocabulary and understanding for design principles patterns are a means of documenting software architectures patterns support the construction of software with defined properties patterns help you build complex and heterogeneous software architectures patterns help you manage software complexity SOE: refactoring and patterns 20 standard documentation form pattern name and classification: a descriptive and unique name that helps in identifying and referring to the pattern intent: a description of the goal behind the pattern and the reason for using it also known as: other names for the pattern motivation (forces): a scenario consisting of a problem and a context in which this pattern can be used applicability: situations in which this pattern is usable; the context for the pattern structure: a graphical representation of the pattern – class diagrams and interaction diagrams may be used for this purpose participants: a listing of the classes and objects used in the pattern and their roles in the design collaboration: a description of how classes and objects used in the pattern interact with each other consequences: a description of the results, side effects, and trade offs caused by using the pattern implementation: a description of an implementation of the pattern; the solution part of the pattern sample code: an illustration of how the pattern can be used in a programming language known uses: examples of real usages of the pattern related patterns: other patterns that have some relationship with the pattern; discussion of the differences between the pattern and similar patterns SOE: refactoring and patterns 21 types of patterns • • • • analysis patterns design patterns/GRASP software architecture patterns organizational and process patterns SOE: refactoring and patterns 22 analysis patterns • • patterns that reflect the generic conceptual structure of business processes rather than actual software implementations simple, specialized notation (very similar to entity-relationship diagram notation) ‘Analysis Patterns: Reusable Object Models’, Martin Fowler SOE: refactoring and patterns analysis problem analysis pattern 23 organisational and process patterns • research into social and behavioural patterns in software firms which lead to successful outcomes Coplien‟s top ten patterns • • • • • • • • • • SOE: refactoring and patterns unity of purpose engage customers domain expertise in roles architect controls product distribute work evenly function owner and component owner mercenary analyst architect also implements firewalls developer controls process 24 design anti-patterns • • • • • • • • • • big ball of mud: a system with no recognizable structure database-as-ipc: using a database as the message queue for routine inter-process communication where a much more lightweight mechanism would be suitable gas factory: an unnecessarily complex design gold plating: continuing to work on a task or project well past the point at which extra effort is adding value inner-platform effect: a system so customizable as to become a poor replica of the software development platform input kludge: failing to specify and implement handling of possibly invalid input interface bloat: making an interface so powerful that it is extremely difficult to implement magic pushbutton: coding implementation logic directly within interface code, without using abstraction race hazard: failing to see the consequence of different orders of events stovepipe system: a barely maintainable assemblage of ill-related components SOE: refactoring and patterns 25 design patterns • • • • • design patterns provide abstract, reusable “micro-architectures” that can be applied (“instantiated”) to resolve specific design issues (forces) in previously-used, high-quality ways GoF (Gang of Four) creational - manage instantiation - can be further divided into classcreation (use inheritance effectively) patterns and object-creational (use delegation) patterns structural - concern class and object composition - use inheritance to compose interfaces and define ways to compose objects to obtain new functionality behavioural - concerned with communication between objects GAMMA, E., HELM, R., JOHNSON, R. & VLISSIDES, J. (1995) Design Patterns, Boston, Addison-Wesley. SOE: refactoring and patterns 26 GoF creational patterns: • abstract factory groups object factories that have a common theme • builder constructs complex objects by separating construction and representation • factory method creates objects without specifying the exact class to create • prototype creates objects by cloning an existing object • singleton restricts object creation for a class to only one instance SOE: refactoring and patterns 27 GoF structural patterns: • adapter allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class • bridge decouples an abstraction from its implementation so that the two can vary independently • composite composes zero-or-more similar objects so that they can be manipulated as one object • decorator dynamically adds/overrides behaviour in an existing method of an object • façade provides a simplified interface to a large body of code • flyweight reduces the cost of creating and manipulating a large number of similar objects • proxy provides a placeholder for another object to control access, reduce cost, and reduce complexity SOE: refactoring and patterns 28 GoF behavioral patterns: concerned with communication between objects • • • • • • • • • • • chain of responsibility delegates commands to a chain of processing objects command creates objects which encapsulate actions and parameters interpreter implements a specialized language iterator accesses the elements of an object sequentially without exposing its underlying representation mediator allows loose coupling between classes by being the only class that has detailed knowledge of their methods memento provides the ability to restore an object to its previous state (undo) observer is a publish/subscribe pattern which allows a number of observer objects to see an event state allows an object to alter its behavior when its internal state changes strategy allows one of a family of algorithms to be selected on-the-fly at runtime template method defines the skeleton of an algorithm as an abstract class, allowing its subclasses to provide concrete behavior visitor separates an algorithm from an object structure by moving the hierarchy of methods into one object SOE: refactoring and patterns 29 pattern use example Movie 1 charge() <<code>> return priceCode.charge() Price charge() ChildrensPrice1 charge() RegularPrice charge() 1 NewRelease 1 Price charge() state pattern singleton pattern SOE: refactoring and patterns 30 GRASP (General Responsibility Assignment Software Patterns) • • • • information expert: allocating responsibilities (methods, computed fields etc.) by determining which class has the most relevant data variables creator: determines which class should govern creation of new instances of classes in non-trivial situations. Given two classes (A,B), class B should be responsible for the creation of A if class B contains or compositely aggregates, records, closely uses or contains the initializing information for class A (see also factory) controller: assigns the responsibility of dealing with system events to a non-UI class that represents a use case scenario(s) - the first object beyond the UI layer that receives and coordinates a system operation. The controller should delegate to other objects the work that needs to be done low coupling: determines low dependency between classes, low impact in a class of changes in other classes and high reuse potential SOE: refactoring and patterns 31 GRASP 2 • • • • • high cohesion: the responsibilities of a given element are strongly related and highly focused polymorphism: responsibility for defining the variation of behaviors based on type is assigned to the types for which this variation happens pure fabrication: a class that does not represent a concept in the problem domain but is added to achieve low coupling, high cohesion, and the reuse potential thereof indirection: supports low coupling between two elements by assigning the responsibility of mediation between them to an intermediate object e.g. controller in MVC. protected variations: protects elements from variations on other elements by wrapping the focus of instability with an interface and using polymorphism to create various implementations of this interface. SOE: refactoring and patterns 32 architectural patterns “.....an architectural pattern expresses a fundamental structural organisation schema for software systems. It provides a set of predefined subsystems, specifies their responsibilities, and includes rules and guidelines for organizing the relationships between them” • from mud to structure • layers • pipes and filters • blackboard • distributed systems • broker • interactive systems • model-view-controller • presentation-abstractioncontrol • adaptable systems • microkernel • reflection BUSCHMAN, F., MEUNIER, R., ROHNERT, H., SOMMERLAD, P. & STAL, M. (1996) Patternoriented Software Architecture, Chichester, Wiley. SOE: refactoring and patterns 33 architectural patterns: from mud to structure layers pipes and filters example OSI model problem large system with high and low level functions requiring decomposition example problem process or transform a data stream structure layer j provides services used by j+1, delegates subtasks to j-1 structure known use TCP protocol, IS •filter: collects, transforms and outputs data supplied by pipe •pipe: transfers, buffers data and synchronizes with neighbours •data source: delivers data to pipe •data sink: consumes output known use UNIX program compilation and documentation creation presentation application logic domain layer database SOE: refactoring and patterns 34 architectural patterns: from mud to structure blackboard problem no feasible deterministic solution for transforming data into high level structures (diagrams, tables, language phrases) structure a collection of independent programs that work cooperatively on common data •blackboard: central data store •knowledge source: evaluates its own applicability, computes a result, updates blackboard known use speech and image recognition, vision, surveillance SOE: refactoring and patterns 35 architectural patterns: distributed systems broker problem manage distributed and possibly heterogeneous systems with independent operating components structure •client: implements user functionality •server: implements services •broker: locates, registers and communicates with servers, interoperates with other brokers through bridges •client side proxy: mediates between client and broker •server side proxy: mediates between server and broker •bridge: mediates between local broker and bridge of a remote broker known use CORBA, WWW SOE: refactoring and patterns 36 architectural patterns: interactive systems model-view-controller problem interactive systems with flexible and change prone user interface structure •model: provides central data and function logic •view: displays information to the user •controller: accepts inputs and makes service requests for the model, display requests for view known use Smalltalk systems SOE: refactoring and patterns 37 architectural patterns: interactive systems presentation-abstractioncontrol problem interactive systems as a set of cooperating agents structure tree hierarchy of PAC agents, with one top level agent – each agent has: •presentation: visible behaviour of the agent •abstraction: maintains data and provides core functionality •control: connect presentation and abstraction and communicate with other agents known use network traffic control SOE: refactoring and patterns 38 architectural patterns: adaptable systems microkernal problem application domains with broad spectrums of standards and programming technologies, continuous hardware and software evolution. Software should be portable, extensible, adaptable structure •microkernal: provides core services, manages resources and communication •internal server: implements additional services •external server: provides programming interfaces for clients •client: represents an application •adapter: hides system dependencies, invokes methods of external servers on behalf of clients known use Windows NT SOE: refactoring and patterns 39 architectural patterns: adaptable systems reflection problem systems exposed to changing technology and requirements, and support their own modification structure •base level: implements the application logic using information from meta level •meta level: encapsulates system internals that may change and provides interface to facilitate modifications to meta-level •metaobject protocol: interface for specifying and performing changes to meta level known use OLE 2.0 SOE: refactoring and patterns 40 potential benefits of patterns • • • • provides a common vocabulary and understanding of design elements for software designers increases productivity in design process due to design reuse promotes consistency and high quality of system designs and architectures due to application of tested design expertise and solutions embodied by patterns allows all levels of designers, from novice to expert, to gain these productivity, quality and consistency benefits SOE: refactoring and patterns 41 concerns • • • • benefits are dependent upon architects, analysts and designers understanding the patterns to be used – the common “design vocabulary” such training can be costly, and in many cases is proprietary and cannot be obtained externally specific funding and effort must be directed toward maintenance and evolution of patterns as reusable assets or they tend to devolve into project/application-specific artifacts with dramatically reduced reusability characteristics promotes design culture at the expense of analysis culture – less focus on responding adequately and accurately to specific user domains SOE: refactoring and patterns 42 patterns and refactoring work together: bottom up design refactoring to pattern development SOE: refactoring and patterns patterns through refactoring 43 design style, abstraction level architecture architectural patterns design as model agile GRASP refactoring design as code design patterns detailed design SOE: refactoring and patterns 44 traditional and agile design styles compared design assumptions traditional agile style top down bottom up starts with modelling programming process grand design up front evolutionary design responsible architect, designers programmers based upon user domain analysis models generic design patterns outcome design document program weakness separation of design and programming absence of early overview, unspecific user domain understandings SOE: refactoring and patterns 45