Re: Text terminal rendering design



H. S. Lahman wrote in 5cg9i.12$6h.3@trnddc08:">news:5cg9i.12$6h.3@trnddc08:
The notion of "Terminal" did not come out of thin air.

Agreed. I created the notion of Terminal myself and I defined what it
means.

The OO paradigm is based on problem space abstraction. Facade
objects are abstracted from the computing space (interfaces, APIs.
etc.). But the notion of Terminal must come from the subject matter
problem space.

You're saying that because you have seen a case where a problem space
abstraction is-a Terminal. This all comes from the fact that you
reject the idea that an object can be both an interface object and a
problem space object. If you did not reject that idea, you would have
no problem with an is-a relation between and interface class and a
problem space class. However, that is all theoretical and does not
matter in this case.

(Also note that there is no generalization in the GoF Facade
pattern structure.)

I am aware of that. Are you intentionally suggesting that no instance
of the Facade pattern should have a Facade class that is a subclass
of some other class? The GoF don't seem to say I cannot do it that
way. In general for patterns, when a pattern does not show
relationships that the participants have with classes outside the
pattern, it does not mean that no such relationships should exist in
a particular instance of the pattern.

What you defined was a generalization relation with Terminal as
the superclass whose responsibilities directly implemented the
subject matter solution. All I can suggest is that you pick up any
OOA/D for an explanation of generalization and its implications.
There is nothing more I can say on this issue that won't be in any
OOA/D book.

As a practical matter, you could comment on the example I carefully
constructed to illustrate my point and why it so totally failed to
convince you. I am sure I would not find that in any OOA/D book, at
least not for my particular example. On the other hand, if you do
know of a book that deals with a similar example, I would be happy
for a reference to that book.

I admit that you have far greater experience and theoretical
knowledge, and perhaps you know things about the implications of
generalization that I cannot immediately see, but in this case I
really don't need to see any implications of generalization. I only
need to see one implication that generalization does not have: it
does not cause coupling in my design.

I have proven that there is no coupling in the only way that really
matters, by practical experience. I know there is no coupling simply
because I can change my design in any way I like without changing the
client. If your theory says I can't, then your theory must be wrong
just as any theory must be wrong if it contradicts empirical facts.

No matter how many books I read that tell me that I should have
coupling; it will not cause coupling to appear where there is none.
Cover my desk with books from the finest OOA/D scholars and I will
still be able to radically change my design without the slightest
change to my client.

If those books can convince me otherwise, as they seem to have
convinced you, then I think I should actually avoid those books.
Theoretical knowledge is great but only as long as it does not make
you ignore empirical evidence when it contradicts your precious
knowledge.

On nonfunctional requirements:
[...]
If you have to get into issues like kerning on a high-end graphics
terminal, it might be a problem if all you have is 20 us. But I
would wait until a profiler demonstrated that.

But isn't it good design practice to create a design that is flexible
enough to easily accommodate whatever the profiler might say needs to
change? In order to do that, whenever something is time critical I
should avoid a design that forces me to do work that is technically
unnecessary at that moment, even if I strongly suspect that I will
have plenty of time to spare when everything is implemented.

It also becomes a time contraint for an editor when a paragraph
is filling the screen and the user is typing new words into the
top of the paragraph. In this case, the entire screen is changing
but not scrolling. I have to perform (A) 2000 times, which is my
biggest worry about how trivial (A) really is. Something that is
trivial when done once is not necessarily trivial when done 2000
times.

But the rest of the screen is already in video RAM. All that is
being added is what the user is typing and that takes so long the
user is never going to notice the conversions.

But if you think about the example I described, you might notice that
even though the screen is in video RAM, that RAM needs to be updated
with modified contents. Perhaps I have not described it properly, but
when I type at the top of a paragraph it is not merely inserting new
letters in one little corner of the screen; it has a cascading effect
down the entire screen. The video RAM will not help me with that; I
need to get the new layout of the text from the client.

If you load all the terminal-ready Symbols from a DB at startup (or
they are linked in), then they are fixed so you don't need a
collection that if efficient at adding/removing entries and can
focus on best search performance. In any event, the differences
between them will be relatively small.

It seems I have also failed to properly describe why I cannot load
all the terminal-ready symbols at startup. Let me try again from a
different direction.

The client has some problem space concept that needs to be displayed
as a symbol on a 2D array of symbols on the screen. We've been
calling that concept an Icon for lack of a better name and I imagine
a client with an actual class called Icon for such objects.

Ideally, the client would be able to send my subsystem an Icon and
target it at some coordinates on the screen and my subsystem would
draw it. In order for that to happen, my subsystem needs some way of
finding a terminal-ready symbol for each Icon that it is given. I can
see two ways to do that: (A) I can use the value of the Icon object,
whatever the client has stored in that object to represent the
semantics of the icon, or (B) I can use the identity of the Icon
object as represented by some value that only this Icon holds, such
as its position in memory.

The data structure that I need does not hold just the terminal-ready
symbols; alone those are useless. Actually, the data structure is a
mapping from Icon values to terminal-ready symbols, whether I use (A)
or (B). While it is relatively easy to know all terminal-ready
symbols at startup, knowing all the icon values at startup presents
some problems.

