views:

171

answers:

5

Which is the better approach

public class Account
{
  public UserAccount GetUserDetails(string acctId)
  {
    return new UserAccount().GetDetails(); //call method from class UserAccount
  }

  public UserAccount GetUserDetails(string acctId)
  {
    return new UserOtherDetails().GetDetails(); //call method from another class
  }
}

or contain the class like this

public class Account
{
  private UserAccount userAccount; //contain UserAccount class
  private UserOtherDetails userOtherDetails;

  public UserAccount GetUserDetails(string acctId)
  {
    return userAccount.GetDetails(); //invoke the method from UserAccount class
  }

  public UserOtherDetails GetOtherDetails(string acctId)
  {
    return new userOtherDetails().GetDetails(); //call method from another class
  }
}

or any other approach guys?

EDIT: what if I Add parameters on the method?

Additional: My point here is I don't want to instantiate UserOtherDetails class when I'm calling the GetUserDetails Method

+4  A: 

As the userAccount will have to be initialized somehow [at least passing account number], I would prefer to use second one.

Tomasz Kowalczyk
+1  A: 

I don't work with C#, but personally I am not totally for this kind of aggregation. You would use something like that when you need some other implementation other than what UserAccount::GetDetails() provide or if you want Account to be a factory for different kinds of more specific accounts.

Going back to the question, I prefer the second approach if that helps you somehow.

hyperboreean
+2  A: 

You second approach is better. The first approach is nasty because everytime you call GetUserDetails a new instance of the UserAccount class will be created.

You could also just expose this as a property

public class Account
{
  public UserAccount Details {get; private set;}
}

Here is an example

public class Account 
{ 
  public UserAccount UserDetails {get; private set;}
  public UserOtherDetails OtherDetails {get; private set;} 

  public Account (UserAccount userDetails, UserOtherDetails otherDetails)
  {
    this.UserDetails = userDetails;
    this.OtherDetails = otherDetails;
  }
} 

The above assumes you have already loaded the UserDetails and UserOtherDetails. If you want to load the details on demand then you might do something like this.

public class Account 
{ 
  private UserAccount _userDetails;
  private UserOtherDetails _otherDetails;

  public GetUserAccountDetails(string accountId)
  {
    if (_userDetails == null)
    {
      // This could be a nice place to look at various factory patterns.
      _userDetails = new UserAccount();
      _userDetails.Load(accountId);
    }
    return _userDetails;
  }

  ...
} 
Chris Taylor
GetUserDetails is method , and what if I put parameters on the method.. GetUserDetails(string accountId) and accountId is not a property of UserAccount?
CSharpNoob
@CSharpNoop, I think my second example addresses this question. I also updated it to include the passing of the accountId.
Chris Taylor
If I call GetUserAccountDetails method, Is this also instantiate UserOtherDetails?
CSharpNoob
@CSharpNoob, based on what I understand from you examples I believe these look like to independent pieces of information. So you would implement GetOtherDetails using the same patter as the GetUserAccountDetails. Of course that is if they are independent, if not then you would probably be better to put them into a single class.
Chris Taylor
+1  A: 

Getters and setters would be the easy way to go:

public class User
{
    public string Name { get; set; }
    public string TagLine { get; set; }
}

public class Account
{
    public User Owner { get; set; }
}

// then...
Console.WriteLine(account.Owner.Name);
Console.WriteLine(account.Owner.TagLine);
Douglas
I cant do that, what if the GetUserDetails has parameters? GetUserDetails(string userId)
CSharpNoob
+1  A: 

As always: It depends.

The first example creates a new instance of UserAccount for every call, whereas the second example reuses an instance that was created previously. Answering which option is better is not possible without knowing what UserAccount represents and what it's constructor does.

Are you considering option 1 because you want to avoid creating a UserAccount object if the method is never called? In that case, lazy loading might be what you want:

private UserAccount userAccount;

public Details GetUserDetails()
{
    if (userAccount == null)
        userAccount = new UserAccount();
    return userAccount.GetDetails();
}
Heinzi
"Are you considering option 1 because you want to avoid creating a UserAccount object" - YES exactly.. so im thinking option 1 performance wise is better, but option 2 looks good..
CSharpNoob
@CSharpNoob: Not necessarily: If GetUserDetails is called 3 times, option 1 creates three objects, whereas option 2 uses the same object all the time. The lazy loading option presented in my answer creates zero objects if the method is never called, an exactly one object if it is called one or more times.
Heinzi
@Heinzi this is a very obscure pattern....I don't mean lazy loading, but returning only the details. Are you going to implement lazy loading in all properties that return a property of userAccount?
Caspar Kleijne
@Caspar: I assumed that userAccount.GetDetails returing (again) a UserAccount is a mistake. Of course, returning the UserAccount itself might make more sense, but CSharpNoob might have his reasons for making only a few of UserAccount's methods available...
Heinzi