40
Software Design With UML, Design Patterns, Components and Application Frameworks Gerson Sunyé University of Nantes [email protected] http://sunye.free.fr 1

Software Design

Embed Size (px)

Citation preview

Software Design With UML, Design Patterns, Components

and Application FrameworksGerson Sunyé

University of [email protected]

http://sunye.free.fr

1

Gerson Sunyé — University of Nantes

Agenda

• Introduction

2

Introduction

3

Software Design

“Art and science of conceiving the structure of software systems.”

4

The Designer

“The designer is the one that simplifies, gives a strong and invisible personality to what he creates, prunes,

purifies, clutters, and creates suitable products.”

5

[Jasper Morrison]

Gerson Sunyé — University of Nantes

Two Approaches

• There are two ways of designing software:

• One way is to make it so simple that there are obviously no deficiencies

• and the other way is to make it so complicated that there are no obvious deficiencies.

• The first way is far more difficult to achieve.

• [C. A. R. Hoare]

6

Software

Software Model

RUP, XP, TDDMéthodes

J2EE, .NET, XML, Zope, Rails

Frameworks

Android, WebOS, iPhone, Symbian

Plate-formes

ISO, OMG, W3C, IEEE Normes

Apache, Mozilla, Sourceforge

Source libre

Corba, SOAP, Pair-à-Pair, Services Web

Middleware

Objets, Composants, Patterns, MDE

Techniques

SpécificationExigences

Modèle d’analyseDomaine

Réusabilité, performance, etc.

Contraintes de Qualité

SoftwareDesigner

7

Gerson Sunyé — University of Nantes

Different Steps

1. Architecture.

2. Component specification (preliminary design).

3. Detailed design.

8

Gerson Sunyé — University of Nantes

Architecture

• Strategic choices for system implementation.

• More engineering than computer science.

• Architectural patterns application.

9

Gerson Sunyé — University of Nantes

Components Specification

• High-level description of the collaboration between the system major components.

• System boundaries definition.

• Component desired behavior description.

10

Gerson Sunyé — University of Nantes

Detailed Design

• Component internal description.

• Preparation of the target programming language projection.

• Design pattern application.

11

Gerson Sunyé — University of Nantes

Other Design Aspects• User interface design.

• Protocol design.

• Database design.

• Algorithm design.

• etc.12

Design Process

Gerson Sunyé — University of Nantes

Design Process Steps1. Preliminary design

1. Requirements/Domain decomposition into components.

2. Detailed design

1. Component specification

2. Additional component decomposition, if needed.14

Gerson Sunyé — University of Nantes

Low-Level Steps1. List the hard decisions and decisions likely

to change

2. Design a component specification to hide each such decision

• Make decisions that apply to whole program family first

• Modularize most likely changes first

• Then modularize remaining difficult decisions and decisions likely to change

• Design the uses hierarchy as you do this (include reuse decisions)

3. Treat each higher-level component as a specification and apply above process to each

4. Continue refining until all design decisions:

• are hidden in a component

• contain easily comprehensible components

• provide individual, independent, low-level implementation assignments

15

Gerson Sunyé — University of Nantes

Best Practices• Separate interface from implementation.

• Separate orthogonal concerns: do not try to connect what is independent.

• The “what” before the “how”.

• First specify what a component should do, then how it does it.

• Work on different abstraction levels.

• Use rapid prototyping.

16

Gerson Sunyé — University of Nantes

Bad Practices• Depth-first design

• Requirement direct refinement.

• Potential changes misunderstanding.

• Design too detailed.

• Ambiguous design.

• Undocumented design decisions.

• Inconsistent design.

17

Keys Principles

18

Gerson Sunyé — University of Nantes

Design Principles1. Decomposition

2. Abstraction

3. Information concealment

4. Cohesion

5. Decoupling

6. Reusability

7. Reuse.

8. Obsolescence anticipation

9. Portability

10. Testability

11. Simplicity

12. SOLID principles

19

Gerson Sunyé — University of Nantes

Decomposition

• Complexity control by the decomposition of problems into sub-problems.

• Divide and conquer approach, common to all design techniques.

20

Gerson Sunyé — University of Nantes

Abstraction

• Complexity control by the amplification of the essential features and the suppression of the less important details.

• Allows to postpone design decisions.

• Types of abstraction: functional, structural, control, etc.

21

Gerson Sunyé — University of Nantes

Information Concealment

• Important means to achieve abstraction.

• Design decisions that are likely to change should be hidden behind interfaces.

• Components should communicate only through well-defined interfaces.

• Interface should be specified by as little information as possible.

• If component internal decisions change, clients should not be affected.

22

