8

Is it acceptable to declare new objects (and return them) from within the same object, as in the example below?

Or, is it better to move it to some kind of handler class?

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    //Gets a list of persons
    public List<Person> GetPersons()
    {
        List<Person> _listPersons = new List<Person>();

        Person _person = new Person();
        _person.Name = "FooFii"; 
        _person.Age = 50;
        _listPersons.Add(_person); 

        return _listPersons; 
    }
}
2
  • 6
    depending on language, I would recommend GetPersons be static or not a member of Person. Currently you need a Person to call GetPersons
    – Caleth
    Commented May 17, 2016 at 13:06
  • Sure, The Java Object class (the root of the class hierarchy) explicitly mandates a clone() method which is intended to provide a copy of the object.
    – TMN
    Commented May 17, 2016 at 18:41

4 Answers 4

9

In general, yes it's ok. In general the constructor of a class is where all the setup necessary for that class to function goes. Often a portion of that setup is abstracted to other areas of the code. For example the factory pattern moves a lot of the initial setup to another class so the setup is clearly separated from the logic.

In your specific example, it's not ok. Possibly because your example is constructed but you're conflating data and logic. You are declaring what a person looks like and giving me methods of how to get specific people. It's worth looking into the Single Responsibility Principle. In your example I would have one simple class defining the datatype of Person, a repository that gets people and class that gets people out the repository and then does something with the data (i.e. email them)

5

Yes, under the right conditions.

A common example is that of filter composition. Here, you build a new filter by calling a method on an older filter.

Contrived example:

class Filter {
    public function where(string field_name, object value) {
        filters = (clone)this->filters;
        filters.setitem(field_name, value);
        return Filter(filters);
    }
}

This allows usage like

query = Filter()
    .where("username", "nobody")
    .where("password", "should be salted and hashed")
;
user = User.get(filter);

This is somewhat how jQuery selector chaining works, and how Django querysets work.

3

Instead of doing it this way, I would try to implement something like a more encapsulated version of the factory pattern. Have a separate object that creates the list instead. See Factory (object-oriented programming).

You are essentially already doing the factory pattern when you return a list of Person, but instead you may want to have two separate classes. If you separate the factory from the product, your implementation of Person won't be tied into your class that creates the list (i.e. PersonFactory).

If you see the link above, you'll see that an example similar to yours is actually posted under the descriptive names section. However, for the reason above I wouldn't do it this way. See the section on Encapsulation (also in the link).

1

I can give you an example and it is not wrong to return same type objects within the same type.

Consider this.

class Employee {}

class Manager : Employee 
{
    List<Employee> Employees { get; set;}
    Manager ReportsTo { get; set; }
}

There is a thin line between separation or mixing of concerns. If you find yourself on the other side of that line, you can use a manager/handler/... kind a object.

class Organization 
{
    Employee FindEmployeeByName (string name) {}
    Employee FindManagerOf (Employee emp) {}
    List<Employees> TeamOf (Employee manager)
    ...
}

Your Answer

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

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