Odd inheritance design problem

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Odd inheritance design problem

Fernando Rodríguez
Hi,

I'm writing a set of classes to represent something similar to a css, but
for rtf files. I have 2 basic kind of text styles, paragraph styles and character
styles. The problem is the same for both, so let's concentrate on character
styles.

I have a class called DefaultStyle, that represents the default formating
for text. An instance of it may  may be Times New Roman and 12 points. Now
say I want a new style that represents bigger text, called BigStyle, which
should inherit Times New Roman and overwrite 12 points with 16 points.

So, it doesn't really inherit from the DefaultStyle class, but from an instance
of it.

This sounds odd and I suspect I have a design error.  Any suggestions?


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Chris Uppal-3
Fernando,

> for text. An instance of it may  may be Times New Roman and 12 points. Now
> say I want a new style that represents bigger text, called BigStyle, which
> should inherit Times New Roman and overwrite 12 points with 16 points.
>
> So, it doesn't really inherit from the DefaultStyle class, but from an
> instance of it.
>
> This sounds odd and I suspect I have a design error.  Any suggestions?

I don't think you have anything to worry about; it's a common design pattern,
and this seems like an appropriate application of it.

You might even say that class-based inheritance is a special case of this
general design, so don't let the word "inherit" worry you ;-)

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Fernando Rodríguez
Hello Chris,

>> So, it doesn't really inherit from the DefaultStyle class, but from
>> an instance of it.
>>
>> This sounds odd and I suspect I have a design error.  Any
>> suggestions?
>>
> I don't think you have anything to worry about; it's a common design
> pattern, and this seems like an appropriate application of it.
>
> You might even say that class-based inheritance is a special case of
> this general design, so don't let the word "inherit" worry you ;-)


OK, but how do you inherit from an instance? O:-)


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Chris Uppal-3
Fernando,

> OK, but how do you inherit from an instance? O:-)

Each instance contains a reference to its parent, which is also a Style (or
nil).  When you ask it for, say, the font-size, it looks to see if it holds a
definition for that and if so answers the value.  If not then it ask the parent
(which in turn might ask its parent, and so on...).   You can do that with
hard-wired instvars (presumably using nil to indicate values that weren't set
locally), or you could put a dictionary-like API on it (probably using a
LookupTable internally in each Style object).

Note that you wouldn't have a DefaultStyle class, you'd just have a Style class
with one special instance which was held the defaults settings.  All other
instances would hold a different instance as their parent (possibly, but not
necessarily, the default Style instance).

Does that make sense ?

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Peter Kenny-2
Chris, Fernando

Wouldn't it be simpler to have just a Style class with DefaultFont and
DefaultPointSize as class variables. Each newly created Style instance has
its font and pointSize instvars set from the class defaults, and retains
these values unless explicitly overridden. You might want to subclass Style
if you wanted another family of styles with a different default, but
normally the one class should be enough. Or have I misunderstood the
problem?

Best wishes

Peter Kenny


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Chris Uppal-3
Peter,

> Wouldn't it be simpler to have just a Style class with DefaultFont and
> DefaultPointSize as class variables. Each newly created Style instance has
> its font and pointSize instvars set from the class defaults, and retains
> these values unless explicitly overridden.

That wouldn't work the same way.  When you changed the master style (say) the
derived styles wouldn't reflect the changes.  E.g. if you changed the global
font to Helvetica, paragraphs that just wanted to use a larger typeface would
still have the old font.

Whether Fernando needs that feature is, of course, a different question...

BTW, another way (better IMO) to implement the pattern you described, is to
have a "template" instance which holds the defaults, and then new instances are
created by #copy-ing that.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Peter Kenny-2
"Chris Uppal" <[hidden email]> wrote:

> That wouldn't work the same way.  When you changed the master style (say)
> the
> derived styles wouldn't reflect the changes.

Yes, I see - hadn't thought of that. So that is the point of your earlier
suggestion that a Style instance might have its font instvar with a value of
nil (because it had not been explicitly set), and the accessor method for
font would do something like 'self class defaultFont' when it found a nil
value. I suppose whether Style class>>defaultFont answers a class variable
or copies the instvar of a template instance is largely irrelevant.

Peter


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Chris Uppal-3
Peter,

> So that is the point of your earlier
> suggestion that a Style instance might have its font instvar with a value
> of nil (because it had not been explicitly set), and the accessor method
> for font would do something like 'self class defaultFont' when it found a
> nil value.

Not exactly.  That would be workable, but (for me) too inflexible since it
limits you to exactly one level of derivation.  E.g. I might want:

#body-text is:
    font = arial
    size = 9pt
    colour = black

#title-text is:
    derived from: #body-text
    size = 12pt

