2

In a project I have following class relationship. Employee and Client have a composition relationship with Company. So implemented this as follows.

class Company
{
    private Employee _Employee {get;set;} // private fields as composition
    private Client _Client {get;set;}

    public Company()
    {
        _Employee = new Employee();
        _Client = new Client();
    }

    public AddEmploees() //Employee objects are controlled by Company
    {
        //
    }

    public DeleteEmploees()
    {
        //
    }

    public AddClients() //Client objects are controlled by Company
    {
        //
    }

    public DeleteClients()
    {
        //
    }
}


class Employee
{
    string Name {get;set;} 
    int ID {get;set;}
    string Address {get;set;}
    string Department  {get;set;}
    DateTime DOB {get;set;}

    private Employee() // constructor private
    {
    }
}


class Client
{
    string CID {get;set;}
    string Name {get;set;}
    string Type {get;set;}
    DateTime StartDate {get;set;}
    string Address {get;set;}

    private Client() // constructor private
    {
    }    
}

When I want to show client / employee details on the UI my DataService is supposed to return a Company object rather than returning Employee/Client objects as the relationship is composition. So I could have a method like GetDetails() in my DataService and then get the required details from the database to assign for properties of Employee and Client. But now the problem is, I will not be able to access private fields (_Employee , _Client) of Company object to set values for the properties as follows

public Company GetDetails()
{
Company company = new Company();
string selectStatement = "SELECT...";
// Get data from DB
company.client.name = rdr["name"].value;  // This is not possible.
.
.
.
}

Though I have few ideas to sort out this problem but non of them are seems adaptable to this class relationship (composition) or either violating separation of concerns principle. Appreciate your help in this regard?

CAD
  • 4,112
  • 6
  • 29
  • 47
  • Why this would not be possible? – Wiktor Zychla May 25 '14 at 16:32
  • Because Client property of contained class Company is private. – CAD May 25 '14 at 16:48
  • 1
    Either you make a public property that wraps it `public Client Client { get { return _client; } }` or you have a public method to access individual properties `GetClientName` / `SetClientName`. SoC has nothing to do with this design, in my opinion. You are rather constained with SOLID principles and this doesn't violate any of these rules. – Wiktor Zychla May 25 '14 at 17:32

2 Answers2

1

It looks like you want to use the

MSDN: Factory Design Pattern

For implementation of the mutual visibility (aka C++ friend class) you can use the

internal visibility modifier

instead of the private visibility. This will allow r/w access to properties of other objects. Microsoft uses it also heavily (internal classes, internal namespaces, see e.g. http://referencesource.microsoft.com/#PresentationFramework/src/Framework/MS/Internal/Data/CollectionViewGroupInternal.cs) so it is not a banned design practice as long as it helps

Community
  • 1
  • 1
xmojmr
  • 8,073
  • 5
  • 31
  • 54
0

You can resolve your problem by invoking GetDetails() from the Company object itself, instead of externally. Something like this:

class Company
{
    // other class features

    public static getDetails(params) // params are there as a filter (if needed)
    {
        // connect to DB and get the data...
        //
        // here you can access private members of Company

        // return array of companies (or a single company)

    }
}

I find this solution far better in OO sense as yours. Class Company relies on itself to get its data via a static method. You do not need to instanciate a COmpany before getting an instance. And more - the private data is nicely protected and invisible to the external world. In your solution, even if you could access the private members from outside, it would be breaking the encapsulation and that's not good.

I would also reconsider using composition to store Clients and Enployees, as their natural relationship with a company is weaker. If a Company "dies", that definitelly does not mean that its Employees of CLients will also die.

Aleks
  • 5,674
  • 1
  • 28
  • 54