Est ServiceLocator un anti-modèle?

J'ai lu récemment Marque Seemann de l'article sur le Service Localisateur anti-modèle.

Auteur souligne deux principales raisons pour lesquelles les ServiceLocator est un anti-pattern:

  1. D'utilisation de l'API question (dont je suis parfaitement bien avec)

    Quand la classe emploie un localisateur de Service, il est très dur de voir ses dépendances, dans la plupart des cas, la classe n'a qu'un constructeur sans paramètre.
    En contraste avec ServiceLocator, DI approche exposer explicitement les dépendances via les paramètres du constructeur si les dépendances sont facile vu dans IntelliSense.

  2. Problème d'entretien (ce qui m'intrigue, c')

    Considérez les points suivants expample

Nous avons une classe 'MyType' qui emploie un localisateur de Service d'approche:

public class MyType
{
    public void MyMethod()
    {
        var dep1 = Locator.Resolve<IDep1>();
        dep1.DoSomething();
    }
}

Maintenant, nous voulons ajouter une autre dépendance à la classe de MyType'

public class MyType
{
    public void MyMethod()
    {
        var dep1 = Locator.Resolve<IDep1>();
        dep1.DoSomething();

        //new dependency
        var dep2 = Locator.Resolve<IDep2>();
        dep2.DoSomething();
    }
}

Et c'est là où mon incompréhension commence. L'auteur dit:

Il devient beaucoup plus difficile de dire si vous êtes l'introduction d'une modification de rupture ou non. Vous avez besoin de comprendre l'ensemble de l'application dans laquelle le Service Locator est utilisée, et que le compilateur ne va pas vous aider.

Mais attendez une seconde, si nous étions à l'aide de DI approche, nous allons introduire une dépendance avec un autre paramètre dans le constructeur (dans le cas du constructeur d'injection). Et le problème sera toujours là. Si l'on peut oublier de configurer ServiceLocator, alors on peut oublier d'ajouter une nouvelle cartographie dans notre conteneur IoC et DI approche aurait le même problème de temps.

Aussi, l'auteur a mentionné à propos de l'unité de test de difficultés. Mais, ne nous ont des problèmes avec DI approche? Ne portons-nous pas besoin de mettre à jour tous les tests qui ont été l'instanciation de cette classe? Nous avons mis à jour à passer un nouveau moqué de dépendance juste pour faire notre test compilable. Et je ne vois pas les avantages de cette mise à jour et de passer du temps.

Je ne suis pas en train de défendre le Service Localisateur d'approche. Mais cette incompréhension me font penser que je vais perdre quelque chose de très important. Quelqu'un pourrait dissiper mes doutes?

MISE À JOUR (RÉSUMÉ):

La réponse à ma question "Est le Service Localisateur d'un anti-pattern" dépend vraiment de la situation. Et je ne dirais pas pour la rayer de votre liste d'outils. Il peut être très pratique lorsque vous commencez à traiter avec le code existant. Si vous êtes assez chanceux pour être au tout début de votre projet, alors les DI approche pourrait être un meilleur choix car il a certains avantages par rapport au Service Locator.

Et ici sont les principales différences qui m'a convaincu de ne pas utiliser le Service de Localisateur pour mes nouveaux projets:

  • Le plus évident et important: le Service Localisateur de masque de classe dépendances
  • Si vous êtes en utilisant un conteneur IoC, il ne sera probablement analyser tous les constructeur au démarrage afin de valider l'ensemble des dépendances et de vous donner de la rétroaction immédiate manquant mappages (ou de la mauvaise configuration); ce n'est pas possible si vous utilisez votre conteneur IoC en tant que Service Locator

Pour plus de détails lire d'excellentes réponses qui sont données ci-dessous.

"N'avons-nous pas besoin de mettre à jour tous les tests qui ont été l'instanciation de cette classe?" Pas nécessairement vrai si vous utilisez un générateur dans vos tests. Dans ce cas, vous n'avez qu'à mettre à jour le générateur de rapports.
Vous avez raison, ça dépend. Dans les grandes applications Android, par exemple, jusqu'à présent, les gens ont été très réticents à utiliser DI en raison de problèmes de performances sur les bas spec appareils mobiles. Dans de tels cas, vous devez trouver une alternative à toujours écrire de code de tests, et je dirais Service Locator est un bon-assez de substitution dans ce cas. (Note: les choses peuvent changer pour Android quand la nouvelle de la Dague 2.0 DI-cadre est assez mature.)
Notez que depuis que cette question a été posté, il y a une mise à jour sur la Marque Seemann Service Locator est un Anti-Patron de la poste décrivant la façon dont le service localisateur de viole de la programmation orientée objet par briser l'encapsulation, qui est son meilleur argument encore (et la raison sous-jacente de tous les symptômes qu'il a utilisé dans tous les avant les arguments). mise à Jour 2015-10-26: Le problème fondamental avec le Service Locator, c'est qu'il viole l'encapsulation.

OriginalL'auteur davidoff | 2014-04-01