Title: M'Sc Computing Science Software Engineering Lecture 7
1M.Sc Computing Science Software Engineering
Lecture 7
- Niki Trigoni
- Department of Computer Science
- and Information Systems
- Birkbeck College, University of London
- Email niki_at_dcs.bbk.ac.uk
- Web Page http//www.dcs.bbk.ac.uk/niki
2Overview of lecture 6
- From Requirements to Design using GRASP patterns
Contract C01 makeNewSale Operation
makeNewSale () Cross References Use Cases
Process Sale Preconditions none Postconditions
- A Sale instance s was created - s was
associated with the Register - Attributes of
s were initialized
Register
makeNewSale()
create()
Sale
create()
Sales LineItem
3Overview of lecture 6
- From Design to Implementation Model
- How to derive class definitions from DCDs
- How to define method bodies from interaction
diagrams
SalesLineItem quantityInteger getSubtotal()Mon
ey
ProductSpec descriptionText priceMoney itemIDIt
emID
Described-by
1
productSpec
public class SalesLineItem private int
quantity private ProductSpec productSpec publi
c SalesLineItem(ProductSpec spec, int qty)
public Money getSubtotal()
4Overview of lecture 6
- From Design to Implementation Model
- How to derive class definitions from DCDs
- How to define method bodies from interaction
diagrams
enterItem(id,qty)
2makeLineItem(spec,qty)
Register
Sale
1specgetSpecification(id)
Product Catalog
public void enterItem (ItemID id, int
qty) ProductSpec spec catalog.getSpecificatio
n(id) sale.makeLineItem (spec, qty)
5Orientation within the Unified Process
quick overview
focus of this lecture
6Overview of lecture 7
- Iteration 2 of Elaboration and its requirements
- More GRASP patterns for assigning
responsibilities - Polymorphism
- Pure Fabrication
- Indirection
- Protected Variations
- GoF (Gang-of-Four) design patterns
- Gamma, Helm, Johnson, Vlissides, 1995
- Adapter
- Factory
- Singleton
7Requirements handled in 2nd iteration
- Additional requirements will be considered for
design - Support for variations in third-party external
services - Complex pricing rules
- Pluggable business rules
- GUI window updates when information changes
- These points concern the same use case scenario,
but address mostly non-functional requirements - These requirements have a minor impact on the
Domain Model - Other requirements could have potentially been
selected for design, e.g. different use case
scenarios, or different use cases
8Moving to design the GRASP patterns
- Information Expert responsibilities should be
assigned to objects that contain relevant
information - Creator the creator of an object is usually an
object that contains, or aggregates it - High Cohesion responsibilities of a certain
class must be highly related - Low Coupling interdependency between classes
should remain low - Controller class which handles external system
events - Polymorphism ???
- Indirection ???
- Pure Fabrication ???
- Protected Variations ???
9Polymorphism
Problem How to handle alternative behaviors
based on type? How to create pluggable software
components? Solution When related alternatives
or behaviors vary by type (class), dont use
conditional logic, but assign the same name to
services (methods) in different classes. The
different classes usually implement a common
interface or are related in an implementation
hierarchy with a common superclass (this is
language-dependent)
10Polymorphism example
ltltinterfacegtgt ITaxCalculator getTaxes(Sale)List
of TaxLineItems
TaxMaster getTaxes(Sale)List of TaxLineItems
GoodAsGoldTaxPro getTaxes(Sale)List of
TaxLineItems
Adding a new tax calculator class with its own
polymorphic getTaxes method will have minor
impact on the existing design.
11Pure Fabrication
Problem What objects should have the
responsibility, when you do not want to violate
High Cohesion and Low Coupling, or other goals,
but solutions offered by Expert (for example) are
not appropriate? Solution Assign a highly
cohesive set of responsibilities to an artificial
or convenience class that does not represent a
problem domain concept something made up to
support high cohesion, low coupling, and reuse.
12Pure Fabrication example
- Where to assign the responsibility to save a Sale
object? - Even though the Sale is a logical candidate to
save itself in the database (by virtue of
Information Expert), it leads to a design with
low cohesion (why?) and low reuse potential
(why?) - Solution Fabricate a new class PersistentStorage
with the purpose of managing objects in
persistent storage medium
PersistentStorage insert(Object) update(Object)
13Pure Fabrication discussion
- Distinction between representational and
behavioral decomposition of the design model - Creation of Sale is by representational
decomposition - Creation of PersistStorage is by behavioral
decomposition - (convenience class conceived by the developer to
group together related functions) - Dont overuse behavioral decomposition into Pure
Fabrication objects! - Risk to move from OO design to functional design
14Indirection
Problem Where to assign a responsibility to
avoid direct coupling between two or more
objects? How to de-couple objects so that reuse
potential remains higher? Solution Assign the
responsibility to an intermediate object to
mediate between other components or services so
that they are not directly coupled.
15Indirection examples
- Introduce a PersistestStorage class in order to
decouple the Sale from the relational database
services - Introduce a TaxAdapter class in order to decouple
the Sale from an external (potentially remote)
tax-calculating class
16Indirection discussion
- How does indirection reduce coupling?
- How is indirection related to polymorphism?
-
- How is indirection related to pure fabrication?
17Protected Variations
Problem How to design objects, systems and
subsystems so that the variations and instability
in these elements does not have an undesirable
impact on other elements? Solution Identify
points of predicted variation or instability
assign responsibilities so that you create a
stable interface around them.
18Protected Variations examples
- The previous example of different tax calculators
and the use of Polymorphism illustrate Protected
variation - Protected Variations is a root principle that
motivates most of the mechanisms and patterns in
design and programming - Examples of Protected Variations mechanisms
- Core (polymorphism, indirection, standards)
- Data-driven designs (metadata for db integration,
reading of class names from external files) - Stable interface of look-up services
- Interpreter-driven designs (query interpreter,
VMs) - Reflective designs
- Structure-hiding designs
19Protected Variations discussion
- Two points of change are worth defining
- Variation point variations in the existing
current system or requirements - Evolution point speculative types of variation
that may arise in the future, but which are not
present in the existing requirements
20Overview of lecture 7
- Iteration 2 of Elaboration and its requirements
- More GRASP patterns for assigning
responsibilities - Polymorphism
- Pure Fabrication
- Indirection
- Protected Variations
- GoF (Gang-of-Four) design patterns
- Adapter
- Factory and Singleton
- Strategy
- Facade
- Observer/Publish-Subscribe/Delegation Event Model
21Adapter (GoF)
Problem How to resolve incompatible interfaces,
or provide a stable interface to similar
components with different interfaces? Solution
Convert the original interface of a component
into another interface through an intermediate
adapter object
22Adapter (GoF) example
ltltinterfacegtgt ITaxCalculatorAdapter getTaxes(Sale
)List of TaxLineItems
TaxMasterAdapter getTaxes(Sale)List of
TaxLineItems
GoodAsGoldTaxProAdapter getTaxes(Sale)List of
TaxLineItems
Within the getTaxes method of TaxMasterAdapter,
a method XXX of an external TaxMaster object is
invoked.
23Factory (GoF)
Problem Who should be responsible for creating
objects when there are special considerations,
such as complex creation logic, a desire to
separate the creation responsibilities for better
cohesion, or need to allow efficient memory
management of created objects? Solution
Construct a pure fabrication called Factory that
handles the creation.
24Factory (GoF) example
ServicesFactory accountingAdapter
IAccountingAdapter inventoryAdapter
IInventoryAdapter taxCalculatorAdapter
ITaxCalculatorAdapter getAccountingAdapter()
IAccountingAdapter getInventoryAdapter()
IInventoryAdapter getTaxCalculatorAdapter()
ITaxCalculatorAdapter
If (taxCalculatorAdapternull) String
className // read className from
input taxCalculatorAdapter (ITaxCalculatorAdap
ter) Class.forName(className).newInstance()
return taxCalculatorAdapter
25Singleton (GoF)
Problem Who creates the factory itself and how
is it accessed? In general, when a single
instance of a class X is usually needed, but it
is called from many places in the code, how do we
create it and make it visible? Solution Define
a static method getInstance that itself provides
a single instance of X.
26Singleton (GoF) example
ServicesFactory instanceServicesFactory accounti
ngAdapter IAccountingAdapter inventoryAdapter
IInventoryAdapter taxCalculatorAdapter
ITaxCalculatorAdapter getInstance
ServicesFactory() getAccountingAdapter()
IAccountingAdapter getInventoryAdapter()
IInventoryAdapter getTaxCalculatorAdapter()
ITaxCalculatorAdapter
public static synchronized ServicesFactory
getInstance() if (instancenull) instance
newServicesFactory() return instance
27Summary of lecture 7
- In the 2nd iteration of elaboration, we
identified an additional set of requirements for
the use case ProcessSale, and moved directly to
the design (omitting the domain model). - Motivated by these requirements, we discussed
several patterns that guide our design decisions. - The overall goal is easy development and easy
maintenance. Most of the suggested patterns aim
to satisfy three necessary conditions - objects are simple to understand
- objects are reusable
- requirement changes have a local impact on
software changes