Component-Level Design Minsoo Ryu Hanyang University
Contents 1. Design Model 2. Fundamental Design Concepts 3. Component-Level Design 4. Object-Oriented Design Techniques 2 2
Data/class design Four Design Models Transforms analysis models into design realizations and the requisite data structures required to implement the software Architectural design Defines the relationship between major structural elements of the software Interfaces design Describes how the software communicates with systems that interoperate within it, and with humans who use it Component-level design Transforms structural elements of the software architecture into a procedural description of software components 3 3
Three Design Quality Characteristics The design must implement all of the explicit requirements contained in the analysis model, and it must accommodate all of the implicit requirements desired by the customer The design must be a readable, understandable guide for those who generate code and for those who test and subsequently support the software The design should provide a complete picture of the software, addressing the data, functional, and behavioral domains from an implementation perspective 4 4
Contents 1. Design Model 2. Fundamental Design Concepts 3. Component-Level Design 4. Object-Oriented Design Techniques 5 5
Fundamental Design Concepts Abstraction Modularity Information Hiding Functional independence Refinement Refactoring Architecture and Patterns 6 6
Abstraction Abstraction is one of the fundamental ways that we as humans cope with complexity, by Grady Booch Two types of abstraction Data abstraction Procedural abstraction 7 7
Data Abstraction door manufacturer model number type swing direction inserts lights type number weight opening mechanism implemented as a data structure 8 8
Procedural Abstraction open details of enter algorithm implemented with a "knowledge" of the object that is associated with enter 9 9
Modularity Modularity is the single attribute of software that allows a program to be intellectually manageable, by G. Meyers Software can be divided into separately named and addressable components, often called modules, that are integrated to satisfy problem requirements Consider two problems, p1 and p2 If the perceived complexity of two problems when they are combined is often greater than the sum of the perceived complexity when each is taken separately This leads to a divide and conquer strategy 10 10
Modularity What is the "right" number of modules for a specific software design? cost of software module development cost module integration cost optimal number of modules number of modules 11 11
Information Hiding Modules should be specified and designed so that information (algorithms and data) contained within a module is inaccessible to other modules that have no need for such information Hiding implies that effective modularity can be achieved by defining a set of independent modules that communicate with one another only that information necessary to achieve software function Abstraction helps to define the procedural (or informational) entities that make up the software 12 12
Information Hiding clients module controlled interface "secret" algorithm data structure details of external interface resource allocation policy a specific design decision 13 13
Functional Independence The functional independence is a direct outgrowth of modularity and the concepts of abstraction and information hiding Independent modules are easier to maintain (and test) because secondary effects caused by design or code modification are limited, error propagation is reduced, and reusable modules are possible 14 14
Functional Independence Independence is assessed using two criteria Cohesion is an indication of the relative functional strength of a module A cohesive module consists of parts that fit together well and form a united whole A cohesive module should (ideally) do just one thing Coupling is an indication of the relative interdependence among modules 15 15
Cohesion Cohesion implies that a component or class encapsulates only attributes and operations that are closely related to one another and to the class or component itself Functional (exhibited primarily by operations) This type of cohesion occurs when a module performs one and only one computation Communicational All operations that access the same data are defined within one class Temporal Operations that are performed to reflect a specific behavior or state, e.g., an operation performed at start-up or all operations performed when an error is detected 16 16
Coupling Coupling is a qualitative measure of the degree to which classes are connected to one another As classes become more interdependent, coupling increases An important objective in component-level design is to keep coupling as low as possible Content coupling Occurs when one component modifies data that is internal to another component (This violates information hiding) Common coupling Occurs when a number of components all make use of a global variable Although this sometimes necessary, common coupling can lead to uncontrolled error propagation and unforeseen side effects when changes are made Control coupling Occurs when operation A() invokes operation B() and passes a control flag to B 17 17
Refinement Step-wise refinement is a top-down design strategy, by Niklaus Wirth Abstraction and refinement are complementary concepts Abstraction enables a designer to specify procedure and data and yet suppress low-level details Refinement helps the designer to reveal low-level details as design progresses 18 18
Stepwise Refinement open walk to door; reach for knob; open door; walk through; close door. repeat until door opens turn knob clockwise; if knob doesn't turn, then take key out; find correct key; insert in lock; endif pull/push door move out of way; end repeat 19 19
Refactoring "Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code [design] yet improves its internal structure, by Fowler When software is refactored, the existing design is examined for redundancy unused design elements inefficient or unnecessary algorithms poorly constructed or inappropriate data structures or any other design failure that can be corrected to yield a better design 20 20
Contents 1. Design Model 2. Fundamental Design Concepts 3. Component-Level Design 4. Object-Oriented Design Techniques 21 21
Component-Level Design Component-level design occurs after the first iteration of architectural design has been completed At this stage, the overall data and program structure of the software has been established The intent is to define the data structures, algorithms, interface characteristics, and communication mechanisms allocated to each software component 22 22
What is a Component? A component is a modular building block for computer software OMG Unified Modeling Language Specification defines a component as a modular, deployable, and replaceable part of a system that encapsulates implementation and exposes a set of interfaces The true meaning of the term component will differ depending on the point of view of the software engineer who use it 23 23
The Conventional View of Component-Level Design A component is a functional element of a program that incorporates processing logic, the internal data structures that are required to implement the processing logic, and an interface that enables the component to be invoked and data to be passed to it A conventional component is also called a module Three roles A control component that coordinates the invocation of all other problem domain components A problem domain component that implements a complete or partial function that is required by the customer An infrastructure component that is responsible for functions that support the processing required in the problem domain 24 24
Conducting Component-Level Design 1. Identify all design components problem domain infrastructure domain 2. Elaborate all design components communications, interfaces, data structures, operations 3. Describe persistent data sources and identify relevant components databases and/or files required components 4. Develop and elaborate behavioral representations data-flow models or state machine models 5. Elaborate deployment specific HW/SW environments locations of components 25 25
Step 1: Identify All Design Components Step 1.1 Identify design components from the problem domain Use architectural components and refine them Step 1.2 Identify design components from the infrastructure domain GUI-related components, OS-related components, etc 26 26
Step 2: Elaborate Design Components Apply the design concepts and techniques we have learned Step 2.1 Specify messages that are passed between design components (message name, content, and properties) Step 2.2 Identify interfaces for each component (interface name and properties) Step 2.3 Identify data structures and data types (variables and complex data structures) Step 2.4 Describe processing flow within each operation (flow chart or UML activity diagram) Specify the parameters and their types for each operation 27 27
Communications and Messages :ProductionJob 1: buildjob ( WOnumber ) 2: submitjob ( WOnumber ) :WorkOrder :JobQueue 28 28
Interfaces computejob Print Jo b initiatejob WorkOrder getjobdescriiption appropriate attributes buildworkorder () buildjob <<interface>> initiatejob Pro d uct io njo b passjobtoproduction() JobQueue submitjob appropriate attributes checkpriority () 29 29
Processing Flow validate attributes input accesspaperdb(weight) returns basecostperpage papercostperpage = basecostperpage size = B papercostperpage = papercostperpage * 1.2 size = C papercostperpage = papercostperpage * 1.4 size = D papercostperpage = papercostperpage * 1.6 color is custom papercostperpage = papercostperpage * 1.1 4 color is standard returns ( papercostperpage ) 30 30
Step 3: Describe Persistent Data Sources and Identify Relevant Components In most cases, persistent data stores are initially specified as part of architectural design Step 3.1 Provide additional detail about the structure and organization of the persistent data stores Step 3.2 Identify design components that are required to manage them 31 31
Step 4: Develop and Elaborate Behavioral Representations In many cases, state machine models are used to represent the behavior of entire system and/or of certain component Step 4.1 Identify and draw states, events, transitions, and actions for the overall system Step 4.2 Identify and draw states, events, transitions, and actions for individual component 32 32
Statechart Diagram behavior within the state buildingjobdata datainputincomplete buildingjobdat a ent ry/ readjobdat a () exit / displayjobdat a () do/ checkconsist ency() include/ dat ainput datainputcompleted [all data items consistent]/displayuseroptions comput ingjobcost ent ry/ comput ejob exit / save t ot aljobcost jobcostaccepted [customer is authorized]/ getelectronicsignature formingjob entry/ buildjob exit / save WOnumber do/ submittingjob entry/ submitjob exit / init iat ejob do/ place on JobQueue jobsubmitted[ all au t h o rizat io n s acq u ired ] / printworkorder 33 33
Step 5: Elaborate Deployment In many cases, state machine models are used to represent the behavior of entire system and/or of certain component Step 5.1 Identify the computing environment that will house design components Step 5.2 Specify the location of each component Step 5.3 Describe specific hardware and/or software environments 34 34
Contents 1. Design Model 2. Fundamental Design Concepts 3. Component-Level Design 4. Object-Oriented Design Techniques 35 35
Object-Oriented Design When an object-oriented approach is chosen, component-level design focuses on the elaboration of; analysis classes (problem domain classes) the definition and refinement of infrastructure classes 36 36
Basic Design Principles Four basic design principles are applicable to OO component-level design The Open-Closed Principle (OCP) The Liskov Substitution Principle (LSP) Dependency Inversion Principle (DIP) The Interface Segregation Principle (ISP) The underlying motivation is To create designs that are more amenable to change To reduce the propagation 37 37
The Open-Closed Principle (OCP) A module should be open for extension but closed for modification The designer should specify the component in a way that allows it to be extended without the need to make internal modifications to the component itself To accomplish this, the designer creates abstractions that serve as a buffer between the functionality that is likely to be extended and the design class itself Design and write a module in a fashion that adding new functionality would involve minimal changes to existing code 38 38
Example of OCP Violation 39 39
A Possible Solution The key mechanisms for OCP are abstraction (inheritance) and polymorphism! * Polymorphism in OO allows the exact behavior to be determined at run-time (late binding) 40 40
The Liskov Substitution Principle (LSP) Subclasses should be substituable for their base classes If S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program Also known as Design by Contract A "client" and a "supplier" agree on a "contract The Liskov Substitution Principle is an important feature of all programs that conform to the Open- Closed Principle It is only when inheriting classes should not perform any actions that will invalidate the assumptions made by the base class 41 41
Example of LSP Violation Rectangle Square Assertion error! The area of rectangle would be 16 42 42
Is a Square a Rectangle? To understand the subtleties of extendable class design, we must address the question "Is a Square a specialization of a Rectangle?" At first glance this seems valid since mathematically a square IS A rectangle However, this class hierarchy fails to adhere to the Liskov Substitution principle because the behavior of a Square differs from the behavior of a Rectangle The subclass may only expand the behavior of the base class How to fix this problem? Square and Rectangle both inherit from Shape, or Square s Set_Width should not alter the height The base class is the abstraction of subclass, hence, the subclass should not change the abstract behavior of the base class 43 43
LSP and Design by Contract...when redefining a routine [in a derivative], you may only replace its precondition by a weaker one, and its postcondition by a stronger one In other words, when using an object through its base class interface, the user knows only the preconditions and postconditions of the base class Thus, derived objects must not expect such users to obey preconditions that are stronger then those required by the base class That is, they must accept anything that the base class could accept 44 44
Dependency Inversion Principle (DIP) Depend on abstractions. Do not depend on concretions High level modules should not depend upon low level modules Both should depend upon abstractions Abstractions should not depend upon details Details should depend upon abstractions 45 45
Example of DIP The Copy module calls the other two in a loop The body of that loop calls the Read Keyboard module to fetch a character from the keyboard, it then sends that character to the Write Printer module which prints the character The two low level modules are nicely reusable However the Copy module is not reusable in any context which does not involve a keyboard or a printer 46 46
Example of DIP Consider a new program that copies to a disk file We could add an if statement to its policy and have it select between the Write Printer module and the Write Disk module depending upon some kind of flag Consider the implications of high level modules that depend upon low level modules Yet, when these modules depend upon the lower level modules, then changes to the lower level modules can have direct effects upon them; and can force them to change Moreover, it is high level modules that we want to be able to reuse 47 47
A Possible Solution The dependency structure of a well designed object oriented program is inverted with respect to the dependency structure that normally results from traditional procedural methods A solution is to have a Copy class which contains an abstract Reader class and an abstract Writer class 48 48
The Interface Segregation Principle (ISP) Clients should not be forced to depend upon interfaces that they do not use This principle deals with the disadvantages of fat interfaces Classes that have fat interfaces are classes whose interfaces are not cohesive In other words, the interfaces of the class can be broken up into groups of member functions Each group serves a different set of clients Thus some clients use one group of member functions, and other clients use the other groups 49 49
Example of ISP Violation 50 50
A Possible Solution 51 51