Java sur cette page 1.8 Il est assemblé avec.
Si vous disposez de l'interface suivante
Logic.java
public interface Logic {
public void printSkyColor();
}
Il a été mis en œuvre comme ça. C'est comme appeler les classes d'implémentation différemment.
public void execute(String type) {
Logic logic = null;
if("S".equals(type)){
logic = new SunnyLogic();
}else if("C".equals(type)){
logic = new CloudyLogic();
}else if("R".equals(type)){
logic = new RainyLogic();
}else{
throw new UnsupportedOperationException("unknown type : "+ type);
}
//SunnyLogic -> "It is Blue."Est sortie en standard
//CloudyLogic-> "It is White."Est sortie en standard
//RainyLogic-> "It is Gray."Est sortie en standard
logic.printSkyColor();
}
Vous pouvez penser à cela comme «énumérer» la logique correspondant au type, non? Est-ce un peu plus propre si vous utilisez bien le type d'énumération?
J'ai pensé et essayé.
Tout d'abord, créez une classe d'énumération comme celle-ci.
LogicConstant.java
public enum LogicConstant {
SUN("S", new SunnyLogic()),
CLOUD("C", new CloudyLogic()),
RAIN("R", new RainyLogic()),
;
private final String type;
private final Logic logic;
private LogicConstant(String type, Logic logic) {
this.type = type;
this.logic = logic;
}
public static Logic ofLogic(String type) {
for(LogicConstant c : values()){
if(c.type.equals(type)){
return c.logic;
}
}
return null;
}
}
Le côté qui utilise l'énumération ci-dessus ressemble à ceci.
public void execute(String type) {
Logic logic = LogicConstant.ofLogic(type);
if(logic == null){
throw new UnsupportedOperationException("unknown type : "+ type);
}
//System.out.print(logic.hashCode()+":");
logic.printSkyColor();
}
Cela fonctionne toujours, mais cela fonctionne, ** L'instance de classe logique est très différente d'avant le changement. ** ** ** Avant la modification, une instance est créée à chaque fois, mais après la modification, il s'agit de la même instance. ** ** C'est le but.
Comme vous pouvez le voir à la source,
//System.out.print(logic.hashCode()+":");
Vous pouvez vérifier la valeur de hachage en décommentant ce commentaire du côté utilisateur.
L'instanciation séparée signifie définir uniquement la classe à générer C'est nouveau quand vous l'appelez, donc ça ressemble à ça.
LogicConstant.java
public enum LogicConstant {
SUN("S", SunnyLogic.class),
CLOUD("C", CloudyLogic.class),
RAIN("R", RainyLogic.class),
;
private final String type;
private final Class<? extends Logic> logic;
private LogicConstant(String type, Class<? extends Logic> logic) {
this.type = type;
this.logic = logic;
}
public static Logic ofLogic(String type) {
for(LogicFactory c : values()){
if(c.type.equals(type)){
try {
return c.logic.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
}
return null;
}
}
Un peu plus de rénovation d'ici.
return c.logic.newInstance();
Premier NewInstance () de la classe est obsolète dans java9
Classe getDeclaredConstructor (). NewInstance ()
Remplacez-le ici comme spécifié dans javadoc de java9.
De plus, les paramètres peuvent quand même être passés au moment du constructeur Alors réécrivez-le pour que les paramètres soient routés.
Puisqu'une autre instance est créée pour chaque appel, le nom de la classe est également défini sur Factory.
finalement Correction de lever une exception au lieu de renvoyer null. (Merci pour votre conseil!)
Reflétant cela ... Ceci est le produit fini.
LogicFactory.java
public enum LogicFactory {
SUN("S", SunnyLogic.class),
CLOUD("C", CloudyLogic.class),
RAIN("R", RainyLogic.class),
;
private final String type;
private final Class<? extends Logic> logic;
private LogicFactory(String type, Class<? extends Logic> logic) {
this.type = type;
this.logic = logic;
}
public static Logic ofLogic(String type, Object... initargs) {
for(LogicFactory c : values()){
if(c.type.equals(type)){
try {
return c.logic.getDeclaredConstructor().newInstance(initargs);
} catch (
InstantiationException | IllegalAccessException | IllegalArgumentException |
InvocationTargetException | NoSuchMethodException | SecurityException e
) {
e.printStackTrace();
throw new IllegalArgumentException("type : "+type, e);
}
}
}
throw new UnsupportedOperationException("unknown type : "+ type);
}
}
Suite à ces corrections Le jugement nul de l'appelant n'est plus nécessaire, supprimez-le.
Eh bien, ce genre de travail de refactoring est souvent considéré comme un passe-temps. Je pense qu'il devrait être organisé autant que possible en tenant compte de l'exploitation et de la maintenance, et qu'il devrait être codé consciemment.
Vous étudiez ou révisez enum? Je vais le décrire pendant un certain temps.
Recommended Posts