First we should acknowledge that LSP is just a principle, so its use isn't a
mandate.  That said, it's a good guide to help avoid some critical
misapplications of inheritance when designing object models.

I believe Add(int one) is preferred for two reasons:

1) The override of Add in DerivedLiskov is a violation of LSP, albeit a
relatively subtle one.  You've essentially changed the semantics of Liskov,
so the substitutability aspect is compromised.  As a consumer of Liskov (and
thus potentially DerivedLiskov), I have the expectation that Add(int one,
int two) do as it indicates, and having some magical number encapsulated in
the second parameter of a derived class compromises that.  A more egregious
break of LSP would be something like:

class Liskov { Add( // something useful ) }
class DerivedLiskov : Liskov { Add( throw new
NotImplementedException("...")) }

This has the same issue as yours:  You're changing the semantics by changing
the scope of behavior in the derived class, so a consumer of Liskov isn't
free to use DerivedLiskov without first considering its type.  This would
present an issue in a lot of scenarios (e.g. plug-in architecture that only
knows about Liskov).

2) As suggested above, the magic number in DerivedLiskov's Add is unclear to
consumers, and even with proper documentation you're still left with an
interface to your class that isn't as intuitive as it should be.  Someone
that hadn't even heard of LSP and its application should be at least
bothered by this, in my opinion.

Regards,
Chad

On Nov 20, 2007 1:36 PM, Abhijit Gadkari <[EMAIL PROTECTED]> wrote:

> I was doing some code review. I saw something interesting – Liskov
> implementation. [for more info, check out
> http://en.wikipedia.org/wiki/Liskov_substitution_principle]
>
> Here is the sample implementation of the same.
>
> namespace ToTest
> {
>    class Liskov
>    {
>        public Liskov()
>        {
>            //do nothing
>        }
>
>        public virtual int Add(int one,int two)
>        {
>            return one + two;
>        }
>    }
>
>    class DerievedLiskov :Liskov
>    {
>        public DerievedLiskov()
>        {
>            //do nothing
>        }
>
>        /// <summary>
>        /// <para>to add the number to itself.For Example - Add(4,0) will
> result 8</para>
>        /// </summary>
>        /// <param name="one"></param>
>        /// <param name="two"></param>
>        /// <returns></returns>
>        public override int Add(int one, int two)
>        {
>            if (two == 0)
>            {
>                return one + one;
>            }
>            else
>            {
>                return base.Add(one, two);
>            }
>        }
>
>        public int Add(int one)
>        {
>            return one + one;
>        }
>    }
> }
>
> Now, I know there is no validation here. But the point is about
> substitution principle. Here we have Add method in the base class. An
> override in derived class will substitute it.
>
> SO if we want to change the behavior of Add method such that it will
> accept only one integer and will return the result as int added to itself
> [i.e. 3+3=6],we have two options as coded in the DerievedLiskov. Which one
> is beter from oo design point?
>
> Thanks.
>
> Abhi
>
> ===================================
> This list is hosted by DevelopMentor(R)  http://www.develop.com
>
> View archives and manage your subscription(s) at
> http://discuss.develop.com
>

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to