73 votes

Comment trouvez-vous une aiguille dans une botte de foin?

Lors de la mise en œuvre d'une aiguille à la recherche d'un botte de foin dans une méthode orientée objet, vous avez trois solutions:

1. needle.find(haystack)

2. haystack.find(needle)

3. searcher.find(needle, haystack)

Lequel préférez-vous, et pourquoi?

Je sais que certaines personnes préfèrent la seconde alternative, car il évite l'introduction d'un troisième objet. Cependant, je ne peux m'empêcher de penser que la troisième approche est plus conceptuel "correct", au moins si votre objectif est de modéliser "le monde réel".

Dans quels cas avez-vous pense qu'il est justifié d'introduire des objets d'aide, tels que le chercheur dans cet exemple, et quand doivent-elles être évitées?

55voto

Brad Wilson Points 22910

Des trois, je préfère l'option #3.

Le Principe de Responsabilité Unique fait que je ne veux pas mettre les capacités de recherche sur mon Otd ou modèles. Leur responsabilité est d'être données, de ne pas trouver eux-mêmes, ni les aiguilles devez savoir sur les meules de foin, ni les meules de foin savoir sur les aiguilles.

Pour ce que ça vaut, je pense qu'il faut plus OO praticiens du temps à comprendre pourquoi le #3 est le meilleur choix. J'ai fait OO pour une décennie, probablement, avant que je vraiment grokked.

@wilhelmtell, C++ est l'un des très peu de langues avec le modèle de la spécialisation qui font qu'un tel système fonctionne. Pour la plupart des langues, un objectif général de "trouver" la méthode serait une idée HORRIBLE.

53voto

Mike Stone Points 21293

Habituellement des actions doivent être appliquées à ce que vous faites l’action sur... dans ce cas une botte de foin, donc je pense que l’option 2 est la plus appropriée.

Vous avez également une quatrième alternative qui je pense serait mieux que l’alternative 3 :

Dans ce cas, il vous permet d’offrir la manière dans laquelle vous souhaitez rechercher dans le cadre de l’action, et donc vous pouvez garder l’action avec l’objet qui est exploité.

16voto

wilhelmtell Points 25504

Il existe une autre alternative, ce qui est l'approche utilisée par la STL du C++:

find(haystack.begin(), haystack.end(), needle)

Je pense que c'est un excellent exemple de C++ en criant "dans ta face!" à la POO. L'idée est que la POO n'est pas une balle en argent de toute nature; parfois, les choses sont mieux décrits en termes d'actions, parfois en termes d'objets, parfois ni et parfois les deux.

Bjarne Stroustrup a dit dans TC++PL que lors de la conception d'un système, vous devez vous efforcer de refléter la réalité sous la contrainte effective et efficace du code. Pour moi, cela signifie que vous ne devriez jamais vous suivez tout ce aveuglément. Réfléchir sur les choses à portée de main (la botte de foin, à l'aiguille) et le contexte, nous sommes dans (recherche, c'est ce que l'expression est d'environ).

Si l'accent est mis sur la recherche, puis à l'aide d'un algorithme (action) qui met l'accent sur la recherche (c'est à dire de manière flexible pour s'adapter à des meules de foin, des océans, des déserts, des listes chaînées). Si l'accent est mis sur la botte de foin, encapsuler la méthode de recherche à l'intérieur de la botte de foin de l'objet, et ainsi de suite.

Cela dit, parfois, vous êtes dans le doute et ont des périodes difficiles de faire un choix. Dans ce cas, être orientée objet. Si vous changez d'avis plus tard, je pense que c'est plus facile à extraire une action à partir d'un objet, puis de diviser une action pour les objets et les classes.

Suivez ces instructions et votre code sera plus clair et plus beau.

15voto

Tilendor Points 9622

Je dirais que l'option 1 est complètement out. Le code doit lire d'une manière qui vous dit ce qu'il fait. L'Option 1 me fait penser que cette aiguille va aller me chercher une botte de foin.

L'Option 2 semble bon si une botte de foin est destinée à contenir des aiguilles. ListCollections sont toujours en cours pour contenir ListItems, afin de faire la collecte.trouver(item) est naturel et expressif.

Je pense que l'introduction d'un objet d'assistance est approproiate lorsque:

  1. Vous n'avez pas le contrôle de la mise en œuvre des objets en question
    C'est à dire: de recherche.trouver(ObsecureOSObject, fichier)
  2. Il n'y a pas une régulière et raisonnable de relation entre les objets
    C'est à dire: nameMatcher.trouver(des maisons,des arbres.de nom)

11voto

Peter Meyer Points 11163

Je suis avec Brad sur celui-ci. Plus je travaille sur énormément de systèmes complexes, plus je vois la nécessité de vraiment dissocier des objets. Il est à droite. Il est évident que l'aiguille ne sais rien à propos de la botte de foin, donc 1 est définitivement hors. Mais, une botte de foin devrait ne sais rien à propos d'une aiguille.

Si j'étais la modélisation d'une botte de foin, je pourrais la mettre en œuvre comme une collection, mais comme une collection de foin ou de paille , et non pas une collection d'aiguilles! Toutefois, je prendrais en compte que les choses ne se perdent dans une botte de foin, mais je ne sais rien à propos de ce qu'est exactement ce genre de choses. Je pense que c'est mieux de ne pas faire de la botte de foin rechercher des articles dans lui-même (comment puce est une botte de foin de toute façon). La bonne approche pour moi est d'avoir la botte de foin présenter une collection de choses qui y sont, mais ne sont pas de la paille ou du foin ou de ce que donne une botte de foin son essence.

class Haystack : ISearchableThingsOnAFarm {
   ICollection<Hay> myHay;
   ICollection<IStuffSmallEnoughToBeLostInAHaystack> stuffLostInMe;

   public ICollection<Hay> Hay {
      get {
         return myHay;
      }
   }

   public ICollection<IStuffSmallEnoughToBeLostInAHayStack> LostAndFound {
      get {
        return stuffLostInMe;
      }
   }
}

class Needle : IStuffSmallEnoughToBeLostInAHaystack {
}

class Farmer {
  Search(Haystack haystack, 
                 IStuffSmallEnoughToBeLostInAHaystack itemToFind)
}

Il y a en fait plus j'allais le type et l'abstrait dans les interfaces et puis j'ai réalisé à quel fou j'ai été faire. Senti comme si j'étais dans une CS de classe au collège... :P

Vous obtenez l'idée. Je pense que que faiblement couplé possible est une bonne chose, mais peut-être que j'étais un peu emporté! :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X