*   after determining the software architecture for a system,
    often one wants to determine the modules for implementing
    it next;

    ...that level of design, considering the modules,
    is the focus of this chapter;

    *   what modules should the system have
    *   which have to be developed

    *   ...making sure that the different views of
        the system "work together"

*   this part is often multi-level, also:
    *   high-level module design:
        *   deciding WHAT modules are needed
        *   the specifications for those modules
	*   HOW the modules will be interconnected

    *   detailed or logic module design
        *   deciding the INTERNAL design of the modules
        *   HOW the module specifications can be satisfied
        *   ,..to the point that actual coding can begin...!

*   some key design concepts
    *   the design of a system is CORRECT if
        *   it will satisfy all the requirements
	*   it is consistent with the (software) architecture

    *   of the correct designs (because there can be more than one!)
        we want the "best" design;
        ...but what is "best"?
        *    within the limitations imposed by the requirements
	     and the physical and social environment in which the
	     system will operate

*    here are SOME criteria we might use in assessing the
     "best"-ness of different potential designs:
     *   modularity
     *   coupling
     *   cohesion
     *   open-closed principle

*   modularity - a system is considered modular if it consists
    of DISCRETE modules,
    *   such that each module can be implemented separately,
    *   and a change to one has minimal impact on other modules

    *   ...we discussed numerous potential advantages
    *   BUT you can't JUST "chop" a program willy-nilly into
        modules to get these benefits;

	*   each module needs to support a well-defined abstraction,
	    with a clear interface through which it can interact
	    with other modules;

    *   let's talk about some criteria for decomposition;

        *   coupling
	*   cohesion
        *   open-closed principle

*   coupling - attempting to capture the notion of "how strongly"
    modules are interconnected;
    
    *   one concept to start with: two modules are INDEPENDENT
        if one can function completely without the presence of another

    *   ALL of the modules in a system can't be completely independent,
        though;
        *   some need to cooperate with each other so you CAN break
	    a large problem into smaller pieces;

	*   the more connections between modules,
	    the more dependent they are in general,
	    in the sense that you need to know more about one
	        module to implement another;

        *   we'd like fewer and simpler connections
	    to make understanding, implementing, testing,
	    maintaining, etc. modules easier;

    *   the more we have to know about module A to understand module
        B, the more closely/highly connected A is to B;
        *   "highly coupled" modules have strong interconnections
        *   "loosely coupled" modules have weak interconnections

	...and we'd prefer loosely coupled, note;

        ...and how coupled modules are is largely determined
	   at this stage of design, so coupling should be
	   considered at this stage;

    *   what kind of factors influence coupling?
        *   type of connection between modules
	*   complexity of the interface
	*   type of information flow between modules

*   consider type of connection between modules...
    *   complexity of interfaces -> increases coupling
    *   obscurity of interfaces -> increases coupling
    *   minimizing interfaces is considered helpful;
    *   number and complexity of parameters can influence 
        coupling;

    *   type of information flow - in general, data information
        is considered more loosely coupled than
	control information
    
*   object-oriented systems can have some
    finer grains of coupling;
    *   interaction coupling - methods of one class
            invoking methods of OTHER classes
    *   component coupling - when a class A has data fields
            and/or variables of another class C
    *   inheritance coupling - when one subclass is a direct
            or indirect subclass of another

*   Cohesion -
    is about WHY the pieces of a SINGLE module are
    in that module 
    (why did you "break" this up this way?)

    *   coupling is about the INTER-module bond between
        DIFFERENT modules;
    *   cohesion is about the INTRA-module aspect,
        why you included elements within ONE module

    *   we WANT high cohesion --
        we want there to be a "good" reason that
        these elements are together in THIS module;
	(low cohesion is not so good...)

    *   SO many levels of cohesion!
        (roughly from lower to higher cohesion,
	from coincidental (lower) to functional (higher)