[JAVA] Essayez de trier les classes par type d'énumération

environnement

Java sur cette page 1.8 Il est assemblé avec.

Changer avant

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é.

Conversion enum

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.


La même instance est plus pratique! Il peut y avoir un cas comme Cette fois, je vais essayer d'en faire une instance distincte en disant "suivre avant le changement".

Énumération partie 2

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.


Je pense personnellement que c'est un peu plus propre.

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

Essayez de trier les classes par type d'énumération
Essayez de trier les classes par type d'énumération
java: Comment écrire une liste de types génériques [Note]
Enum (type d'énumération)
Je veux trier par délimiteur d'onglet avec ruby
[Java] Type d'énumération
Essayez d'afficher le nombre premier en utilisant le type booléen
Essayez de libérer la gemme
Comment repousser la barre oblique \