I've been learning to design with OOD and stuck with a scenario.
I have a class User
which extends an abstract class Person
. Class Person
has a member with type Address
. User
only have Username and Password, and Address
have some string fields.
Now, I want to add a class Client
which can be a Person
or an Organization
(to be added). Client
will have some data also.
I thought about interfaces but they can have only methods. Can anyone help me with what will be the proper design?
I'm not following any pattern and coding with C#.NET.
I think I could not explain the scenario properly. Sorry for that. Please, have a look on the diagram. Here, the Client
class is what I want to add.
Try to work with composition. A person and an organization are not necessarily a user, although they both can HAVE an address or a user account. Actually they most likely have more than one of both.
If you think more in terms of HAS A and less in terms of IS A you can come up with more maintainable choices.
For instance you can have a
class Address {
public string street {get; private set;}
public string city {get; private set;}
public AddressTypes AddressType {get; private set;} // an enum to differentiate
// "home address", "legal address"
...
}
now, if you need to model the fact that both a Person
and a Organization
are things that must have Address
es, you can create an interface
interface IAddressable {
IEnumerable<Address> {get;}
}
and have both Person
and Organization
implement it. The same can be done with an Account
class that holds Username
and Password
.
Now Person
and Organization
don't need to BE User
s, but they can both HAVE Accounts, Addresses and anything else you need. And you can force them to have these things via interfaces, as shown above.
As for Client
, I can see your problem. You are tempted to say that "a Person (or an Organization) IS a Client". But in your design "a Person IS already a User" and you can't have Person inherit from two different base classes.
However, note that a Person is not necessarily a client. I'm not sure what a Client exactly is in your model, but let's assume it's someone with an Address and an Account who can be a Person or an Organization (and you want to know if it's one or the other). You can do this in several ways, but one could be:
abstract class Client : IAddressable, IWithAccount {
// implement IAddressable and IWithAccount
}
class PersonClient : Client
{
public PersonClient(Person person)
{
// make the Client's address refer to the Person's address
// make the Client's account refer to the Person's account
}
}
class OrganizationClient : Client
{
public OrganizationClient(Organization organization)
{
// make the Client's address refer to the Organization's address
// make the Client's account refer to the Organization's account
}
}
the advantages are that:
StateClient
without changing the existing piecesIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With