Click here to Skip to main content
11,923,948 members (65,388 online)
Rate this:
Please Sign up or sign in to vote.
I have a design question for the geeks. I shall present a hypothetical situation.
I have a couple of interfaces required by my application to make an object usable. Let’s say they are;

1. IAdult.cs, with two properties
a. Age
b. LicenceNo.
2. IEducated.cs, with two methods
a. Read()
b. Write()

If we had to implement an abstract class out of these interfaces, we could simply create a class, say, abstract class EducatedAdult{}. Let’s assume that the implementation of these interfaces shall remain the same most of the times.

Now we define three different objects with their own respective inheritances and a set of respective properties;

1. Carpenter.cs (derives from class A)
2. Plumber.cs (derives from class B)
3. Programmer.cs (derives from class C)

(Here class A, B, C belong to an external library) Now to make these objects usable in the Program, they need to implement the above given interfaces. So the issue is that for each one of these classes, I’ll have to explicitly implement the above stated interfaces. Could there be a better design where I do not have to implement the interfaces redundantly in all the classes. This could be a solution, had it been possible;
class EducatedAdult<t>: t, IAdult, IEducated 
 <implementation of="" interfaces=""> 
And later, maybe, I could just initialize my derived classes like;

Carpenter carpenter = new EducatedAdult<carpenter>().</carpenter>

Not that this would be an ideal solution, ‘cause the public interface of the carpenter object shall still not include my interface members (without required casting). But then, what could be the most suitable design?
Posted 30-Apr-11 0:10am
Edited 30-Apr-11 0:58am
Albin Abel 30-Apr-11 6:18am
Hi VermaManish, Is the response solved your issue or still waiting for a better response? :)
Nishant Sivakumar 30-Apr-11 12:37pm
Dude, you are everywhere huh? SO, CP, and MSDN? :-)
VermaManish 30-Apr-11 12:51pm
Who me? No! Its Lord Krishna who's everywhere - The Omnipresent! :)
Nishant Sivakumar 30-Apr-11 12:54pm
No, not you. I meant Albin. And Krishna is not omnipresent, if so he'd have been there for the WC finals and he clearly wasn't! *grin*
Albin Abel 30-Apr-11 14:48pm
Hi Nishant, It is nice to meet you everywhere too. :) :)
VermaManish 30-Apr-11 6:23am
Hi Albin,
Nice to see you here. But I am still looking for a better design.
Rate this: bad
Please Sign up or sign in to vote.

Solution 3

Your problem is classified in two parts:
1) Adequate modeling,
2) Technical aspects of week form of multiple inheritance.

1) Adequate modeling

I think you missing one important principle: if you have 1-3 design options using different technical tools. You cannot just ask "what could be the most suitable design?". It depends on semantic of the members of you terminal classes; if you know the classes and the members, you should fist ask "do I really need them?".

Let me illustrate this. What is IAdult? I don't need it! You need IPerson or just a class Person. A person always has the age and can have null or non-null License. It would cover all people including children. When a child obtains License, the class instance changes. For this purpose, your need LicenseNumber? (nullable type). You don't need age, ever. You need date of birth instead. Having age will cause you to change the instance all the time.

You don't need IEdicated as well. Consider everyone as educated, this is fair. You should create a type Education. All persons will instantiate the instance of this type, but the qualify of education will be changed; so the values in this instance will change (grow, hopefully).

What complexity has left? None! You see, by simple analysis I removed all your needs in multiple inheritance by turning it all into on single base class. I made the picture simpler technically yet more adequate to the real life we're trying to model.

2) Technical aspect of week form of multiple inheritance.

After the model is simplified, let's go back to multiple inheritance from more then one interface, so called week form of multiple inheritance. How to make different implementation in different classes in a way free from a predefined hierarchy of implementation classes? I don't want to use your interfaces anymore. Let's talk about interfaces IFirst and ISecond.

I would suggest using a technique of implementation helpers. Something like this:

