Collection personnalisée vs Collection générique pour les méthodes publiques [fermé]

StackOverflow https://stackoverflow.com/questions/1544800

Question

Quelles sont les lignes directrices de conception-cadre pour exposer une collection personnalisée vs générique? par exemple

public class ImageCollection : Collection<Image>
{
     ...
}

public class Product
{
   public ImageCollection {get; set;}
}

VS

public class Product
{
   public Collection<Image> Images{get; set;}
}
Était-ce utile?

La solution

En général, il est préférable d'exposer l'une des interfaces, telles que IEnumerable<T>, ICollection<T> ou IList<T> au lieu d'une classe concrète.

Cela vous donne beaucoup plus de flexibilité en termes de changement de votre API interne. IEnumerable<T>, en particulier, vous permet de modifier potentiellement vos internes plus tard pour permettre la diffusion des résultats, est donc le plus flexible.

Si vous connaissez les habitudes d'utilisation attendues de vos « collections », vous devez exposer l'API appropriée qui fournit les moins de contraintes dans l'avenir. Si, par exemple, vous savez que les gens ont juste besoin d'itérer vos résultats, exposer IEnumerable<T>, vous pouvez changer à toute collection plus tard, ou même passer à utiliser simplement le retour de rendement directement.

Autres conseils

Si vous construisez une API publique, envisagez d'utiliser une collection personnalisée pour les avantages suivants.

  • Extensibilité - vous pouvez ajouter des fonctionnalités à votre collection personnalisée dans l'avenir sans changer l'API.

  • Rétrocompatibilité - vous êtes libre de changer les entrailles de votre classe de collection que vous s'il vous plaît, sans casser le code existant que les clients ont programmé contre la collecte.

  • Il est également plus facile de faire des changements potentiellement briser avec moins d'impact. Peut-être que plus tard vous décidez que vous ne voulez pas que ce soit un Collection<Image>, mais un autre type de collection - vous pouvez personnaliser votre classe ImageCollection d'avoir les mêmes méthodes que précédemment, mais hériter de quelque chose de différent - et le code client ne sera pas susceptible de se briser .

Si c'est juste pour le code d'usage interne, la décision est pas nécessairement aussi important, et vous pouvez décider d'aller avec « plus simple est mieux ».

Un exemple du haut de ma tête est le serveur API ArcGIS de ESRI - ils utilisent des collections personnalisées dans leurs API. Nous utilisons également des collections personnalisées dans notre API est surtout pour ces raisons.

Je pencherais pour le second. Le code client doit connaître l'image de type de toute façon.

Le premier moyen de seulement plus de code.

La principale raison pour laquelle je peux penser est que vous pouvez avoir des méthodes spécifiques à une collection d'images qui fonctionnent sur cette collection elle-même. Ensuite, j'utiliser une classe ImageCollection pour contenir ces méthodes. encapsulation classique.

En outre, juste un côté, vous devriez vraiment exposer seulement un getter pour cette collection, et initialiser un champ de support en lecture seule avec la collection réelle. Vous voulez probablement les gens à ajouter / supprimer des éléments à la collecte, remplacez pas la chose entière:

class Product {
    private readonly Collection<Image> _images;
    public Product() { _images = new Collection<Image>(); }
    public Collection<Image> Images { get { return _images; } }
}

-Oisin

La seule raison d'utiliser jamais Collection<T> est si vous voulez accrocher dans l'ensemble des méthodes virtuelles qui vous permet de voir toutes les mutations à la liste sous-jacente. Cela vous permet de faire des opérations telles que répondre à la suppression, la mise en œuvre des événements, etc ...

Si vous n'êtes pas intéressé à répondre ou regarder ces modifications de collecte alors List<T> est un type plus approprié.

Je préfère avoir une propriété générique du public pour rendre le fonctionnement interne extensible, mais un champ privé serait la coutume une avec la fonctionnalité réelle.

Il ressemble généralement à ceci:

public interface IProduct
{
     ICollection<Image> Images { get; }
}

public class Product : IProduct
{
   private class ImageCollection : Collection<Image>
   {
      // override InsertItem, RemoveItem, etc.
   }

   private readonly ImageCollection _images;
   public ICollection<Image> Images
   {
      get { return _images; }
   }
}

Je fais aussi souvent la classe de collection personnalisée imbriquée dans une autre classe, ce qui me permet de modifier certains membres privés de la classe parente au cours Ajout / suppression.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top