comp.lang.ada
 help / color / mirror / Atom feed
From: rjh@cs.purdue.EDU (Bob Hathaway)
Subject: Re: Good Design Strategies <Was comments on comments>
Date: 3 Mar 89 05:45:48 GMT	[thread overview]
Message-ID: <6156@medusa.cs.purdue.edu> (raw)
In-Reply-To: 2542@goofy.megatest.UUCP

In article <2542@goofy.megatest.UUCP>, djones@megatest.UUCP (Dave Jones) writes:
>...My assertion -- must I repeat it again? --
>is that good modules are more likely to come from a bottom-up approach.

Ok, I'll admit you've made a good point although I still think starting at
the top is the natural way to design systems (and algorithms).

>> By breaking the system into smaller pieces with each
>> piece providing some well defined and more manageable part of the system,
>> the components should emerge.
>>
>Components might emerge. But how they emerge may be dictated by the
>...

Ok, how about a quick example starting at top level.  When designing
a "Classical" compiler/interpreter front-end, I know the structure will
consist of a scanner to read input and a parser to read the grammar.  
I'll assume the parser functions return an intermediate code Adt for
triviality.  Now, I know I'll need a symbol table for identifiers and
reserved words and a token type to return to the parser, and we have:

|-------|       |------|     |------------|
|scanner|------>|parser|---->|intermediate|
|-------|       |------|     |    code    |
      \          /           |------------|
       \        /
        |-------|
        |symbol |
	|table  |
        |-------|

Their are four top-level modules immediately identified.  
1. Symbol Table 
    Provides a symbol_table_entry Adt (encapsulates a type).
    <Description>
    Operations
	a. lookup/insert
	   <Description>
	...
2. Scanner 
    Provides TokenType Adt (encapsulates a type).
    <Description>
    Operations
	a. Next_Token
	   <Description>
	b. Match_Token
	   <Description>
	...
3. Intermediate Code
    Provides Intermediate_Code Adt (encapsulates a type)
    <Description>
    Operations
	a. Make_Node
	   <Description>
	b. Make_Child
	   <Description>
	...
4. Parser
    Parses input (encapsulates functionally related subprograms).
    <Description>
    Operations
	a. Statement
		Returns an intermediate code representation of the 
		parsed statement...
	b. Parse
		Go for the whole thing:-)
	...

Thus, a modular design with Adts.  The design can proceed by identifying
the return values and parameters to operations and possibly some high level
pseudo code to insure the problem is well understood and all parts of the
system will work together as expected.  To begin the implementation we 
analyze the dependencies, almost always the Adts come last.
Dependencies
  parser:  	scanner, symbol table, intermediate code, 
  scanner: 	symbol table
  symbol table:	 nothing
  intermediate code: nothing
We can begin implementation with the intermediate code and symbol table
because we know what they need to provide and how they fit into the system
and because they don't depend on unwritten code.  Yes, the token, 
symbol table, and intermediate code Adts won't change much and
are good candidates for reuse; I wouldn't expect to add more than one
or two operations and change more than a few parameters for each Adt
above after the initial design is complete.  Each module provides a
well defined interface and encapsulates either a type (Adt) or a
set of functionally related subprograms (the parser).  After the top level
design is complete we can turn to the internal design of the Adts.
For example the intermediate code Adt may be complex requiring recursive
application of the above technique, i.e. top down.  So, a generic tree
Adt from a library can be used, and so on, nothing special purpose.
The parser functions can be designed top-down and implemented bottom-up,
so we'll know what gramatical constructs are necessary from the top and
get there fastest from the bottom (the preferred implementation technique
for parsers).  Efficiency considerations can come later *if* the system
doesn't meet its timing constraints, good design comes first.  We wouldn't
know where to optimize until profiling anyway.

Classification:
Object Oriented (design & implementation)
    Yes: objects identified, 2nd level design and coding begins with 
	 objects (data structures).
    No : no inheritance.
Top-Down (design)
    Yes: Top-down design is used within modules, especially in the parser.
    No : Structure charts were possible, but modules provided the best high
	 level view of the system.
Bottom-up (implementation)
    Yes: started with the lowest level Adt.  Generic linked lists, tree adts,
	 etc., would be used to implement the Adts from the bottom up.
What I call this mess:
    Modular design with abstract data types, top-down design within modules.
Reuse:
    All software tools and components are conceivably replaceable 
    and reusable.

>... Which method is best depends on the job at hand. ...

I agree, the above technique was chosen after carefully considering the 
problem and I have found it suitable for most, if not all applications.
Direct encoding of the design and implementation is possible in Ada
and to my understanding this is the preferred application of Ada's 
methodology.  Flamage and comments are welcome.  In view of the recent
object-oriented discussions, can anyone comment on how inheritance,
dynamic binding, or any other object oriented techniques fit into or
could improve the above scheme?  I'll be disappointed if the modular 
technique with Adts is the only one provided:-)

Bob Hathaway
rjh@purdue.edu

  reply	other threads:[~1989-03-03  5:45 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1813@goofy.megatest.UUCP>
1989-02-10 21:16 ` comments on comments Bob Hathaway
     [not found] ` <20233@agate.BERKELEY.EDU>
     [not found]   ` <9689@ihlpb.ATT.COM>
1989-02-23  2:15     ` Bob Hathaway
1989-02-23  7:22       ` Dave Jones
1989-02-23 22:50         ` Good Design Strategies <Was comments on comments> Bob Hathaway
1989-02-25  1:07           ` Dave Jones
1989-02-26 19:34             ` Rob Jellinghaus
1989-02-27  0:58               ` William Thomas Wolfe,2847,
1989-02-27 15:29                 ` John Baugh
1989-02-27 18:29                 ` Reuseable Ada components William Thomas Wolfe,2847,
1989-02-28  0:53             ` Good Design Strategies <Was comments on comments> Bob Hathaway
1989-02-28 22:13               ` Dave Jones
1989-03-03  5:45                 ` Bob Hathaway [this message]
1989-03-08 17:14                   ` David P. Schneider
1989-03-11 11:15                   ` Stuart H. Ferguson
1989-02-24  1:57         ` comments on comments William Thomas Wolfe,2847,
1989-02-23 20:41       ` comments on comments on reusability Rick Farris
1989-02-24  2:15         ` comments on comments on comments William Thomas Wolfe,2847,
1989-02-24  3:31           ` William A. Bralick
1989-02-24  9:24           ` Rick Farris
1989-02-25 14:28           ` Robert Claeson
1989-03-09 21:12           ` Rick Clements
1989-02-27  9:09 Good Design Strategies <Was comments on comments> Erland Sommarskog
1989-02-27 15:46 ` William Thomas Wolfe,2847,
1989-02-27 17:07   ` Mike Coffin
1989-02-28  4:16     ` Steven D. Litvintchouk
1989-02-28  4:11   ` Steven D. Litvintchouk
1989-03-04  1:25     ` Robert A. Agnew
1989-02-28 11:23   ` Mikael Eriksson
1989-03-01 22:25     ` William Thomas Wolfe,2847,
1989-03-02 22:14       ` Michael Schwartz
1989-02-28 12:22   ` Robert Claeson
1989-02-28  1:16 ` Bob Hathaway
1989-02-28  4:55   ` Rob Jellinghaus
1989-02-28 22:35     ` Dave Jones
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox