1 / 38

Modular Design

Modular Design. What are modules? Good modules Criteria for evaluating modularity Hierarchy Modules and Classes Namespaces Other tricks and techniques. Modularity -- What does it look like?. Modularity packages abstractions into discrete units. What are Modules?.

keala
Download Presentation

Modular Design

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Modular Design • What are modules? • Good modules • Criteria for evaluating modularity • Hierarchy • Modules and Classes • Namespaces • Other tricks and techniques sd

  2. Modularity -- What does it look like? Modularity packages abstractions into discrete units. sd

  3. What are Modules? • Modules are just another name to software units: • Pieces of code • They should have “building block” properties: • Independent • Well-defined interface • Examples: • Routines • AKA procedures, functions, subprograms, subroutines, etc. • Files • as in C • Packages • as in ADA • Modules • as in Modula • Objects • Classes sd

  4. Good Modules • Two aspects to a module: • interface • specification in Ada • *.h in C “One must provide the intended user with all the information needed to use the module correctly, with nothing more.” David Parnas [1972]: • implementation • called a body in Ada • *.c in C “One must provide the implementer with all the information needed to complete the module, and nothing more.” David Parnas [1972]: sd

  5. Good Modularity • “Modularity - the property of a system that has been decomposed into a set of cohesive and looselycoupled modules.” [G. Booch, OODwA, '91, p. 52] • Cohesion • Loose coupling • Criteria for evaluating the quality of modularity in a system or a design methodology [Meyer, OOSC ‘88]: • Global Criteria • Decomposability • Composability • Continuity • Local Criteria • Continuity • Understandability • Protection sd

  6. Decomposability • Divide a problem into several sub-problems, and work on each sub-problem individually. • Examples: • Top-down design • Automobile systems: • Transmission • Brake • Electricity • Operating System: • File system • Processes • Timer • Counter Examples: • Initialization module • The C++ Programming Language: There is no decent sub-language other than C! • MS-Windows: No simple uninstall strategy. sd

  7. Composability • Build a new system from existing components • Examples: • Good Procedure Libraries • C stdio • C strings • IMSL • Common Data Format (usually weakly typed) • RTF: Rich Text Format. • Lisp: the nested list metaphor. • UNIX filters: text files. • ML: Hyper Text Markup Language. • IMSL: Numerical computation library: real vectors/matrices. • OLE/VBX Controls. • Counter Examples: • Most DOS applications • Pre-processors sd

  8. Continuity • Small change in problem specification leads to a small change in the module/system • Examples: • #define MAX_ELEMENTS 50 • Counter Examples: • Changes in data formats • Top-down design • Dependency on implementation: function/variable • if (f.eof) • if (f.eof()) sd

  9. Understandability • Understand a module by examining at most few of its neighbours • Examples: • Smalltalk containers library • Counter Examples: • Most current applications sd

  10. Protection • Modular Protection • Effects of errors limited to one module, or at most few of its neighbours. • Examples: if (!(p = calloc(MAX_ELEMENTS, sizeof *p))) { printf(stderr, ”cannot allocate...\n”); ...} • Counter Examples: f(){char s[100]; gets(s); ....} sd

  11. Achieving Good Modular Design • The Main Technique: • Hierarchy • A person can usually understand • the magical number seven plus minus one or two. • In order to deal with large system, one must be able to organize it in a hierarchy of abstractions. • Even finding good names and identifiers become a problem, e.g.,dbg_dbg_std_open() sd

  12. Hierarchy • Example: Computer Organization: • Pascal virtual machine downto microcode. • Mechanisms for building a hierarchy: • Conceptual layers (e.g., ISO communication model). • User discipline. • Lingual Mechanisms: • routine • class (only in OOP languages) • file/cluster of classes • -- missing link! • nested procedures? • nested modules? • namespaces? • directories? • categories? sd

  13. Modules and Classes • Simple and pure OOP approach: • Class = Module • Module = Class Difficulty: need higher level structures • More sophisticated approach: • Classes and objects are implemented in modules to produce the architecture of a system. • Independent design decisions: • Logical design: Finding the classes and objects. • Physical design: Organizing the classes and objects into modules. sd

  14. Classes as Namespaces • In C++ each class forms a namespace, in which one can make enum, typedef and even class and struct definitions. • Let class specific definitions belong in its namespace • Example: enumerated typed as symbolic constants class Stack { enum {DEFAULT_SIZE = 1000 }; ...}; The alternate ways for defining symbolic constants, #define DEFAULT_SIZE 1000 and constint DEFAULT_SIZE = 1000; are much less modular. sd

  15. Classes as Namespaces (cont.) • Example : Type definitions class String{private: typedef char* pchar; ...}; class Date{public: typedef enum { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec } Month;...}; sd

  16. More on Classes as Namespaces Static class variables can be used to define class specific variables class Complex {public: static Complex Infinity; enum {DEFAULT_SIZE = 1000 };}; f(Complex c){if (c == Complex::Infinity) { ... } ... } sd

  17. Nested Classes Class nesting can be used to group together related classes: class Stack {public: class Overflow { }; // May be thrown from push()class Underflow { }; // May be thrown from pop() ...}; class Tree23{private: class Node { ... }; class InternalNode: public Node {...}; class ExternalNode: public Node {...}; ...}; sd

  18. Namespaces namespace TurboWindows { class Window {... }; Window *display;} • Define • Use single element by explicit qualification TurboWindows::display.clear(); • Incorporate a single element via ausing-declaration using TurboWindows::display; ... display.clear(); • Incorporate an entire namespace via a using-directive usingnamespace TurboWindows; ... display.clear(); sd

  19. Nested Namespaces namespace Technion {namespace Base {namespace Math {class Complex { ... }; ... }namespace Types {class String { ... };class Date { ... }; Date today; ... } }namespace DataStructures {class Stack { ... };class Queue { ... }; ... }namespace Windows {class Window { ... }; ... }} sd

  20. Adding Elements to Namespaces namespace Technion {namespace Windows {class Window { ... }; }} ... #include <stdio.h>... namespace Technion {namespace Windows { Window *display; }} sd

  21. Manipulating Namespaces // Alias to a namespacenamespace Math = Technion::Math; // Composing namespacesnamespace My {usingnamespace Technion::Base::Types;usingnamespace HebrewUniversity::Math;usingnamespace GNU::String; // Overloads Technion::Base::Types::String}; sd

  22. Decisions in Modular Design • Grouping of logically-related classes together • Example: tree, tree-node, and tree-iterator • Rule of thumb: • 5 or so classes • 10-15 or so functions • Concerns: • Work is partitioned by modules • Machine architecture constraints • Reuse of modules across applications • Isolate machine dependencies • Isolate configuration dependencies • Partitioning of each module into interface and implementation parts • Recall Parnas’ rules. • Visibility graph among modules These decisions are a creative and inventive process. They can never be made in any disciplined order! sd

  23. Techniques for Good Modularity Bertrand Meyer [OOSC ‘88] enumerates five principles that “ensure proper modularity”: • Creativity is Dangerous: • Linguistic modular units • Must use proper language constructs • Totalitarian Regime Communication: • Few interfaces • You may talk with only few others! • Small interface • You may use only few words in your conversation! • Explicit interface • All conversations. • Paranoid Approach: • Information Hiding • Everything is secret unless explicitly declared otherwise. sd

  24. Linguistic Modular Units • Demand • Modules must correspond to syntactic units in the languages used. • Rationale • Global • Decomposability: There should be a clear boundary between modules. • Composability: Dispersed modules cannot be conveniently recomposed. • Local • Understandability: Dispersed modules are difficult to understand. • Protection: The best protection is that of the compiler. Programmers tend to break non enforceable rules. • Conclusion • It is foolish to make a modular design for Cobol! sd

  25. Few Interfaces • Demand • Every module should communicate with as few others as possible. • Rationale • Global: • Continuity: changes less likely to affect other modules. • Local: • Understandability: small neighbourhood to consider. • Protection: less likely to affect others. sd

  26. Module Architecture #1/4 • Complete Graph • Maximal number of interfaces: n(n-1)/2 • Worst case! sd

  27. Module Architecture #2/4 • Shallow Tree (Star) • Minimal number of interfaces n-1 • Best case in terms of the total number of connections, but there is a node of a very high degree n-1 sd

  28. Module Architecture #3/4 • Binary (Low Degree) Tree • Minimal number of interfaces n-1 • Best case in terms of • total number of connections. • maximal number of connections. • usually three. • Try to keep the diameter small. • More generally, low expansion property is desired. sd

  29. Module Architecture #4/4 • Planar Graph • Reasonable number of interfaces: 3n-6 • Relatively simple to draw (can use straight lines only...) • Typical in OOP • Try to keep the degree small sd

  30. Cycles in the Interfaces Graph Buffer Handle Chunk Hanoi Node List • Recall that the graph is directed. • Cycles are usually a bad sign. • Large cycles are unacceptable! • Small cycles are in many cases OK: sd

  31. Mutually Recursive Routines Peano North Peano West Peano East Peano South Peano Curve: sd

  32. Biconnected Components • Biconnected Components are usually candidates for higher level clusterization: sd

  33. Small Interface (Weak Coupling) • Demand • If two modules communicate at all, they should exchange as little information as possible. • Rationale • Global • Continuity: changes less likely to affect other modules • Local • Understandability: small neighbourhood to consider • Protection: less likely to affect others • Conclusion (also from “few interfaces”): • Ban • C global variables • Fortran global garbage block sd

  34. Coupling StrongCoupling WeakCoupling Classical Levels of Coupling [Myers ‘78], [Stevens, Constantine, Myers ‘81] • Content - A module refers directly to the contents (source code) of another. • Examples: Modify statement, jump to internal label, refer to local data through numerical offset, etc. • Common - Access to the same global data. • Examples: C’s global variables, Fortran’s common block. • Control - Directly affect the control of another module. • Examples: pass control flag, request one module to print an error message for another, prescribed order among modules. • Parameter - AKA signature coupling, occurs when a data structure is used to pass information between modules. • Hardly a concern in strongly typed languages. • Data Coupling - Occurs when all parameters are either simple, or, data structures all of whose elements are used. Irrelevant in modern languages, replaced by: • Subtype Coupling - Inheritance. sd

  35. Explicit Interfaces • Demand • Whenever modules A and B communicate, this must be obvious from the text of A and B or both. • Dynamic tool (e.g. run-time system) or, better yet, static tool (e.g., compiler) should be able to check that the communication is done according to that interface. • Rationale • Global • Composability: Must know which modules are connected. • Local • Understandability: We should be able to know which modules are dependent on, and affect the one we try to understand. • Counter Examples: • Shared variables, files, etc. • Pointers. • Shared types. sd

  36. Information Hiding • Demand: • All information about a module should be private unless it is specifically declared public. • Rationale: • Global: • Continuity: Changes to private parts will not affect other modules. • Local: • Protection: Protection from changes to internal data format. • Understandability: Gives two levels of understanding the module. • Counter Examples: • C’s struct • Pascal main Program • Examples: • Turbo/Borland Pascal’s units • C++’s class sd

  37. Criteria & Principles Relationships Decomposability LinguisticModular Units Composability Few Interfaces Understandability Small Interfaces Continuity Explicit Interfaces Protection Information Hiding Hierarchy Principles Criteria SimpleInterfaces Cohesion sd

  38. Cohesion WeakCohesion StrongCohesion Classical Levels of Cohesion [Myers ‘78] • Coincidental - Occurs when carelessly trying to satisfy style rules. • print_prompt_and_check_parameters • Logical - Related logic, but no corresponding relation in control or data. • Library of trigonometric functions, in which there is no relation between the implementation of the functions. • Temporal - Series of actions related in time. • Initialization module. • Sequential - Series of actions related to a step of the global processing. • read_inputs, check_all_inputs, output_result. • Communication- Series of actions related to a step of the processing of a single data item. May occur in the attempt to avoid control coupling. • clear_window_and_draw_its_frame • Functional - Execute a single, well-defined function or duty. • Data - Collection of related operations on the same data. sd

More Related