Gerson Sunyé — University of Nantes

Typical Information Concealment• Data representation

• Data types, etc.

• Algorithms

• Data search and sorting

• Input and output formats

• Machine dependencies, e.g., byte-ordering, character codes

• Lower-level interfaces

• Ordering of low-level operations

• Policy/Mechanism separation

• Multiple policies for one mechanism.

• Same policy for multiple mechanisms.

23

Gerson Sunyé — University of Nantes

Cohesion

• Cohesion should be increased where possible.

• Types of cohesion: functional, layer, de communicational, sequential, procedural, temporal, utility.

24

Gerson Sunyé — University of Nantes

Keeping Together• All the code that performs a particular task (functional cohesion).

• All the code that provides or uses a set of related services (layer cohesion).

• All code that access or modify certain data (communicational cohesion).

• A sequence of operations, in which one operation provides input to the next (sequential cohesion).

• A set of operations that are used one after another (procedural cohesion).

• Operations that are performed at the same execution phase (temporal cohesion).

• Operations which cannot logically be placed in other cohesive units (utility cohesion).

25

Decoupling

• Coping should be reduced where possible.

• Interdependencies impacts maintainability, testability, and simplicity.

LOCAL_NAMEARGUMENT_NAME

NAME

+ is_manifest_string : Boolean+ is_result : Boolean+ is_void : Boolean

TYPE_CLASS

(from TYPE)

GLOBALS

PROCEDURE

DEFERRED_ROUTINE

DEFERRED_PROCEDURE

WRITABLE_ATTRIBUTE

ONCE_ROUTINE

ONCE_PROCEDUREE_CHECK

E_RETRY

REVERSE_ASSIGNMENTROUTINE

CALL

ONCE_FUNCTION

FUNCTION

DEFERRED_FUNCTION

ATTRIBUTE

DECLARATION_LISTDECLARATION

+ count : Integer

EXPRESSION

CST_ATT

+value

PROC_CALLASSIGNMENT

TYPE

CREATION_CALL

+call

+type

DECLARATION_1DECLARATION_GROUP

RENAME_PAIR

(from InheritanceClause )

EXPORT_ITEM

(from InheritanceClause )

EXPRESSION

+left_side+right_side

+result_type

1+writable1

LOCAL_ARGUMENT

+name

+name_list

FORMAL_GENERIC_LIST

PARENT

(from InheritanceClause )

+rename_list+export_list

CALL_PROC_CALL

1

+target

1

0..*

+arguments

0..*

FEATURE_NAME_LIST

+undefine _list

+redefine_list

+select_list

TYPE

+result_type

CLASS_NAME

SMALLEIFFEL

+ magic_count : Integer+ is_ready : Boolean

+ load_class()+ get_started()+ falling_down()+ afd_check()

PARENT_LIST

(from InheritanceClause )

FEATURE_NAME

+ is_frozen : Boolean

CLASS_NAME

+to_runnable

FEATURE_CLAUSE_LIST

CREATION_CLAUSE_LIST

CLIENT_LIST

+list

BASE_CLASS

+ path : String+ is_deferred : Boolean+ is_expanded : Boolean/+ is_generic : Boolean+ is_any : Boolean = initval+ is_general : Boolean

+base_class

+base_class_dictionary

+base_class

+parent_list

+base_class

+origin_base_class

+base_class

+name+feature_clause_list

+creation_clause_list

FORMAL_ARG_LIST

TYPE

FEATURE_CLAUSE

+clients

+list

CREATION_CLAUSE

+list

E_FEATURE

+ is_deferred : Boolean = initval

+clients

+base_class

+arguments

+result_type

+list

FEATURE_NAME_LIST

+procedure_list

+names

FEATURE_NAME

INFIX_NAMEPREFIX_NAMEFROZEN_FEATURE_NAME

WHEN_ITEM_1WHEN_ITEM_2

LOCAL_VAR_LIST

INSTRUCTION

E_LOOP

IFTHENELSEIFTHEN

E_DEBUG

EFFECTIVE_ROUTINE

+local_ vars

COMPOUND

0..*0..*

+loop_body

+initialize

+else_compound

+then_compound

+routine_body

+rescue_compound

WHEN_ITEMWHEN_LIST

E_INSPECT

+else_compound

E_WHEN +list+list

SIMPLE_FEATURE_NAME

EXPRESSION

EXTERNAL_FUNCTIONEXTERNAL_PROCEDURE

NATIVE

+ language_name : StringEXTERNAL_ROUTINE+native

NATIVE_C NATIVE_SMALL_EIFFELNATIVE_JVM

TYPE_GENERIC

(from TYPE)

FORMAL_GENERIC_ARG