public interface IFirst {
    void A();
    void B();
public interface ISecond {
    void A();
    void C();
public class FirstHelperDetail { }
public class FirstHelper : IFirst {
    public FirstHelper(FirstHelperDetail userDetail) {
        this.UserDetail = userDetail;
    void IFirst.A() { /* implementaion using UserDetail */ }
    void IFirst.B() { /*...*/ }
    FirstHelperDetail UserDetail;
public class SecondHelper : ISecond {
    public SecondHelper(System.Func<string, bool> userPredicate) {
        this.UserPredicate = userPredicate;
    void ISecond.A() { /* implementaion using UserDetail */ }
    void ISecond.C() {
        if (UserPredicate != null) { /*...*/ }
    System.Func<string, bool> UserPredicate;
class User : IFirst, ISecond {
    internal User(/*...*/) {
        FirstHelper = new FirstHelper(new FirstHelperDetail(/*...*/));
        SecondHelper = new SecondHelper(predicate);
    void IFirst.A() { FirstHelper.A(); }
    void IFirst.B() { FirstHelper.B(); }
    void ISecond.A() { SecondHelper.A(); }
    void ISecond.C() { SecondHelper.C(); }
    IFirst FirstHelper;
    ISecond SecondHelper;
    System.Func<string, bool> predicate = (name) => { /* use name... */; return false; };

The sample demonstrate separate techniques of parametrization of helpers. Also, pay attention to explicit form of interface method implementation; this style is usually better then public: the method can not be called through the reference as class, only as interface which provide nice isolation. In particular, one can have too methods A of the same signatures. This style of interfacing is of course optional.

VermaManish 1-May-11 5:19am
This is perfectly valid in some cases. We could even use extension methods that can achieve the same pattern a little more elegantly. But let's agree to your argument that we should have bigger preference for language independent semantics. And so, your approach of using implementation helpers seems quite valid. But Nishant’s solution has one big advantage - we are able to encapsulate the implementation of our interfaces. This advantage of (encapsulated implementation) holds big relevance in case of my solution, even if it is at the cost of using language specific semantics. And after all, if everybody would avoid using language specific semantics, there wouldn’t be a need for second language. But I do really appreciate a good pattern that your solution manifests. Thanks
SAKryukov 1-May-11 14:45pm
Would you formally accept this answer?
I think it is adequate based on your formulation of the problem.
VermaManish 2-May-11 3:17am
With pleasure! But it was Nishant's solution (Solution 3) that worked for me.
SAKryukov 2-May-11 4:17am
Thank you, Verma. It's good Nishant's code was better for your, but I hope you understand I provided some wider understanding of the problem. Isn't it the meaningful criterion for acceptance of the solution, along with ad-hoc purpose? :-)
Albin Abel 2-May-11 0:07am
My 5 for language independent semanatics. This way provide little flexibility to the user class how to use the interface implementation, whereas encapsulating the interface methods hinders further flexibility. void IFirst.A() { FirstHelper.A(); } and I have flexibility to use void IFirst.A() { NewHelper.A(); }. By design I like this way. Nishant's answer satisfy Verma's question. So question answered and you solution is a better design. :) 5++
SAKryukov 2-May-11 1:18am
Thank you, Albin. I only did not understand what language-independent did you find in my solution. Everything using just the framework is really language-independent; and my syntax is C#-only...
Albin Abel 2-May-11 9:12am
Your syntax is c#, but this model is applicable to other object oriented languages as well, except the predicate things. :)
SAKryukov 2-May-11 13:45pm
What a minute. Predicate is just a variable name, common for all languages, in my code it only requires generics which is common to all languages, but anonymous is not...
Albin Abel 2-May-11 14:47pm
Right, you were talking about syntax, these lamda syntax is not common to all languages
SAKryukov 2-May-11 1:21am
As to better design or not... I tried to demonstrate that the design really depends on the real-life problem and its modeling. Good technical approach to one case maybe pretty bad for another...
Thank you.
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

Here's a simplified example of one possible approach :

class Program
    static void Main()
        EducatedAdult<Carpenter> eac = new EducatedAdult<Carpenter>();
        eac.Age = 10;
        Carpenter cpr = eac;
interface IAdult
    int Age { get; set; }
interface IEducated
    void Read();
class EducatedAdult : IAdult, IEducated
    public void Read()
    public int Age
            return 18;
class A { }
class Carpenter : A
    public void DoWork()
class B { }
class Plumber : B { }
class EducatedAdult<T> : EducatedAdult where T:new()
    private T t;
    public EducatedAdult()
        this.t = new T();
    public static implicit operator T(EducatedAdult<T> eat)
        return eat.t;
VermaManish 30-Apr-11 13:31pm
I think your solution is par excellent!
I'll have to do few more tests related to serializing the generic EducatedAdult, before I come back.
Albin Abel 30-Apr-11 14:49pm
Sure, my 5++
SAKryukov 30-Apr-11 23:14pm
Things can be simplified through better analysis but needs some more flexibility; also, the final solution depends on semantic.

Please see my variant.
Rate this: bad
Please Sign up or sign in to vote.

Solution 1

How about some sort of construct like:

class MyCarpenter : carpenter
    public EducatedAdult EA = null;
    public MyCarpenter()
        EA = new EducatedAdultSubClass();

i.e. embed rather than inherit - you can put whatever behaviours you like in your EducatedAdult class and any sub-classes (do you even need the base EducatedAdult class to be abstract?) and implement them once only.

I'm sure others will come up with alternative ways of doing it, but this seems to me to be relatively straightforward.
VermaManish 30-Apr-11 6:22am
The application that shall use these objects identifies the interfaces (IAdult, IEducated) only. So I need to implement these contracts to make these objects (Carpenter, Programmer, Plumber) usable.
SAKryukov 30-Apr-11 23:12pm
The idea make sense and should be use an many cases but have limitations. Could be a variety of methods. My 4. Thinks are more simple and more complext at the same time.

Please see my solution.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy | Mobile
Web04 | 2.8.151125.3 | Last Updated 30 Apr 2011
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100