Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Is there an overhead in this OO design ?

Author: Mridul Muralidharan

Date: 12:58:06 01/06/06

Go up one level in this thread


Hi Alex,

  You raise very valid points.
Given a choice , I would lean towards including isAdjscent() into the CSquare -
but the other way also does not sound much different to me either ... wanted to
know your thoughts : hence my post :-)

To further the discussion , in java (which is what I code at work) there is a
simple analogy in the form of the Comparator interface.
(http://java.sun.com/j2se/1.4.2/docs/api/java/util/Comparator.html)

The comparator does the comparison of two objects.
The Comparator interface very similar to your point of view - externalise the
functionality outside in another class such that the objects themselves do not
maintain the ordering related info.
This way arbitrary comparisons can be achieved based on the comparator.

Then again , there is an alternate interface called Comparable
(http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Comparable.html).
The object itself implements this interface and it is used to get the 'natural
comparison method'.

The way I see it , isAdjescent() is similar to this 'natural comparison method'.
It is an intrinsic characterstic of the Square itself : just like rowUp() ,
rowDown() , isValid() , etc are.

You can ofcourse have other comparison - like whether it is adjescent from a
knights point of view , from a wrapping around the board point of view , etc -
these would not be the natural expectation for this class : but specialisation
which makes no sense to be part of the class itself.

Sorry for this relatively long post , this discussion is getting more
interesting with every post of yours :-)

Thanks,
Mridul

On January 06, 2006 at 12:28:00, Alexander Kure wrote:

>On January 06, 2006 at 11:18:37, Mridul Muralidharan wrote:
>
>>Hi Alex,
>>
>>  Just a comment about IsAdjacent() below.
>>
>>Thanks,
>>Mridul
>>
>>On January 06, 2006 at 08:44:09, Alexander Kure wrote:
>>
>>>On January 06, 2006 at 03:37:17, Gerd Isenberg wrote:
>>>
>>>
>>>[..]
>>>
>>>>>3) Instead of low-levely maipulating a square by means of operator+=() you could
>>>>>declare the following high-level functions in class CSquare:
>>>>>
>>>>>   void Up();
>>>>>   void Down();
>>>>>   void Left();
>>>>>   void Right();
>>>>>   void Next();
>>>>>   void Previous();
>>>
>>>>
>>>>Isn't it better to return a reference for this functions, to cascade several
>>>>directions in one expression?
>>>
>>>If you like to cacsacde these functions then your suggestion of returning a
>>>reference for these functions is the way to do it.
>>>
>>>> What about throwing an out of board exception?
>>>
>>>Good idea but depends on how these functions should behave. You could for
>>>example let them wrap around the board.
>>>
>>>>>4) You could also declare other convenient functions outside of class CSquare:
>>>>>
>>>>>   bool IsAdjacent(const CSquare&, const CSquare&);
>>>>
>>>>while polymorphism is a nice thing to have, this function may also be member of
>>>>CSquare.
>>>
>>>I don't understand what polymorphism has to do with it but concerning your
>>>question if this function may also be member of CSquare:
>>>
>>>From the perspective of encapsulation - an important issue in OO - it is better
>>>to define IsAdjacent() as a non-member non-friend function in order to increase
>>>encapsulation.
>>>The idea is to separate the implementation issues of IsAdjacent() from the
>>>internals (read: non-public interface, i.e. protected and private interface) of
>>>CSquare by just using its public interface only - thus increasing encapsulation.
>>>If this can be done without a serious performance penalty this is surely the way
>>>to do it.
>>>Since IsAdjacent() can be implemented by using CSquare::GetFile() and
>>>CSquare::GetRank() that are both inlined member functions there is no
>>>performance penalty at all.
>>>A change of the internals of CSquare later in the development process does not
>>>effect (read: need to be changed) non-member functions like IsAdjacent() that
>>>rely on the public interface of CSquare only. In contrast all member functions
>>>of CSquare dependant on the internals are effected and need to be changed.
>>>
>>>Best,
>>>Alex
>>
>>
>>Just wondering about the design decision here ... I am not really sure if
>>IsAdjacent() should be external to CSquare.
>>It just so happens that , in this case , we can deduce the fact that one square
>>is adjascent to another by looking at the public interface.
>>IsAdjacent() would be similar to isEqual() ... something which the object has to
>>decide upon , not an external function.
>>
>>Example, a 0x88 CSquare , a 8x8 CSquare and a 12x12 CSquare would have different
>>ways of finding out who is adjescent to whom , etc ... if all of them extend
>>from CSquare - this can be simply handled by making IsAdjacent() a virtual
>>method of CSquare itself.
>>
>>Ofcourse , I could be misunderstanding the problem here.
>>
>>Thanks !
>>Mridul
>
>Dear Mridul,
>
>Everything you say is correct but doesn't address the encapsulation issue. By
>making IsAdjacent() a member function actually _reduces_ encapsulation!
>
>I don't think a square should decide if it is adjacent to another square.
>Adjaceny is a concept that goes way beyond of the concept of a square and should
>therefore be handled somewhere else.
>In contrast equality is a more fundemantal concept directly related to a class,
>so in this case you should declare and define a member function IsEqual() or
>operator==() in that class. Compare this to IsAdjacent() which doesn't make
>sense for most of the classes you can come up with.
>
>In your scenario of having CSquare as a base class with specializations of
>classes for 0x88, 8x8 or 12x12 derived from CSquare the concept of adjaceny can
>still be handled externally. In CSquare you still have in the public interface
>GetFile() and GetRank() as non-virtual member functions. The implementation for
>example of GetFile() calls a private member function DoGetFile() which is
>declared pure virtual in CSquare (making use of the NVI pattern - non virtual
>interface). Same for GetRank() with DoGetRank().
>In the specialized classes you implement DoGetFile() and DoGetRank()
>respectivly.
>The code for IsAdjacent() does not change at all, because it is _not_ dependent
>on the internal representations of a square in the specialized classes, not even
>dependent on the interface of the specialized classes (thanks to NVI), it only
>depends on the public interface of the base class.
>
>This is what encapsulation is all about! The concept of adjaceny is independent
>of the internal representation of a square. Even if you make CSquare a base
>class and introduce new specialized classes derived from CSquare it doesn't
>effect our function IsAdjacent().
>
>Best,
>Alex



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.