If I use (A), I am coupling my subsystem to the client representation
of Icons, which is surely not a good thing. I am also forcing it to
announce all of its icons in advance of starting.

If I use (B), I am not coupling my subsystem to anything, but I am
forcing the client to announce all its icon identities in advance of
starting, which seems even more problematic. They cannot know the
location in memory of each Icon object before starting, especially if
they ever want to dynamically allocate or delete an Icon. So memory
location cannot be used as identity, even though that is a popular
option. In practice I expect I will be forcing the client to keep
track of a special identity value for each Icon object, for the sole
purpose of keeping my subsystem happy.

Have you considered the above consequences when you suggest I load
all the terminal-ready symbols at startup?

Probably the biggest single factor will the form of identity of
the icons. If you can possibly avoid it (i.e., you have some say
over how the client identifies icons), you should avoid lengthy
ASCII keys or compound keys. Since ASCII and unicode have
convenient consecutive integer keys I would do that lookup with a
simple array and the search becomes O(1).

Unfortunately, the client will want more than mere ASCII or Unicode.
The client will also want to specify color, at least. I want to
support pure ASCII, but that is not the expected use for this
subsystem.

If the symbol to be displayed is a true icon, that identifier is
likely to be ASCII so I would keep that lookup separate. Then all
you need to know is whether the identifier in hand is for a
character or an icon. Since the client would naturally know that
you can insist that the client supply that information with the
request (e.g., calling displayCharacter or displayIcon).

That seems reasonable, but how am I supposed to figure out what
should be displayed when I am given nothing but a mere identifier?
Worst of all, it is a client chosen identifier, so my subsystem has
no means of determining what the identifier means, and surely you
expect the subsystem to treat it as a handle.

I suppose you are assuming that all the mapping information between
identifiers and symbols is loaded at startup, so it is not an issue.
However, in real life I cannot reasonably expect to load all the
terminal-ready symbols at startup, despite the usually small number
of available symbols for any given hardware.

In practice, I will need the client to somehow describe each symbol
in messages, and some handle that my subsystem cannot analyze does
not seem helpful with that.

If you keep all the terminal-ready Symbols in memory, then things
like frequency of access are not going to matter. That stuff only
becomes of interest if you can't keep all the Symbols in memory at
once. And for ASCII/unicode all you need is a single index lookup
in an array.

I agree, but it is far more likely that ASCII/unicode will be the
symbol value that I send to the hardware than the values that I get
from the client. In other words, ASCII describes the values stored in
the array rather than the index.

The character or icon identity that the client provides must be
unique. There may be different messages that carry an identifier,
but they all go to the same table lookup.

How exactly do you picture the icon identity being used? Would it be
something as simple as 'display(x,y,iconID)'? In that case, how is my
subsystem to know the meaning of the identifier? It seems more likely
that I would be getting messages of the form

display(x,y,complexValueDescribingAllTheDetailsOfTheDesiredSymbol)

However, what you seem to be worried about is that the client has
control over your internal processing and will require multiple
messages to complete the processing of getting a single
character/icon displayed.

That is not what I meant at all. I know better than that now, and I
never really ever had that intention in my design. What I was
actually trying to say was that one message alone seems like it might
not be expressive enough to give a client access to the full
diversity of symbols that some hardware can support.
.



Relevant Pages

  • Re: Text terminal rendering design
    ... The fact that you have to hand the client a Terminal object that provides a specific implementation of the responsibilities for the actual hardware in hand is a direct demonstration that the generalization is an implementation artifact. ... It seems I have also failed to properly describe why I cannot load all the terminal-ready symbols at startup. ... We've been calling that concept an Icon for lack of a better name and I imagine a client with an actual class called Icon for such objects. ... In order for that to happen, my subsystem needs some way of finding a terminal-ready symbol for each Icon that it is given. ...
    (comp.object)
  • Re: Text terminal rendering design
    ... The Terminal generalization is abstracted from specific facades that could be given to the client to handle messages. ... It could be that the nonfunctional requirements that you are advocating my subsystem resolve are so completely trivial because takes no time at all. ... tracking terminal-ready Symbols in memory after they are initially ... If the symbol to be displayed is a true icon, that identifier is likely to be ASCII so I would keep that lookup separate. ...
    (comp.object)
  • Re: Text terminal rendering design
    ... I expect that the real facade class would always be a subclass of the class shown to he client in practice, especially if this facade is acting as a subsystem interface. ... But I don't see how having terminal-ready symbols already in memory helps in eliminating conversions. ...
    (comp.object)
  • Re: Text terminal rendering design
    ... I expect that the real facade class would always be a subclass of the ... class shown to he client in practice, ... acting as a subsystem interface. ... But I don't see how having terminal-ready symbols already in memory ...
    (comp.object)
  • Re: Text terminal rendering design
    ... \\ the client directly, against common wisdom. ... I just tell the client that has a Terminal pointer and let it think it is talking to a facade. ... We want to change the name of the subsystem interface. ... Certainly within the UI subsystem I am free to do whatever I want even with my current design, including the exposed terminal-ready symbols. ...
    (comp.object)