[comp.object] Display methods, pro or con...

sjs@roland.ctt.bellcore.com (Stan Switzer) (08/07/90)

Quite simply, the question is this: should objects be concerned with
their presentation?

Leaving aside objects which are explicitly intended as display
artifacts (windows, menus, etc.) and considering application domain
objects such as personnel files, tractors, and fishing boats, should
these objects be concerned with how they are displayed or should we
separate the objects (models) from views?

Pro:  It is a lot simpler to just put "printme" methods in objects, and
in any event a lot of objects exist primarily for presentation
purposes.  This argument is made in the Booch book (of which I have
rather mixed emotions).

Con:  A fishing boat is a fishing boat no matter whether I am using a
dumb terminal or an X terminal.  Furthermore, who is to say that there
is only one kind of view for an object.  Or even only one view of a
particular kind.

My opinion:  I am powerfully impressed with the Model-View-Controller
paradigm.  It seems to make a lot of sense to define "view" objects
which can be pointed at other objects to display them.  Views would
display objects according to their "type" (as opposed to their class).
There would be views for "tables" (classes which respond to the
messages of the "table" type).  Tables could be displayed in tabular
form, or as graphs, charts, etc.  It should be possible to have
multiple simultaneous views of a single object.  And heck, why limit
it to display?  There's no reason why dragging on the bars in a bar
chart shouldn't be able to manipulate the table it displays.

Not that it's always easy.  An interesting problem is described in
Cox's book: There is a graphical front-end to the "make" program (or
something like that.)  From a purely semantic point of view, the data
being displayed and manipulated is simply a partial ordered graph.  In
defining the objects representing the nodes, it really doesn't make
any sense to have an object representing a source file know anything
about where it is on the display, but on the other hand you really do
want (from the UI point of view) to be able to display the graph later
with the nodes in the same positions, even though this has nothing to
do with the basic notion of partial ordering.  Where do you keep this
"annotation" information?  The "Andrew" system, which takes pains to
separate "views" from "data" has an idea of "view data" (if I remember
correctly), which represents additional display information (color,
position, etc.) which is not present in the underlying object.  

We can even generalize this a bit.  Should an object's methods be
concerned with what it is *for* or simply with what it *is*.  Example:
personnel records.  We should certainly have methods which realize and
elaborate on the basic concept of personnel records, but should we
embed intelligence about company personnel policy in these objects?

Obviously, up to a point, form follows function, but once we have an
object (such as a personnel record) which was intended for a particular
function we now have a resource for future development.  For good or
ill, this data resource can be used in many ways.  Of course, the
general utility of the object is compromised if there is too much of
the original application's semantics built into the object.

Now these issues don't make much difference in-the-small, but I'm
thinking of large systems, either distributed systems based on O-O
concepts, or O-O DBMSs, or perhaps dozens of evolving, interrelated
applications.  Consider a distributed object-oriented application: it
might easily arise one application might have to keep information
(workforce management) "about" objects managed by another application
(personnel).  Do we consider this to be one big object (employee) whose
realization happens to be distributed (with part of the "employee"
being realized in the workforce management application and part in the
personnel application)?  Or, do we consider them separate objects which
happen to be closely related?

I propose that it makes a lot of sense, even at the highest levels of
design to keep separate the ideas of what an object *is* and what the
object is *for*.  It is going to be difficult to tease apart the
concepts of what we do *to* an object and what the object *does*.  Up
to a point--but where?--an object should be free of teleological
baggage.

So what do you think?  Are there any good papers discussing these
issues?  At this point, I'm mostly interested in the issue of display
methods, but I think the problem goes much deeper that that.

Stan Switzer  sjs@bellcore.com

welter@aristotle.ils.nwu.edu (Pete Welter) (08/08/90)

In article <25966@bellcore.bellcore.com> sjs@roland.ctt.bellcore.com (Stan 
Switzer) writes:
> I propose that it makes a lot of sense, even at the highest levels of
> design to keep separate the ideas of what an object *is* and what the
> object is *for*.  It is going to be difficult to tease apart the
> concepts of what we do *to* an object and what the object *does*.  Up
> to a point--but where?--an object should be free of teleological
> baggage.

