È accettabile dichiarare oggetti dello stesso tipo, dentro se stessi?

8

È accettabile dichiarare nuovi oggetti (e restituirli) all'interno dello stesso oggetto, come nell'esempio qui sotto?

Oppure, è meglio spostarlo su un tipo di handler di classe?

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; 
    }
}
    
posta AsusT9 17.05.2016 - 15:00
fonte

4 risposte

9

In generale, sì, è ok . In generale, il costruttore di una classe è dove va a finire tutta l'installazione necessaria per quella classe. Spesso una parte di questa configurazione è astratta ad altre aree del codice. Ad esempio, il pattern factory sposta molte delle impostazioni iniziali in un'altra classe, in modo che l'installazione sia chiaramente separata dalla logica.

Nel tuo esempio specifico, non è ok . Forse perché il tuo esempio è costruito ma tu sei conflating dati e logica. Stai dichiarando che aspetto ha una persona e mi dai metodi per ottenere persone specifiche. Vale la pena esaminare il principio di responsabilità singola . Nel tuo esempio avrei una semplice classe che definisce il tipo di dati di Person, un repository che ottiene persone e classe che porta le persone fuori dal repository e poi fa qualcosa con i dati (ad esempio, li invia tramite e-mail)

    
risposta data 17.05.2016 - 16:18
fonte
5

Sì, nelle giuste condizioni.

Un esempio comune è quello della composizione del filtro. Qui, si crea un nuovo filtro chiamando un metodo su un filtro precedente.

Esempio di contrived:

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

Ciò consente l'utilizzo come

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

Questo è un po 'come funziona il concatenamento del selettore jQuery e come funzionano i set di query di Django.

    
risposta data 17.05.2016 - 17:07
fonte
3

Invece di farlo in questo modo, proverei a implementare qualcosa come una versione più incapsulata del pattern factory. Avere un oggetto separato che crea invece la lista. Vedi Factory (programmazione orientata agli oggetti) .

Stai essenzialmente già facendo lo schema di fabbrica quando restituisci un elenco di Person , ma potresti preferire avere due classi separate. Se separi factory dal prodotto , la tua implementazione di Person non sarà legata alla tua classe che crea l'elenco (cioè PersonFactory ).

Se vedi il link sopra, vedrai che un esempio simile al tuo è in realtà pubblicato nella sezione nomi descrittivi . Tuttavia, per la ragione sopra, non lo farei in questo modo. Vedi la sezione su Incapsulamento (anche nel link).

    
risposta data 17.05.2016 - 16:02
fonte
1

Posso darti un esempio e non è sbagliato restituire gli stessi oggetti di tipo all'interno dello stesso tipo.

Considera questo.

class Employee {}

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

C'è una linea sottile tra separazione o mescolanza di preoccupazioni. Se ti trovi dall'altra parte di quella linea, puoi usare un gestore / gestore / ... un oggetto gentile.

class Organization 
{
    Employee FindEmployeeByName (string name) {}
    Employee FindManagerOf (Employee emp) {}
    List<Employees> TeamOf (Employee manager)
    ...
}
    
risposta data 17.05.2016 - 19:41
fonte

Leggi altre domande sui tag