3

At start, I have these classes in code and consequently tables in the database.

Person
Company
Address

Both Person and Company have an address. So I have to establish a relationship between them. Person one - Address many (let's say a person can have more than one address). I know the same address can be for two persons, but that's not important as this is not relationship critical (won't search by address).

Company has an address too. So in class Address I would have both relations to Person and Company. In code, this is not a problem, but in the desing model, it shows both foreign keys and columns, and this makes for me some ambiguity when displaying on the screen (I can hide it though).

I was thinking to create another class: CompanyAddress which will inherit Address and have only one property which will hold key to Address class)

So this is idea:

CompanyAddress : Address
{
}

and

PersonAddress : Address
{
}

So CompanyAddress and PersonAddress would inherit Address class and be used to hold relation (foreign key) to Company and Person classes. This will display in database in 2 possible ways (it can show foreign keys in same table (Address) or it can store foreign key in its own table CompanyAddress). I prefer to store in same table not to use joins.

I can choose in database to have Address table that stores also foreign keys of Person and Company (this is fine I think). Or I can have PersonAddress table which stores only key and all other fields are in Address table. I prefer first approach. Still OOP model can be different for obvious reasons since it can simplify desing model where you dont have to hide keys of Company when displaying Person address in UI design model. So you see benefit of different OOP models.

Code

public class Address
{
    public string Street  { get; set; }
    public string City    { get; set; }
    public string ZIPCode { get; set; }
    public string County  { get; set; }
}

public class Person
{
    public string Name    { get; set; }
    public string Surname { get; set; }
    // relationship here one to many with class PersonAddress 
    // note: I cannot write code as I use some third party controls
    // which code is much different for usage in relationships
}

public class Company
{
    public string CompanyName   { get; set; }
    public string CompanyNumber { get; set; }
    // relationship here one to many with class CompanyAddress 
}

public class CompanyAddress : Address 
{
    // a relation with Company class
}

public class PersonAddress : Address
{
    // a relation with Person class
}

Is this good OOP or it is a bad idea?

4
  • It doesn't seem sensible for addresses to have references to the company or person that occupies them, unless the concept of physical "premises" (which may be informally called "an address", which may be occupied by multiple persons and companies, and which may also have an occupation history) is relevant to your model. It also doesn't seem sensible to have specific kinds of address class for each, unless again there are Premises in your model and there is a firm distinction between business and personal premises.
    – Steve
    Jun 2, 2019 at 20:18
  • @Steve Of course, there are multiple persons, not one person. And one person can have multiple address. One address can have multiple persons living in same building, but is that important? Its not. So therefore relationship is one to many. Same is with Company, company resides on some address. Jun 4, 2019 at 10:43
  • @Steve It can have one or multiple addresses, though for the company not so important. Why I have made distinction between CompanyAddress and PersonAddress (though they are in stored same table Address) is because of UI model that makes it easier to do UI (in UI it will not show Person foreign key in company address and vice versa, so I don't have bogues tasks to hide Person foreign key when Company Address is displayed). This model perfectly suits for my needs as it is CRUD based application. Jun 4, 2019 at 10:43
  • just a note: most apps are CRUD based, with no specific logic involved. Jun 8, 2019 at 15:23

4 Answers 4

4

It's actually hard to say whether your object-oriented design is good or bad: At the moment all you have is some pure data objects (only setters and getters) - see Anemic Domain Model. In short: Good OOP design is when your classes do have non-trivial behavior, which helps you to deal with the cases at hand.

Please also note, that Company and Person are more likely entities (their identities matter), while Address is probably just a Value Object, and how it is stored is secondary matter.

Model (and object model is no different) can't be good or bad without relation to the problem you are solving. For one problem you may need an object for every street, and for another - everything you have added to one denormalized database table.

In a sense, object-oriented design should capture characteristics and behaviors of the domain objects and communication between objects. If all you need is CRUD (create-read-update-delete), then maybe you do not need any design or programming at all - just use some of the shelf tool to model your domain.

That said, I see you are trying to reconcile relational database with OOP. It's a big thing in itself due to OOP-relational impedance mismatch. If CRUD is almost all you need, get some ORM tool (Object-relational mapping) to take boilerplate code away.

0
3

The CompanyAddress and PersonAddress are good but not on the class level and certainly not as inheriting entities (no is-a relationship). They should be (link) tables keeping relations between companies and addresses and between persons and addresses respectively. Then you can do anything. They do not represent anything in the real world, you probably do not want a class for them at all.

Class Person could have a property Addresses and class Address could have a property Persons which you could populate using a query. Same for company.

4
  • thanks. I agree CompanyAddress and PersonAddress do not represent anything in real world. But in my design OOP model it makes me to simplify design model. Database model is different and all is kept in Address table (both corresponding keys). So, my database model will be different of OOP model. This solution was just to make OOP model simpler as UI design is based on it. If I keep OOP model all in Address class, than in UI design I would have to remove Company column from display of Person address and vice versa. Hope it makes sense Jun 2, 2019 at 19:57
  • 1
    It sounds like you are using UI controls that map directly to a table. This is not sustainable, you should have some kind of view control instead that you can use independently from any table structure. Most data control libraries will support that. Alternatively you can design your own form and retrieve and persist the data yourself. Jun 2, 2019 at 20:12
  • Martin, yes, I am using some third party controls, which are CRUD based, since software is CRUD based, there are no complex logic involved. As for views, yes I will use that way since its possible using this way. Jun 2, 2019 at 22:11
  • yes UI controls maps directly to a table, but that is because of the model I am using. I have an option to display any view of table I need. Jun 4, 2019 at 10:48
2

Company has an address too. So in class Address I would have both relations to Person and Company.

Addresses should not refer to a Company or Person (but rather vice versa: a Company or Person has one primary (mailing/billing) address).

What will happen to your data model if two companies or two people share an address? You won't be able to express it, so you'll have to duplicate the address somehow.

If you resolve this issue, other problems will disappear.

1
  • yes, company can have more than one address. When 2 companies share same address, well , thats not important, since I will not search by address for my particular program, its irrelevant. So I can have 2 duplicated addresses (foreign key repeated) and its not an issue, though in 99.8% of cases it will not happen. Creating many to many relationship would bring more issues than benefit. Jun 2, 2019 at 14:44
2

What your doing is at this point not object-oriented at all. Don't worry, this is not a value judgement, you don't have to be object-oriented if you don't want to. If you do however, you still have work to do.

First, you are data-modeling. Having properties and relations, like you sometimes see in UML diagrams is a way of describing data not objects. You yourself said that you store these things in a database.

Object-orientation is not about data, but about behavior. You have to identify what business-functionality (not technical functionality!) you have to support, and assign those functionalities (sometimes also called responsibilities) to objects. Without business-functionality an object is not an object.

3
  • thanks for comment. I am still beginner, and OOP is something they do not teach a lot in tutorials. However, my app has basic logic, so I am trying to model it for database and app is basically CRUD based. My goal is to make it as fast as possible without not going too much into complex logic. Jun 2, 2019 at 22:15
  • my reputation is only 8 and I cannot give +1 still, I need 15 points. Thanks for the answer and advises. Jun 3, 2019 at 0:43
  • @ExpertLoser One more nuance to add: Perhaps, nowadays learning OOP concepts should be started from Alan Kay's original definition: wiki.c2.com/?AlanKaysDefinitionOfObjectOriented . And only after that Grady Booch and co with UML etc will start to make sense.
    – Roman Susi
    Jun 3, 2019 at 3:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.