+ constrained : boolean+ rank : Integer

+list

TYPE_FORMAL_GENERIC

(from TYPE)

+formal_generic_list

TYPE

/ path : String

+generic_list

+constraint

+formal_generic_list

+current_type

TYPE_ANY

TYPE_CHARACTER

TYPE_POINTER TYPE_NONE

1 2

10

3

4 85 6 7 911

12

20

1314

15 16 17 18 19

21 22 23 24

25 26

27

28 29 30

60

31

51

32

3334

35

36

37 3839

40

41 4243 44

45

46 47 48 49 50

52

5354 55

5657

58

59 6162

63

6465

66 67

68 69 70

71

72 7374 75 76 77

78

7980

81

82

83 84

85

86 87 88

GNU Eiffel Compiler

Gerson Sunyé — University of Nantes

Types of Coupling• Content: when a class (module) modifies the content of another class. Violates encapsulation, Law of

Demeter.

• Common: when classes share global variables.

• Control: when a parameter controls the behavior of an operation.

• Stamp: when a class of a component becomes the parameter type of another component.

• Data: when parameter types are primitive types.

• Operation call: when an operation calls another.

• Datatype use: when a component uses a datatype defined in another component.

• Merge or import: when a component includes another (merge) or when a class imports another.

• External: when a component depends on external artifacts: operating system, hardware, libraries, etc.

27

Gerson Sunyé — University of Nantes

Reducing Coupling

• Dependencies among component should form a directed acyclic graph.

• Dependency between two components must follow the direction of stability (a component must always depend on a more stable one).

28

Gerson Sunyé — University of Nantes

Reusability• Reusability should be increased where possible.

• Components should be designed to work on different contexts.

• Generalize design as much as possible:

• Use Frameworks, Patterns, and UML Collaborations.

• Design the system to contain hooks.

• Keep the design as simple as possible

29

Gerson Sunyé — University of Nantes

Reuse Analysis, Design, and Code

• Reuse existing artifacts when possible, to take advantage of existing investment.

• Use Frameworks, Patterns, and UML Collaborations.

• Complementary to the principle of reusability.

30

Gerson Sunyé — University of Nantes

Obsolescence Anticipation

• Avoid:

• Immature technologies.

• Undocumented features.

• Software and Hardware without long-term support provision.

• Plan technology changes and adopt technologies that are supported by different vendors.

31

Gerson Sunyé — University of Nantes

Portability

• Develop on and for different platforms.

• Avoid platform-specific frameworks or libraries.

32

Gerson Sunyé — University of Nantes

Testability

• The internal state of a component should be accessible by external programs.

• Design components to be used directly by external clients, without user interfaces.

33

Gerson Sunyé — University of Nantes

Simplicity• The KISS principle [US Navy, 1960] :

• Keep it simple, stupid!

• Most systems work best if they are kept simple rather than made complicated

• Simplicity should be a key goal in design and unnecessary complexity should be avoided.

34

Gerson Sunyé — University of Nantes

SOLID• Single responsibility [Robert Martin]:

• a class should have only a single responsibility (i.e. only one potential change in the software's specification should be able to affect the specification of the class).

• Open/Closed principle [Bertrand Meyer]:

• Software entities should be open for extensions but closed for modification.

35

Gerson Sunyé — University of Nantes

SOLID• Leskov substitution principle [Liskov 1994]:

• Class instances can be used throughout the superclass interface, without notifying its clients.

• Interface-segregation [Robert Martin 2002]:

• Many client-specific interfaces are better than one general-purpose interface.

• Dependency inversion [Robert Martin 2003]:

• A client should depend upon abstractions and not upon concretions.

36

Conclusion

37

Gerson Sunyé — University of Nantes

Conclusion

• Design is a creative activity that goes beyond diagrams drawing.

• A good design requires experience.

38

Gerson Sunyé — University of Nantes

Références• Real-Time UML: Developing Efficient Objects for

Embedded Systems. Bruce Powel Douglass

• Real-Time Design Patterns: Robust Scalable Architecture for Real-Time Systems. Bruce Powel Douglass

• Software Patterns. James Coplien. SIGS Books. New York, 1996.

39

• Smalltalk Patterns: Best Practices. Kent Beck. Prentice Hall, 1997, 256 pp., ISBN 0-13-476904-X

• Design Patterns: Elements of Reusable Object-Oriented Software. Erich Gamma, Richard Helm,Ralph Johnson, and John Vlissides. Addison Wesley. October 1994.

• Mohamed E. Fayad, Douglas C. Schmidt, Ralph Johnson (September 2009). Implementing Application Frameworks: Object-Oriented Frameworks at Work.

40