views:

92

answers:

4

// stupid title, but I could not think anything smarter

I have a code (see below, sorry for long code but it's very-very simple):

namespace Option1
{
    class AuxClass1
    {
        string _field1;
        public string Field1
        {
            get
            {
                return _field1;
            }
            set
            {
                _field1 = value;
            }
        }

        // another fields. maybe many fields maybe several properties

        public void Method1()
        {
            // some action
        }

        public void Method2()
        {
            // some action 2
        }
    }

    class MainClass
    {
        AuxClass1 _auxClass;
        public AuxClass1 AuxClass
        {
            get
            {
                return _auxClass;
            }
            set
            {
                _auxClass = value;
            }
        }

        public MainClass()
        {
            _auxClass = new AuxClass1();
        }
    }
}

namespace Option2
{
    class AuxClass1
    {
        string _field1;
        public string Field1
        {
            get
            {
                return _field1;
            }
            set
            {
                _field1 = value;
            }
        }

        // another fields. maybe many fields maybe several properties

        public void Method1()
        {
            // some action
        }

        public void Method2()
        {
            // some action 2
        }
    }

    class MainClass
    {
        AuxClass1 _auxClass;

        public string Field1
        {
            get
            {
                return _auxClass.Field1;
            }
            set
            {
                _auxClass.Field1 = value;
            }
        }

        public void Method1()
        {
            _auxClass.Method1();
        }

        public void Method2()
        {
            _auxClass.Method2();
        }

        public MainClass()
        {
            _auxClass = new AuxClass1();
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Option1
        Option1.MainClass mainClass1 = new Option1.MainClass();
        mainClass1.AuxClass.Field1 = "string1";
        mainClass1.AuxClass.Method1();
        mainClass1.AuxClass.Method2();

        // Option2
        Option2.MainClass mainClass2 = new Option2.MainClass();
        mainClass2.Field1 = "string2";
        mainClass2.Method1();
        mainClass2.Method2();

        Console.ReadKey();
    }
}

What option (option1 or option2) do you prefer ? In which cases should I use option1 or option2 ? Is there any special name for option1 or option2 (composition, aggregation) ?

+1  A: 

According to Law of Demeter, Option2. That way you can freely change the implementation of MainClass, You don't have to worry about calling code relying on details of AuxClass1, and indeed can remove it entirely if needed.

Matthew Flaschen
but most of the times it is hell to make your team believe that the Option2 is good one, though it needs you to write more code.
TheVillageIdiot
@TheVillage, tell them it's named after a Greek goddess. If that doesn't convince them, nothing will.
Matthew Flaschen
+1  A: 

EDIT

interface IAuxClass1
{
    string Field1 { get; set; }
    void Method1();
    void Method2();
}

class AuxClass1 : IAuxClass1
{
    string _field1;
    public string Field1
    {
        get
        {
            return _field1;
        }
        set
        {
            _field1 = value;
        }
    }

    // another fields. maybe many fields maybe several properties 

    public void Method1()
    {
        // some action 
    }

    public void Method2()
    {
        // some action 2 
    }
}

public class MyClass : ServiceContainer
{
    public MyClass()
    {
        this.AddService(typeof(IAuxClass1), new AuxClass1());
    }

    public MyClass(IAuxClass1 auxClassInstance)
    {
        this.AddService(typeof(IAuxClass1), auxClassInstance);
    }

    public IAuxClass1 AuxClass
    {
        get
        {
            return (this.GetService(typeof(IAuxClass1)) as IAuxClass1);
        }
    }
}

Original

I tihnk MainClass should derive from AuxClass..

class MainClass : AuxClass1
{ 

}
this. __curious_geek
No, this question is not related to inheritance. MainClass cannot derive from AuxClass. AuxClass is just a class with an additional functionality to MainClass.
alex
A: 

I would start with implementing a nice feature of C# called "automatic properties". Instead of writing

private ThisType _myThing;
public ThisType MyThing 
{ 
    get { return _myThing; } 
    set { _myThing = value; }
}

you can write

public ThisType MyThing { get; set; }

and the compiler will generate the exact same IL. On top of this, you can add some options, for example making the setter private:

public ThisType MyThing { get; private set; }

In your case, I would go for option 3:

namespace Option3
{
    public AuxClass
    {
        public string Field1 { get; set; }
        public Method1() { ... }
        public Method1() { ... }
    }

    public MainClass
    {
        public AuxClass Aux { get; private set; }
        public MainClass(AuxClass aux)
        {
            this.Aux = aux;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Option3.AuxClass = auxClass3 = new Option3.AuxClass();
        Option3.MainClass mainClass3 = new Option3.MainClass(auxClass3);
        mainClass3.Aux.Field1 = "string2";
        mainClass3.Aux.Method1();
        mainClass3.Aux.Method2();
    }
}

This way, you lock the AuxClass reference once it's set (like in Option 2) while not locking up yourself for changes in the AuxClass interface (like in Option 1).

Tomas Lycken
I know about auto-implemented properties, but i work on vs2005 so i can't use them. thanks for an option3!
alex
A: 

Decision of choosing design is based on different factors,

  1. Shorter code => Option 1
  2. Monitor activity of each functionality and every access => Option 2, however using linq and expressions, you can write a generalized code that can work with even option 1, but thats too complicated to discuss here.
Akash Kava