#important-title-text is:
    derived from: #body-text
    colour = red

So each "aspect" that wasn't set in one instance would be fetched by asking its
parent for the value of the same aspect, which might well ask /its/ parent, and
so on.  There are very minor issues about how you terminate that process, but
there are several ways to handle that (according to taste), and anyway that's
just code...

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Fernando Rodríguez
Hello Chris,

> Not exactly.  That would be workable, but (for me) too inflexible
> since it limits you to exactly one level of derivation.  E.g. I might
> want:
>
> #body-text is:
> font = arial
> size = 9pt
> colour = black
> #title-text is:
> derived from: #body-text
> size = 12pt
> #important-title-text is:
> derived from: #body-text
> colour = red
> So each "aspect" that wasn't set in one instance would be fetched by
> asking its parent for the value of the same aspect, which might well
> ask /its/ parent, and so on.  

That's exactly what I' looking for. However, I have the feeling of reinventing
the wheel, as I'm reimplementing a kind of  inheritance by hand...


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Esteban A. Maringolo-3
Fernando Rodríguez escribió:

> That's exactly what I' looking for. However, I have the feeling of
> reinventing the wheel, as I'm reimplementing a kind of  inheritance by
> hand...

Have in mind that inheritance is a concept, beyond the fact that
Smalltalk uses it for its objects.

Regards,

--
Esteban.


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Chris Uppal-3
In reply to this post by Fernando Rodríguez
Fernando,

> That's exactly what I' looking for. However, I have the feeling of
> reinventing the wheel, as I'm reimplementing a kind of  inheritance by
> hand...

<Grin/>  Yes, I see what you mean.  But the mechanism used for class
inheritance isn't really suitable for use here (unless you create classes
on-the-fly), so you need a different implementation of roughly the same idea.

(Now if you were using ECMAScript or SELF, then instance inheritance is built
in to the language /instead/ of having class inheritance.  That's an
interesting idea, but it won't help you much here ;-)

BTW, if I were doing this, I would be tempted to give my Style objects a
Dictionary-like API, so the code that used them would say things like:
    color := aStyle styleAt: #Color.
rather than:
    color := aStyle color.
which would save a lot of messy duplication of the lookup code in each "aspect"
of style (colour, font, size, etc).  I might even create a general-purpose
InheritingDictionary and use those inside, or instead of, the Style objects.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Fernando Rodríguez
Hello Chris,

> <Grin/>  Yes, I see what you mean.  But the mechanism used for class
> inheritance isn't really suitable for use here (unless you create
> classes on-the-fly), so you need a different implementation of roughly
> the same idea.
>
> (Now if you were using ECMAScript or SELF, then instance inheritance
> is built in to the language /instead/ of having class inheritance.
> That's an interesting idea, but it won't help you much here ;-)

Interesting idea, I'll try to check it out.

> BTW, if I were doing this, I would be tempted to give my Style objects
> a
> Dictionary-like API, so the code that used them would say things like:
> color := aStyle styleAt: #Color.
> rather than:
> color := aStyle color.
> which would save a lot of messy duplication of the lookup code in each
> "aspect"
> of style (colour, font, size, etc).  I might even create a
> general-purpose InheritingDictionary and use those inside, or instead
> of, the Style objects.


That's a good idea, I'll give it a try. Thanks! :-)


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Stefan Schmiedl
On Thu, 16 Mar 2006 16:04:41 +0000, Fernando Rodríguez wrote:

>> (Now if you were using ECMAScript or SELF, then instance inheritance is
>> built in to the language /instead/ of having class inheritance. That's
>> an interesting idea, but it won't help you much here ;-)
>
> Interesting idea, I'll try to check it out.

And while you're at it, hop over to www.iolanguage.com, which is a
nice, small and quite fast language for classless oop.

Another thing, re: self. Somewhere on the 'net is a movie
about self ... yes, there it is:

http://www.merlintec.com:8080/Self

So you were dead on with your feeling about reinventing the wheel.

Good work,
s.


Reply | Threaded
Open this post in threaded view
|

Re: Odd inheritance design problem

Fernando Rodríguez
Hello Stefan,

> On Thu, 16 Mar 2006 16:04:41 +0000, Fernando Rodríguez wrote:
>
>>> (Now if you were using ECMAScript or SELF, then instance inheritance
>>> is built in to the language /instead/ of having class inheritance.
>>> That's an interesting idea, but it won't help you much here ;-)
>>>
>> Interesting idea, I'll try to check it out.
>>
> And while you're at it, hop over to www.iolanguage.com, which is a
> nice, small and quite fast language for classless oop.

Pretty cool. Before reading it, "classless oop" seemed crazy to me, but now
I'm not sure if classes are really necessary at all...