É aceitável declarar objetos do mesmo tipo dentro de si?

8

É aceitável declarar novos objetos (e devolvê-los) de dentro do mesmo objeto, como no exemplo abaixo?

Ou é melhor movê-lo para algum tipo de handlerclasse?

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
fonte
6
dependendo do idioma, eu recomendaria GetPersonsser estático ou não ser um membro da Person. Atualmente você precisa PersonligarGetPersons
Caleth 17/05
Claro, a Objectclasse Java (a raiz da hierarquia de classes) exige explicitamente um clone()método que se destina a fornecer uma cópia do objeto.
TMN

Respostas:

9

Em geral, sim, está tudo bem . Em geral, o construtor de uma classe é o local para onde vai toda a configuração necessária para que essa classe funcione. Geralmente, uma parte dessa configuração é abstraída para outras áreas do código. Por exemplo, o padrão de fábrica move grande parte da configuração inicial para outra classe, para que a configuração seja claramente separada da lógica.

No seu exemplo específico, não está bem . Possivelmente porque seu exemplo foi construído, mas você está conflitando dados e lógica. Você está declarando a aparência de uma pessoa e me dando métodos de como conseguir pessoas específicas. Vale a pena examinar o Princípio da Responsabilidade Única . No seu exemplo, eu teria uma classe simples definindo o tipo de dados Person, um repositório que obtém pessoas e a classe que tira pessoas do repositório e, em seguida, faz algo com os dados (por exemplo, enviá-los por e-mail)

Tom Squires
fonte
5

Sim, nas condições certas.

Um exemplo comum é o da composição do filtro. Aqui, você cria um novo filtro chamando um método em um filtro mais antigo.

Exemplo artificial:

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

Isso permite o uso como

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

É assim que funciona o encadeamento do seletor jQuery e como os conjuntos de consultas do Django.

Sjoerd Job Postmus
fonte
3

Em vez de fazer dessa maneira, tentaria implementar algo como uma versão mais encapsulada do padrão de fábrica. Tenha um objeto separado que crie a lista. Consulte Factory (programação orientada a objetos) .

Você já está essencialmente executando o padrão de fábrica ao retornar uma lista de Person, mas, em vez disso, pode querer ter duas classes separadas. Se você separar a fábrica do produto , sua implementação Personnão será vinculada à sua classe que cria a lista (ou seja PersonFactory).

Se você vir o link acima, verá que um exemplo semelhante ao seu é realmente publicado na seção de nomes descritivos . No entanto, pela razão acima, eu não faria dessa maneira. Veja a seção Encapsulamento (também no link).

Snoop
fonte
1

Eu posso dar um exemplo e não é errado retornar objetos do mesmo tipo dentro do mesmo tipo.

Considere isto.

class Employee {}

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

Há uma linha tênue entre separação ou mistura de preocupações. Se você estiver do outro lado dessa linha, poderá usar um gerente / manipulador / ... como um objeto.

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