0

Let's say I have a Person class:

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string IdCard { get; set; }
    public string Phone { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
    public string Credit { get; set; }
    public Bank Bank { get; set; }
    public Job Job { get; set; }
    // etc.
}

When instantiated, the properties get their values from a database.

Another class is displaying a Person. However, it displays only a few of the available properties. What should it get as arguments?

class Program
{
    void ShowPerson(string firstName, string LastName, string phone)
    {
        Console.WriteLine(firstName);
        Console.WriteLine(lastName);
        Console.WriteLine(phone);
    }
}

or

class Program
{
    void ShowPerson(Person person)
    {
        Console.WriteLine(person.FirstName);
        Console.WriteLine(person.LastName);
        Console.WriteLine(person.Phone);
    }
}

The advantage of sending only relevant properties is memory efficiency and more precise SQL. The advantage of sending an entire instance is much cleaner code, and potentially easier to change.

So which should I use? Thanks.


Note:

  1. This question is about data objects in particular. My question is more general, and it's about any type of object. They are not the same.
  2. I am not asking for opinions. I am asking if there is a very well established, common guideline, approach or pattern to deal with this situation.
  • 1
    Strictly speaking, if you can pass parameters instead of an object, that is better, as you can restrict access of the callee to only the data needed. On the other hand, this can become clumsy with many parameters, and it does not allow you to develop layers of abstraction. For example, to work with complex number or 3d vector arithmetic, using objects to encapsulate the scalars within the complex number or vector will always be simpler and closer to the mathematical formulas. – Frank Hileman Apr 23 '17 at 22:28
3

If memory efficiency is your concern, the second option is better. Most OOP languages pass by reference, so it's not passing 3 strings compared to passing 7 strings, 2 unknown-sized objects and some more unknown fields it's passing 3 references to strings compared to passing one reference to an object. And references are always the same size. Unless your language uses fat pointers for strings, which only makes the first option even heavier...

Even languages that don't pass by reference by default - like C++ - usually have special syntax for passing by reference, which you should use.

But that's optimization, and you care about the principle. I believe the relevant principle here is Single Source of Truth(very close to DRY). SSoT is not just about data - it's about code as well. When you define a piece of behavior, you should strive to have all the definition of that behavior in one place. And the second option does that better.

The behavior here is printing a person's info. You have a ShowPerson function, which should be the SSoT for that behavior. (Or, as Ewan recommended, Person.Show should be that SSoT). But in the first option you leak some of that behavior definition to the caller:

  • The fact that it prints 3 fields. In the second option only the callee needs to know that - in the first
  • The identity of these 3 fields. In the first option, it is decided outside ShowPerson. The argument names are not deciding the fields - they are just a recommendation.
    • BTW - this may cause bugs, if you call ShowPerson with the wrong fields, or with fields in the wrong order. That's the exact sort of bug SSoT aims to prevent.
  • The fact that Person have these fields! The fact that the caller needs to know them is a real problem if you want to use templates or reflection...
|improve this answer|||||
  • Thanks! But with this approach, I need to query the database for each and every property even if I need only one. Is that really efficient? – Sipo Apr 24 '17 at 13:49
  • 1
    This is micro-optimization here - you need to try and measure to know what's more efficient, and unless performance becomes an issue and profiling says this is your bottleneck - it ain't worth the effort. It may look like requesting only the fields you need is more efficient- but this means you need more queries(because different functions need different fields), which may potentially bump more queries out of your database's implicit statements cache, and actually harm performance. Modern computing is complicated like that - doing less does not always result in less work for the machine. – Idan Arye Apr 24 '17 at 17:14
3

1: OO design would be Person.Show()

2: The problem with your first function is really just naming. it has no relation to Person anymore.

But then what do you call it? ThreeStringWriterToConsole? the benefit of ShowPerson(Person p) is its vagueness. You can add the middle name later, or change from console to a file or graphic and nothing else changes.

|improve this answer|||||
  • Thanks! This is just an example. The point is about the arguments. – Sipo Apr 23 '17 at 16:53
  • yes. i know it is – Ewan Apr 23 '17 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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