2010-07-09 2 views
2

J'ai donc fait quelques refactorisations et deux de mes classes se ressemblent maintenant à l'exception de leurs constructeurs.Quelle est la meilleure façon de déshumidifier ces classes, la duplication dans tout sauf constructeur

Les classes enveloppent un objet API qui n'est pas très joli et ajoutent certaines fonctionnalités qui appartiennent au bord de l'API.

class A extends API { 
    public A { 
    this.APIOption = Option1; 
    this.AnotherAPIOption = Option2; 
    // a few more 
    } 

    public ArrayList<String> somethingTheAPIDoesntDo() { 
    // Do something the API doesn't provide but I use alot 
    } 
    // Other shared methods 
} 

class B extends API { 
    public B { 
    this.APIOption = Option3; 
    this.AnotherAPIOption = Option4; 
    // a few more 
    } 

    public ArrayList<String> somethingTheAPIDoesntDo() { 
    // Do something the API doesn't provide but I use alot 
    } 
    // Other shared methods 
} 

Est-il judicieux de pousser le code commun entre les deux à une classe abstraite de base et ont les sous-classes à mettre en œuvre que les constructeurs avec les paramètres d'option spécialisés? Cela a du sens sur papier, mais quelque chose semble bizarre/contre-intuitif à ce sujet. Est-ce qu'il me manque un motif ici?

possible Solution sèche

class A extends BetterAPIBase { 
    public A { 
    this.APIOption = Option1; 
    this.AnotherAPIOption = Option2; 
    // a few more 
    } 
} 

class B extends BetterAPIBase { 
    public B { 
    this.APIOption = Option3; 
    this.AnotherAPIOption = Option4; 
    // a few more 
    } 
}  

abstract class BetterAPIBase extends API { 
    public Better APIBase() {} 
    public ArrayList<String> somethingTheAPIDoesntDo() { 
    // Do something the API doesn't provide but I use alot 
    } 
    // Other methods 
} 

EDIT

modèle statique usine est agréable, mais je pense que je peux ajouter une interface qui inclut les méthodes communes je.

Je voudrais que la classe BetterAPI implémente également IBetterAPI, ce qui n'exposerait que les méthodes que j'ai ajoutées partout où je déclare le type de l'instance comme IBetterAPI.

interface IBetterAPI{ 
     public ArrayList<String> somethingTheAPIDoesntDo(); 
     // other methods I added in BetterAPI 
} 

//somewhere else: 
IBetterAPI niceApi = BetterAPI.createWithOptionSetA(); 
niceApi.somethingTheAPIDoesntDo(); 

// Can't do this, nice and hidden. 
niceApi.somethingBaseAPIDoes(string uglyOptions, bool adNauseum); 
+1

Ouais, à peu près ce que je ferais ... – Amadan

+3

Factory Pattern pourrait aussi bien fonctionner. Une classe. Et l'usine prend soin de le créer avec différentes options. – CaffGeek

Répondre

13

Ne serait-il pas plus simple d'avoir une classe avec un constructeur paramétré (éventuellement privé) et plusieurs méthodes d'usine statiques?

class BetterAPI extends API { 
    private BetterAPI(APIOption option, AnotherAPIOption anotherOption) { 
    this.APIOption = option; 
    this.AnotherAPIOption = anotherOption; 
    } 

    public static BetterAPI createWithOptionSetA() { 
    return new BetterAPI(Option1, Option2); 
    } 

    public static BetterAPI createWithOptionSetB() { 
    return new BetterAPI(Option3, Option4); 
    } 

    // ... 
} 

Le cœur de votre problème semble être que vous ne pouvez pas avoir plusieurs constructeurs sans paramètre dans la même classe. Les méthodes d'usine statiques offrent une bonne solution à cela.

+0

Bonne réponse, je l'ai mentionné comme un commentaire, mais était trop paresseux pour écrire le code! – CaffGeek

1

C'est assez proche de ce que je ferais. Bien que si le « peu plus » fait pour beaucoup de code redondant dans le constructeur, j'écrire:

abstract class BetterAPIBase extends API { 
    public BetterAPIBase(String APIOption, int AnotherAPIOption, ... more ...) { 
    this.APIOption=APIOption; 
    this.AnotherAPIOption=AnotherAPIOption; 
    // a few more 
    } 
    public ArrayList<String> somethingTheAPIDoesntDo() { 
    // Do something the API doesn't provide but I use alot 
    } 
    // Other methods 
} 

class A extends BetterAPIBase { 
    public A { 
    super(Option1, Option2, ... more ...); 
    } 
} 

class B extends BetterAPIBase { 
    public B { 
    super(Option3, Option4, ... more ...); 
    } 
}  

Bien sûr, si l'une des valeurs d'option sont les mêmes alors ils ne doivent être passées , qui est l'endroit où l'élimination réelle des redondances viendrait.

Questions connexes