What is component design



Yüklə 1,9 Mb.
tarix08.08.2018
ölçüsü1,9 Mb.
#61185



What is component design

  • What is component design

  • Basic design principles

  • Modularity and Information hiding

  • Component design process



OMG Unified Modeling Language Specification [OMG01] defines a component as

  • OMG Unified Modeling Language Specification [OMG01] defines a component as

    • “… a modular, deployable, and replaceable part of a system that encapsulates implementation and exposes a set of interfaces.”
  • OO view: a component contains a set of collaborating classes

  • Conventional view: 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.







Class Design Principles

  • Class Design Principles

  • Package Design Principles

  • Package Coupling Principles



Single Responsibility Principle (SRP)

  • Single Responsibility Principle (SRP)

  • Open/Closed Principle (OCP)

  • Liskov Substitution Principle (LSP)

    • a.k.a. Design by Contract
  • Dependency Inversion Principle (DIP)

  • Interface Segregation Principle (ISP)







Class should have only one reason to change

  • Class should have only one reason to change

    • Cohesion of its functions/responsibilities
  • Several responsibilities

    • mean several reasons for changes → more frequent changes
  • Sounds simple enough

    • Not so easy in real life
    • Tradeoffs with complexity, repetition, opacity
















Multipurpose classes

  • Multipurpose classes

    • Methods fall in different groups
    • Not all users use all methods
  • Can lead to unwanted dependencies

    • Clients using one aspect of a class also depend indirectly on the dependencies of the other aspects
  • ISP helps to solve the problem

    • Use several client-specific interfaces




Reuse-Release Equivalency Principle

  • Reuse-Release Equivalency Principle

  • Common Closure Principle

  • Common Reuse Principle





Group components (classes) for reusers

  • Group components (classes) for reusers

  • Single classes are usually not reuseable

  • Classes in a package should form a reuseable and releaseable module

    • Module provides coherent functionality
    • Dependencies on other packages controlled
    • Requirements on other packages specified
  • Reduces work for the reuser





Group classes with similar closure together

  • Group classes with similar closure together

    • package closed for anticipated changes
  • Confines changes to a few packages

  • Reduces package release frequency

  • Reduces work for the programmer





Group classes according to common reuse

  • Group classes according to common reuse

    • avoid unneccessary dependencies for users
  • Following the CRP often leads to splitting packages

    • Get more, smaller and more focused packages
  • Reduces work for the reuser



Acyclic Dependencies principles

  • Acyclic Dependencies principles

  • Stable Dependencies principles

  • Stable Abstractions principles













Organise package dependencies in the direction of stability

  • Organise package dependencies in the direction of stability

  • Dependence on stable packages corresponds to DIP for classes

    • Classes should depend upon (stable) abstractions or interfaces
    • These can be stable (hard to change)




Computer systems are not monolithic:

  • Computer systems are not monolithic:

    • they are usually composed of multiple, interacting modules.
  • Modularity has long been seen as a key to cheap, high quality software.

  • The goal of system design is to decide:

    • – what the modules are;
    • – what the modules should be;
    • – how the modules interact with one-another.


Common view: a piece of code. Too limited.

  • Common view: a piece of code. Too limited.

  • Compilation unit, including related declarations and interface

  • David Parnas: a unit of work.

  • Collection of programming units (procedures, classes, etc.)

    • with a well-defined interface and purpose within the entire system,
    • that can be independently assigned to a developer


Management: Partition the overall development effort

  • Management: Partition the overall development effort

    • – Divide and conquer
  • Evolution: Decouple parts of a system so that changes to one part are isolated from changes to other parts

    • Principle of directness (clear allocation of requirements to modules, ideally one requirement (or more) maps to one module)
    • – Principle of continuity/locality (small change in requirements triggers a change to one module only)
  • Understanding: Permit system to be understood

    • as composition of mind-sized chunks, e.g., the 7±2 Rule
    • with one issue at a time, e.g., principles of locality, encapsulation, separation of concerns
  • Key issue: what criteria to use for modularization?