As a beginning Mac Common Lisper (a language that supports multiple
inheritance), I wonder if the best way to deal with this is to use
multiple inheritence, mixing in the appropriate interface class with
the class that is to be displayed.  Is this a common practice in
languages that support multiple inheritance, and if not, why not?

Having done a few user interfaces in OO systems, I remember feeling
that building a parallel display class was sort of "wrong" (it 
seems to blow encapsulation), yet putting all kinds of display stuff
in an object really gets away from (as Stan says) what an object *is*.



Pete Welter
Institute for the Learning Sciences
Northwestern University
welter@aristotle.ils.nwu.edu

cline@cheetah.ece.clarkson.edu (Marshall Cline) (08/08/90)

In article <25966@bellcore.bellcore.com> sjs@roland.ctt.bellcore.com (Stan Switzer) writes:
>Quite simply, the question is this: should objects be concerned with
>their presentation?
...
>We can even generalize this a bit.  Should an object's methods be
>concerned with what it is *for* or simply with what it *is*.  Example:
>personnel records.  We should certainly have methods which realize and
>elaborate on the basic concept of personnel records, but should we
>embed intelligence about company personnel policy in these objects?

I'll extend this to: Objects Should Provide Mechanism Rather Than Policy.
Ex: a Circle should enable various `views', rather than a specific policy
of bitmapped display, textual "I am a Circle", etc.  Similar remarks go
for a PersonnelRecord.

It seems to me that this `mechanism-not-policy' issue is the essential
reason why OOD scales better than top-down-structured-design (TDSD).
TDSD percolates policy down from the top.  When (not `if') a requirement
spec changes, huge branches of the TDSD `tree' may need to be lopped off
and modified.  Contrasting, OOD allows mechanism to percolate `up' the
tree (a String provides catenation, copy, printing, etc, but it doesn't
dictate which order things happen).

Since changes in requirement specs are inevitable, only the top `layers'
(the `pure policy' sections) need to change in OOD, since they simply call
on different mechanisms (or different orderings of the same mechanism) in
the lower level objects.

This is also why bottom-up implementation is so horrible in TDSD where
it's not *as* bad in OOD.

Stan is right on target.  Objects must provide maximal mechanism, with
system-wide policy decisions being delayed as long as possible.

Marshall Cline
--
==============================================================================
Marshall Cline / Asst.Prof / ECE Dept / Clarkson Univ / Potsdam, NY 13676
cline@sun.soe.clarkson.edu / Bitnet:BH0W@CLUTX / uunet!clutx.clarkson.edu!bh0w
Voice: 315-268-3868 / Secretary: 315-268-6511 / FAX: 315-268-7600
Career search in progress; ECE faculty; research oriented; will send vita.
PS: If your company is interested in on-site C++/OOD training, drop me a line!
==============================================================================

cline@cheetah.ece.clarkson.edu (Marshall Cline) (08/09/90)

I just posted a `positive' follow-up to Stan Switzer's comments on policy
rather than mechanism.  However now I'd like to post a problem with Stan's
specific example of the Model-View-Controller (MVC) paradigm.

QUESTION: Should a `Shape' be able to `draw' itself?

The usual answer is ABSOLUTELY.  I have to totally agree, since adding a
new Shape (Hexagon, for example) only requires adding code rather than
changing existing code (as would be required if there were a global `draw'
function).  This is the usual ``don't operate on objects; instead enable
the object to provide services for you''.

However: what if I add a new terminal type?  Or what if I want a textual
`view' (using MVC terminology) rather than a graphical `view'.  The real
problem is: what if I want several views to coexist in the system at the
same time, so a Square is either `viewed' as a bunch of pixels, the name
"Square", or whatever, depending on which `view' it's being `drawn on'.

The best I've come up with is this:

	    GraphicalShape     TextualShape   <-- One per `view'
	                 \     /
	                  \   /
	                  Shape
	                 /  |  \
	                /   |   \
	               /    |    \
	         Square   Circle  Hexagon     <-- One per concrete Shape

	class GraphicalShape { public: void graphical_draw() = 0; };
	class TextualShape   { public: void textual_draw()   = 0; };
	class Shape : public GraphicalShape, public TextualShape { };

Adding an XYZView means adding XYZShape to the base class list of Shape,
and filling in the XYZ_draw() in each concrete Shape (Square, Circle, ...).
The advantage over simply adding another pure virtual XYZ_draw() to Shape
is that GraphicalView can have a list of GraphicalShape's but can't get at
a Shape's textual_draw().  (I'm not sure if that's a bug or a feature :-)

Unfortunately this scheme means `reopening' all the concrete Shapes
whenever a new `view' is added.  However at least adding a new Shape
doesn't involve changing existing code in each `view' class.

Pros?  Cons?

Some of these concerns *may* go away in untyped languages (Smalltalk etc)
but I'd like to see a reasonable solution in a [pseudo]strongly-typed OOPL
(C++ etc).

Marshall
--
==============================================================================
Marshall Cline / Asst.Prof / ECE Dept / Clarkson Univ / Potsdam, NY 13676
cline@sun.soe.clarkson.edu / Bitnet:BH0W@CLUTX / uunet!clutx.clarkson.edu!bh0w
Voice: 315-268-3868 / Secretary: 315-268-6511 / FAX: 315-268-7600
Career search in progress; ECE faculty; research oriented; will send vita.
PS: If your company is interested in on-site C++/OOD training, drop me a line!
==============================================================================

timm@runxtsa.runx.oz.au (Tim Menzies) (08/11/90)

User-interface design gurus recommend seperating out the interface functionality
from the underlying program functionality. This, they say, lets the programmer
change one without having to change the other. THis is very useful for
prototyping user interfaces (and this is a GOOD THING, they say).

Now, these guys weren't talking about OOP. They were just reviewing all the
disasters they'd ever heard about in user-interface design. But, I'm willing
to accept their experience and conclude that the view object should be seperate
to the model object.


 _--_|\  Tim Menzies (timm@runxtsa.oz)      PH: 02 9297729, 61 2 4280200 (fax)
/      \ HiSoft Expert Systems Group,       "Software should be altered to 
\_.--._/ 2-6 Orion Rd Lane Cove, NSW,       accomodate the quirks of human
      v  Australia, 2066                    thought, and not vice versa."

cory@three.mv.com (Cory Kempf) (08/15/90)

cline@cheetah.ece.clarkson.edu (Marshall Cline) writes:

>QUESTION: Should a `Shape' be able to `draw' itself?

>The usual answer is ABSOLUTELY.  

>However: what if I add a new terminal type?  Or what if I want a textual
>`view' (using MVC terminology) rather than a graphical `view'.  The real
>problem is: what if I want several views to coexist in the system at the
>same time, so a Square is either `viewed' as a bunch of pixels, the name
>"Square", or whatever, depending on which `view' it's being `drawn on'.

It would seem to me that the advice that I was given when I was first 
learning Object Programming: Try to make your objects model a hardware
implimentation.

Your instincts are correct: The Shape should be able to draw itself.  In 
reality, the Shape doesn't (usually) actually muck with the pixels on the
screen, but rather tells the GraphicsDevice to perform some actions which
acomplish the same task.  From the description above, there are two classes
of objects: Shapes and GraphicsDevices.  The Shapes, when told to draw
themselves tell the GraphicsDevices what commands need to be executed.  The
GD's would impliment a set of Graphics Primitive methods that would actually 
do the work.  

I don't know how that would work with the idea of showing the name of the 
original objecct, but I would not view that as being a drawing related task
(e.g. instead of asking the Shape to draw itself, you would ask it to Name
itself).

+C
-- 
Cory Kempf				I do speak for the company (sometimes).
The EnigamI Co.							603 883 2474
email: cory@three.mv.com, harvard!zinn!three!cory