Skip to main content
added 407 characters in body
Source Link
svidgen
  • 15.3k
  • 3
  • 40
  • 63

To make sure all classes which have hierarchical components do this I created an abstract class which they all inherit so no one forgets to do it both ways.

An interface would also "remind" developers to add those methods.

.. how do I design my classes so they do get the functionality they need (and share with other classes) without creating an abstract class.

If the amount of duplicative code is small or simple, use an interface and just force inheritors to write their own implementations. In your example, AddChild(), AddParent(), RemoveChild(), and RemoveParent() all seem pretty straightforward and simple to build.

But, if the implementations are difficult for you to repeat, you could provide an "inner" class (like TreeNode) for inheritors to wrap:

class DomNodeOrSomething<T> : ITreeNode
{
  private TreeNode data = new TreeNode<T>();

  void AddChild(T item)
  {
    data.AddChild(item);
  }

  void AddParent(T item)
  {
    data.AddParent(item);
  }

  void RemoveChild(T item)
  {
    data.RemoveChild(item);
  }

  void RemoveParent(T item)
  {
    data.RemoveParent(item);
  }
}

And, if that doesn't float your boat, use extension methods.

In the example from MS, a WordCount() method is added to the String interface. When this namespace is included, all String's will "automagically" have a .WordCount() method dangling off them.

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}

I believe you can do the same sort of thing for any interface. Something like:

namespace ExtensionMethods
{
  public static class TreeNodeExtensions
  {
    public static void AddChild(this ITreeNode self, ITreeNode item)
    {
      self.children.add(item);
    }
  }
}

This would still require that the ITreeNode interface force inheritors to provide common properties that the extension methods can manipulate.

To make sure all classes which have hierarchical components do this I created an abstract class which they all inherit so no one forgets to do it both ways.

An interface would also "remind" developers to add those methods.

.. how do I design my classes so they do get the functionality they need (and share with other classes) without creating an abstract class.

If the amount of duplicative code is small or simple, use an interface and just force inheritors to write their own implementations. In your example, AddChild(), AddParent(), RemoveChild(), and RemoveParent() all seem pretty straightforward and simple to build.

But, if the implementations are difficult for you to repeat, you could provide an "inner" class (like TreeNode) for inheritors to wrap:

class DomNodeOrSomething<T> : ITreeNode
{
  private TreeNode data = new TreeNode<T>();

  void AddChild(T item)
  {
    data.AddChild(item);
  }

  void AddParent(T item)
  {
    data.AddParent(item);
  }

  void RemoveChild(T item)
  {
    data.RemoveChild(item);
  }

  void RemoveParent(T item)
  {
    data.RemoveParent(item);
  }
}

And, if that doesn't float your boat, use extension methods.

In the example from MS, a WordCount() method is added to the String interface. When this namespace is included, all String's will "automagically" have a .WordCount() method dangling off them.

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}

I believe you can do the same sort of thing for any interface.

To make sure all classes which have hierarchical components do this I created an abstract class which they all inherit so no one forgets to do it both ways.

An interface would also "remind" developers to add those methods.

.. how do I design my classes so they do get the functionality they need (and share with other classes) without creating an abstract class.

If the amount of duplicative code is small or simple, use an interface and just force inheritors to write their own implementations. In your example, AddChild(), AddParent(), RemoveChild(), and RemoveParent() all seem pretty straightforward and simple to build.

But, if the implementations are difficult for you to repeat, you could provide an "inner" class (like TreeNode) for inheritors to wrap:

class DomNodeOrSomething<T> : ITreeNode
{
  private TreeNode data = new TreeNode<T>();

  void AddChild(T item)
  {
    data.AddChild(item);
  }

  void AddParent(T item)
  {
    data.AddParent(item);
  }

  void RemoveChild(T item)
  {
    data.RemoveChild(item);
  }

  void RemoveParent(T item)
  {
    data.RemoveParent(item);
  }
}

And, if that doesn't float your boat, use extension methods.

In the example from MS, a WordCount() method is added to the String interface. When this namespace is included, all String's will "automagically" have a .WordCount() method dangling off them.

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}

I believe you can do the same sort of thing for any interface. Something like:

namespace ExtensionMethods
{
  public static class TreeNodeExtensions
  {
    public static void AddChild(this ITreeNode self, ITreeNode item)
    {
      self.children.add(item);
    }
  }
}

This would still require that the ITreeNode interface force inheritors to provide common properties that the extension methods can manipulate.

Source Link
svidgen
  • 15.3k
  • 3
  • 40
  • 63

To make sure all classes which have hierarchical components do this I created an abstract class which they all inherit so no one forgets to do it both ways.

An interface would also "remind" developers to add those methods.

.. how do I design my classes so they do get the functionality they need (and share with other classes) without creating an abstract class.

If the amount of duplicative code is small or simple, use an interface and just force inheritors to write their own implementations. In your example, AddChild(), AddParent(), RemoveChild(), and RemoveParent() all seem pretty straightforward and simple to build.

But, if the implementations are difficult for you to repeat, you could provide an "inner" class (like TreeNode) for inheritors to wrap:

class DomNodeOrSomething<T> : ITreeNode
{
  private TreeNode data = new TreeNode<T>();

  void AddChild(T item)
  {
    data.AddChild(item);
  }

  void AddParent(T item)
  {
    data.AddParent(item);
  }

  void RemoveChild(T item)
  {
    data.RemoveChild(item);
  }

  void RemoveParent(T item)
  {
    data.RemoveParent(item);
  }
}

And, if that doesn't float your boat, use extension methods.

In the example from MS, a WordCount() method is added to the String interface. When this namespace is included, all String's will "automagically" have a .WordCount() method dangling off them.

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static int WordCount(this String str)
        {
            return str.Split(new char[] { ' ', '.', '?' }, 
                             StringSplitOptions.RemoveEmptyEntries).Length;
        }
    }   
}

I believe you can do the same sort of thing for any interface.