Hide secrets. OK, what’s a “secret”?

  • Hide secrets. OK, what’s a “secret”?

    • Representation of data
    • Properties of a device, other than required properties
    • Implementation of world models
    • Mechanisms that support policies
  • Try to localize future change

    • Hide system details likely to change independently
    • Separate parts that are likely to have a different rate of change
    • Expose in interfaces assumptions unlikely to change




Interface as a contract - whatever is published by a module that

  • Interface as a contract - whatever is published by a module that

  • Syntactic interfaces

    • How to call operations
      • List of operation signatures
      • Sometimes also valid orders of calling operations
  • Semantic interfaces

    • What the operations do, e.g.,
      • Pre- and post-conditions
      • Use cases


Explicit interfaces

  • Explicit interfaces

    • Make all dependencies between modules explicit (no hidden coupling)
  • Low coupling - few interfaces

    • Minimize the amount of dependencies between modules
  • Small interfaces

    • Keep the interfaces narrow
      • Combine many parameters into structs/objects
      • Divide large interfaces into several interfaces
  • High cohesion

    • A module should encapsulate some well-defined, coherent piece of functionality (more on that later)


Cohesion is a measure of the coherence of a module amongst the pieces of that module.

  • Cohesion is a measure of the coherence of a module amongst the pieces of that module.

  • Coupling is the degree of interaction between modules.

  • You want high cohesion and low coupling.





The result of randomly breaking the project into modules to gain the benefits of having multiple smaller files/modules to work on

  • The result of randomly breaking the project into modules to gain the benefits of having multiple smaller files/modules to work on

    • Inflexible enforcement of rules such as: “every function/module shall be between 40 and 80 lines in length” can result in coincidental coherence
  • Usually worse than no modularization

    • Confuses the reader that may infer dependencies that are not there


A “template” implementation of a number of quite different operations that share some basic course of action

  • A “template” implementation of a number of quite different operations that share some basic course of action

    • variation is achieved through parameters
    • “logic” - here: the internal workings of a module
  • Problems:

    • Results in hard to understand modules with complicated logic
    • Undesirable coupling between operations
  • Usually should be refactored to separate the different operations





Temporal cohesion concerns a module organized to contain all those operations which occur at a similar point in time.

  • Temporal cohesion concerns a module organized to contain all those operations which occur at a similar point in time.

  • Consider a product performing the following major steps:

  • Temporal cohesion would lead to five modules named initialize, input, calculate, output and cleanup.

  • This division will most probably lead to code duplication across the modules, e.g.,

    • Each module may have code that manipulates one of the major data structures used in the program.


A module has procedural cohesion if all the operations it performs are related to a sequence of steps performed in the program.

  • A module has procedural cohesion if all the operations it performs are related to a sequence of steps performed in the program.

  • For example, if one of the sequence of operations in the program was “read input from the keyboard, validate it, and store the answers in global variables”, that would be procedural cohesion.

  • Procedural cohesion is essentially temporal cohesion with the added restriction that all the parts of the module correspond to a related action sequence in the program.

  • It also leads to code duplication in a similar way.





Communicational cohesion occurs when a module performs operations related to a sequence of steps performed in the program (see procedural cohesion) AND all the actions performed by the module are performed on the same data.

  • Communicational cohesion occurs when a module performs operations related to a sequence of steps performed in the program (see procedural cohesion) AND all the actions performed by the module are performed on the same data.

  • Communicational cohesion is an improvement on procedural cohesion because all the operations are performed on the same data.



Module with functional cohesion focuses on exactly one goal or “function”

  • Module with functional cohesion focuses on exactly one goal or “function”

    • (In the sense of purpose, not a programming language “function”).
  • Module performing a well-defined operation is more reusable, e.g.,

    • Modules such as: read_file, or draw_graph are more likely to be applicable to another project than one called initialize_data.
  • Another advantage of is fault isolation, e.g.,

    • If the data is not being read from the file correctly, there is a good chance the error lies in the read_file module/function.


Informational cohesion describes a module as performing a number of actions, each with a unique entry point, independent code for each action, and all operations are performed on the same data.

  • Informational cohesion describes a module as performing a number of actions, each with a unique entry point, independent code for each action, and all operations are performed on the same data.

    • In informational cohesion, each function in a module can perform exactly one action.
  • It corresponds to the definition of an ADT (abstract data type) or object in an object-oriented language.

  • Thus, the object-oriented approach naturally produces designs with informational cohesion.

  • Each object is generally defined in its own source file/module, and all the data definitions and member functions of that object are defined inside that source file





