¿Es aceptable declarar objetos del mismo tipo, dentro de sí mismos?

8

¿Es aceptable declarar nuevos objetos (y devolverlos) desde el mismo objeto, como en el ejemplo a continuación?

¿O es mejor moverlo a algún tipo de handlerclase?

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; 
    }
}
AsusT9
fuente
66
dependiendo del idioma, recomendaría GetPersonsser estático o no ser miembro de Person. Actualmente necesita una PersonllamadaGetPersons
Caleth
Claro, la Objectclase Java (la raíz de la jerarquía de clases) exige explícitamente un clone()método destinado a proporcionar una copia del objeto.
TMN

Respuestas:

9

En general, sí, está bien . En general, el constructor de una clase es donde va toda la configuración necesaria para que esa clase funcione. A menudo, una parte de esa configuración se abstrae a otras áreas del código. Por ejemplo, el patrón de fábrica mueve gran parte de la configuración inicial a otra clase, por lo que la configuración está claramente separada de la lógica.

En su ejemplo específico, no está bien . Posiblemente porque su ejemplo está construido pero está combinando datos y lógica. Usted está declarando cómo se ve una persona y me está dando métodos de cómo obtener personas específicas. Vale la pena analizar el Principio de responsabilidad única . En su ejemplo, tendría una clase simple que define el tipo de datos de Persona, un repositorio que saca a las personas y una clase que saca a las personas del repositorio y luego hace algo con los datos (es decir, enviarles un correo electrónico)

Tom Squires
fuente
5

Sí, bajo las condiciones correctas.

Un ejemplo común es el de la composición del filtro. Aquí, crea un nuevo filtro llamando a un método en un filtro anterior.

Ejemplo contribuido:

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

Esto permite el uso como

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

Así es como funciona el encadenamiento del selector jQuery y cómo funcionan los conjuntos de consultas de Django.

Sjoerd Job Postmus
fuente
3

En lugar de hacerlo de esta manera, trataría de implementar algo como una versión más encapsulada del patrón de fábrica. Tenga un objeto separado que cree la lista en su lugar. Ver Factory (programación orientada a objetos) .

Básicamente, ya está haciendo el patrón de fábrica cuando devuelve una lista de Person, pero en su lugar es posible que desee tener dos clases separadas. Si separa la fábrica del producto , su implementación de Personno estará vinculada a su clase que crea la lista (es decir PersonFactory).

Si ve el enlace de arriba, verá que un ejemplo similar al suyo se publica en la sección de nombres descriptivos . Sin embargo, por la razón anterior, no lo haría de esta manera. Vea la sección sobre Encapsulación (también en el enlace).

Fisgonear
fuente
1

Puedo darle un ejemplo y no está mal devolver los mismos objetos de tipo dentro del mismo tipo.

Considera esto.

class Employee {}

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

Hay una delgada línea entre la separación o la mezcla de preocupaciones. Si te encuentras al otro lado de esa línea, puedes usar un administrador / manejador / ... tipo un objeto.

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