7
votes

La séparation entre API et la mise en œuvre devrait-elle être totale?

La séparation entre la conception de l'API et leur mise en œuvre est souvent recommandée dans les grandes implémentations logicielles. Mais quelque part, ils doivent être reconnectés (c'est-à-dire que la mise en œuvre doit être reconnectée à l'API).

L'exemple suivant montre une conception de l'API et une invocation de sa mise en œuvre via l'objet d'instance: P>

import java.util.List;

public abstract class Separation {

    public static final Separation INSTANCE = new SeparationImpl();

    // Defining a special list
    public static interface MySpecialList<T> extends List<T> {
        void specialAdd(T item);
    }

    // Creation of a special list
    public abstract <T> MySpecialList<T> newSpecialList(Class<T> c);

    // Merging of a special list
    public abstract <T> MySpecialList<? extends T> specialMerge(
        MySpecialList<? super T> a, MySpecialList<? super T> b);

    // Implementation of separation
    public static class SeparationImpl extends Separation {

        @Override
        public <T> MySpecialList<T> newSpecialList(Class<T> c) {
            return ...;
        }

        @Override
        public <T> MySpecialList<? extends T> specialMerge(
            MySpecialList<? super T> a, MySpecialList<? super T> b) {
            return ...;
        }

    }

}


0 commentaires

4 Réponses :


4
votes

Une technique qui utilise souvent à OSGI est de disposer de l'API dans un module distinct à la mise en œuvre. L'API devrait compiler en lui-même en évitant toute référence à la mise en œuvre directement.


2 commentaires

Est-ce une nécessité absolue pour Osgi ou juste de bonnes pratiques?


Utiliser certains des cadres tels que l'iPojo, c'est nécessaire, mais vous n'avez pas à le faire dans tous les cas (et je ne le fais pas)



6
votes

J'ai toujours compris l'obligation de séparer l'interface de la mise en œuvre pour signifier que vous ne mélangez pas le comment de votre implémentation avec le quel . Donc, dans votre exemple ci-dessus, mélanger API et la mise en œuvre signifieraient exposer dans l'API quelque chose qui était spécifique à la mise en œuvre de votre API.

À titre d'exemple, examinez comment l'itération est mise en œuvre dans diverses classes de collecte. Il existe des moyens plus spécifiques que vous pouvez récupérer des éléments dans des collections spécifiques (par exemple, par la position dans une arrachelist), mais ceux-ci ne sont pas exposés dans Collection car ils sont spécifiques à la mise en œuvre de la mise en oeuvre concrète.

J'ai également vu des projets avec d'énormes répertoires d'interfaces, chacune ayant une seule implémentation concrète et chacune desquelles reproduit mécaniquement chaque méthode dans leur mise en œuvre concrète, qui semble être une abstraction "prétendre" complètement inutile, telle qu'elle est ne fournissant pas une abstraction logique.


0 commentaires

2
votes

Les réponses de Peter et Steve sont suffisantes, mais je voudrais ajouter plus - si vous n'avez jamais eu qu'une seule implémentation de l'interface ou de la classe abstraite, alors son inutile d'avoir une interface ou une classe abstraite comme étant la défaite du but de l'abstraction. de
Dans votre cas, je n'ai vraiment pas compris - pourquoi vous avez mis en œuvre Séparation en tant que classe abstrait, plutôt SéparationMpl peut être une classe API ou si vous avez des implémentations différentes Séparation peut être une introtrface et si vous avez une fonctionnalité commune, vous pouvez avoir une autre classe abstraite implémentant votre interface, puis SéparationMpl hériter de cette classe abstraite. La hiérarchie de la classe d'échantillons ressemblerait à xxx

comme la bibliothèque de collecte standard xxx


4 commentaires

Même s'il n'y a qu'une seule implémentation de production, les ABC et les interfaces sont toujours souvent une bonne chose; Premièrement, ils appliquent la séparation propre des préoccupations. Deuxièmement, ils permettent des tests d'unités faciles via des simulacres.


J'essayais d'illustrer le fait que parfois, vous avez besoin d'accéder à une instanciation d'une API et d'une manière consiste à la fournir de l'API elle-même. Je suis d'accord, cela aurait pu être fait avec une interface uniquement.


@Oli Charlesworth - Nous pouvons se moquer des classes concrètes, aucune interface pour un but moqueur au moins.


@Premraj Comment garantissez-vous que l'API moquée correspond à l'API implémenté? Avec interfaces c'est trivial. Une mocke est elle-même une implémentation simple et dénudée, donc en ayant une maquette que vous avez une deuxième mise en œuvre.



2
votes

En plus des bons points des autres auteurs, je mentionnerais les objectifs de test de l'unité:

à maquette des objets est très facile lorsque vous disposez d'interfaces intégrées de classes.


0 commentaires