One module directly refers to the content of the other

  • One module directly refers to the content of the other

    • module 1 modifies a statement of module 2
      • Assembly languages typically supported this, but not high-level languages
      • COBOL, at one time, had a verb called alter which could also create self-modifying code (it could directly change an instruction of some module).
    • module 1 refers to local data of module 2 in terms of some kind of offset into the start of module 2.
      • This is not a case of knowing the offset of an array entry - this is a direct offset from the start of module 2's data or code section.
    • module 1 branches to a local label contained in module 2.
      • This is not the same as calling a function inside module 2 - this is a goto to a label contained somewhere inside module 2.


Common coupling exists when two or more modules have read and write access to the same global data.

  • Common coupling exists when two or more modules have read and write access to the same global data.

  • Common coupling is problematic in several areas of design/maintenance.

    • Code becomes hard to understand - need to know all places in all modules where a global variable gets modified
    • Hampered reusability because of hidden dependencies through global variables
    • Possible security breaches (an unauthorized access to a global variable with sensitive information)
  • It’s ok if just one module is writing the global data and all other modules have read-only access to it.



  • Sometimes necessary, if a lot of data has to be supplied to each module



Two modules are control-coupled if module 1 can directly affect the execution of module 2, e.g.,

  • Two modules are control-coupled if module 1 can directly affect the execution of module 2, e.g.,

    • module 1 passes a “control parameter” to module 2 with logical cohesion, or
    • the return code from a module 2 indicates NOT ONLY success or failure, but also implies some action to be taken on the part of the calling module 1 (such as writing an error message in the case of failure).
  • The biggest problem is in the area of code re-use: the two modules are not independent if they are control coupled.



It is a case of passing more than the required data values into a module, e.g.,

  • It is a case of passing more than the required data values into a module, e.g.,

    • Passing an entire employee record into a function that prints a mailing label for that employee. (The data fields required to print the mailing label are name and address. There is no need for the salary, SIN number, etc.)
  • Making the module depend on the names of data fields in the employee record hinders portability.

    • If instead, the four or five values needed are passed in as parameters, this module can probably become quite reusable for other projects.
  • As with common coupling, leaving too much information exposed can be dangerous.



Data coupling exhibits the properties that all parameters to a module are either simple data types, or in the case of a record being passed as a parameter, all data members of that record are used/required by the module. That is, no extra information is passed to a module at any time

  • Data coupling exhibits the properties that all parameters to a module are either simple data types, or in the case of a record being passed as a parameter, all data members of that record are used/required by the module. That is, no extra information is passed to a module at any time



Routine call

  • Routine call

    • increases connectedness of a system
  • Type use

    • use in ClassA types from ClassB (complex modifications)
  • Inclusion or import

    • occurs when CompA incs./imports CompB
  • External

    • occurs when calling OS system calls, DBMS services, etc.


Step 1. Identify all design classes that correspond to the problem domain.

  • Step 1. Identify all design classes that correspond to the problem domain.

  • Step 2. Identify all design classes that correspond to the infrastructure domain.

  • Step 3. Elaborate all design classes that are not acquired as reusable components.

    • Step 3a. Specify message details when classes or component collaborate.
    • Step 3b. Identify appropriate interfaces for each component.
    • Step 3c. Elaborate attributes and define data types and data structures required to implement them.
    • Step 3d. Describe processing flow within each operation in detail.


Step 4. Describe persistent data sources (databases and files) and identify the classes required to manage them.

  • Step 4. Describe persistent data sources (databases and files) and identify the classes required to manage them.

  • Step 5. Develop and elaborate behavioral representations for a class or component.

  • Step 6. Elaborate deployment diagrams to provide additional implementation detail.

  • Step 7. Factor every component-level design representation and always consider alternatives.



课后阅读

  • 课后阅读

    • 《Design Principles and Design Patterns》
  • Next Lecture

    • Software Design Model


Yüklə 1,9 Mb.

Dostları ilə paylaş:




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə