9

I have looked on line for information that would help me solve a design issue that is confusing me. I am new to complicated inheritance situations so my solution could actually just be rooted in a better design. But in trying to figure out what my design should be, I keep ending up thinking I really just need to inherit more than 1 base class.

My specific case involves Assets and different types of Assets.

Starting with the Asset...

Every PhysicalDevice is an Asset
Every VirtualDevice is an Asset
Every Server is an Asset

Every PhysicalServer would need to be both a PhysicalDevice and a Server
Every VirtualServer would need to be both a VirtualDevice and a Server
Every NetDevice is a PhysicalDevice
Every StorageArray is a PhysicalDevice

One solution I guess is to duplicate the Server code for both PhysicalServers, and VirtualServers however, I feel like this goes against what im trying to do, which is inherit.

They need to be separate classes because each of the types will have properties and methods. For instance, Server will have OSCaption, Memory, Procs, etc. PhysicalDevice will have things like Location, Serial, Vendor etc. And VirtualDevice will have a ParentDevice, State, VHDLocation etc.

If the inheritance is liner then i run into the problem of not being able to describe these types accurately.

Something that seems intriguing is Interfaces. It seems that i can define all base classes as interfaces and implement them in my main classes as needed. but, I am simply unsure of what the implications are if I were to do that.

for instance, something like... PhysicalServer : IAsset : IServer : IPhysical

I am in deep water so I’m really just looking for suggestions or guidance.

1
  • Please don't add "C#" to the ends of your titles. That's what the tags are for. Commented Feb 16, 2012 at 6:45

4 Answers 4

8

Interfaces are an appropriate way of ensuring contract integrity across types, but you may end up with duplicate code for each implementation.

Your scenario may lend itself better to composition than inheritance (or a combination thereof).

Example - Inheritance + Composition

public class PhysicalServer : Asset
{
    public PhysicalInfo PhysicalProperties
    {
         get;
         set;
    }
}

public class VirtualServer : Asset
{
    public VirtualInfo VirtualProperties
    {
         get;
         set;
    }
}

Example - Composition Only

public class VirtualServer
{
    public VirtualInfo VirtualProperties
    {
         get;
         set;
    }

    public AssetInfo AssetProperties
    {
         get;
         set;
    }
}

You could then add polymorphism/generics into the mix and create derivatives of types to represent more specific needs.

Example - Inheritance + Composition + Genericized Member that inherits from a common type

public class VirtualServer<TVirtualInfo> : Asset
   where TVirtualInfo : VirtualDeviceInfo
{
    public TVirtualInfo VirtualProperties
    {
         get;
         set;
    }
}

public class VirtualServerInfo : VirtualDeviceInfo
{
   // properties which are specific to virtual servers, not just devices
}

There are countless ways that you could model this out, but armed with interfaces, composition, inheritance, and generics you can come up with an effective data model.

Sign up to request clarification or add additional context in comments.

6 Comments

+1 for composition over inheritance - I find most situations where inheritance is causing some head scratching can be resolved through a compositional approach.
To be clear, use interfaces on classes to define what they do. Then compose them of private members that can do the work required by the interfaces. Yes?
@MStodd - yes, if objects share the same contract (members and operations), that contract can (and often should) be defined in an interface. Different types can then also be cast to the same interface and handled uniformly.
This will take some research to figure out exactly what this means but i think I basiclly understand. Compisition relates to a HAS-A rather than a IS-A realtionship?
@jwrightmail - Correct. I know this is a lot of information to process. I would suggest 1) drawing out your basic objects and identifying commonalities 2) experimenting with interfaces and generics and 3) reading up on common design patterns.
|
3

Use mixins.

You first decide which is the primary thing you want your object to be. In your case I think it should be server.

public class PhysicalServer : Server

Then you add interfaces for the other functionalities.

public class PhysicalServer : Server,IAsset,IVirtualDevice

And you add extension methods to the interfaces.

public static int WordCount(this IAsset asset)
{
  //do something on the asset
}

Here's an article on mixins in case my answer is too simple: http://www.zorched.net/2008/01/03/implementing-mixins-with-c-extension-methods/

Comments

1

C# doesn't support multiple inheritance from classes (but does support multiple implementations of interfaces).

What you're asking for is not multiple inheritance. Multiple inheritance is where a single class has more than one base class. In your example each class inherits from one/zero other classes. Asset and Server being the ultimate base classes. So you have no problem doing that in c#, you can just define the functionality common in eg server and then do different things in VirtualDevice and PhysicalDevice.

However you will end up with a possibly complex class hierarchy and many people would advocate composition over inheritance. This is where you'd have interfaces defining behaviour and classes implement the interface to say that they do something but each class can implement the interface methods differently. So your example for the PhysicalServer interfaces may be encouraged.

2 Comments

I would like to clarify that Server inherits from Asset. I am unsure if that makes them both "ultimate base classes". The distinction is important because I am not only dealing with servers but all different types of both Virtual and Physical types of Assets. This includes servers yes, but also AttachedStorage, NetworkThing types, etc... In the end I want to be able to have the base classes necessary, to basically allow for scalability to any new asset Type that might arise.
Well then only Asset is the ultimate base class and as suggested, composition should generally be preferred with limited inheritance where appropriate
0

To start with remember that inheritance is the obvious result of the kind of problem that you have mentioned. Every class does have more than one behavior and everyone falls into this trap. So chill. You are not the first nor the last.

You need to modify your thinking a bit to break away from the norm.

You need to look at it from the angle of what "changes" in future rather than look at a hierarchical kind of class diagram. A class diagram may not be hierarchical instead it needs to represent "what changes" and what "remains constant". From what I see, in future you may define a MobileDevice, VirtualMobileDevice.

In your current classes you seem to have properties like Vendor, Serial. These may be needed in MobileDevice too right ? So you need to modify your thinking to actually think of behaviors instead of classes that make hierarchical sense.

Rethink, you are going down the track of multiple inheritance, very dangerous and complex design. Its not the correctness of your thought process that is in question here. Its the question of you coding something and someone up ahead in the near future complicating it beyond repair.

No multiple inheritance in java is there for this one reason, to ensure that you dont think the hierarchical way.

Think "factories" (for creation), strategy (for common functionality/processing).

Edited :

Infact you should also consider creating layers in the form of library, so that there is complete abstraction and control on the main parts of your processing. What ever you intend to do with the Asset/Device class should be abstracted into a library, which can be protected by change.

1 Comment

Interesting, and thank you. Yes your example of future types is spot on. The ability to scale with asset types would be greatly benificial to sort out now rather than have to come back much later and up root core plumbing. ...Behaviors, I will ponder on this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.