[JAVA] Versuchen Sie, Klassen nach Aufzählungstyp zu sortieren

Umgebung

Java auf dieser Seite 1.8 Es ist zusammengebaut mit.

Vorher ändern

Wenn Sie die folgende Schnittstelle haben

Logic.java


public interface Logic {
	public void printSkyColor();
}

Es wurde so implementiert. Es fühlt sich an, als würden die Implementierungsklassen anders aufgerufen.

	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."Wird standardmäßig ausgegeben
		//CloudyLogic-> "It is White."Wird standardmäßig ausgegeben
		//RainyLogic-> "It is Gray."Wird standardmäßig ausgegeben
		logic.printSkyColor();
	}

Sie können sich das als "Aufzählen" der Logik vorstellen, die dem Typ entspricht, oder? Ist es etwas sauberer, wenn Sie den Aufzählungstyp gut verwenden?

Dachte ich und versuchte es tatsächlich.

Enum-Konvertierung

Erstellen Sie zunächst eine Aufzählungsklasse wie diese.

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;
	}
}

Die Seite, die die obige Aufzählung verwendet, sieht folgendermaßen aus.

	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();
	}

Es funktioniert immer noch, aber es funktioniert, ** Die Instanz der Logikklasse unterscheidet sich entscheidend von der vor der Änderung. ** **. ** Vor der Änderung wird jedes Mal eine Instanz erstellt, aber nach der Änderung ist es dieselbe Instanz. ** **. Das ist der Punkt.

Wie Sie aus der Quelle sehen können,

//System.out.print(logic.hashCode()+":");

Sie können den Hashwert überprüfen, indem Sie diesen Kommentar auf der Benutzerseite auskommentieren.


Die gleiche Instanz ist bequemer! Es kann einen Fall wie geben Dieses Mal werde ich versuchen, es zu einer separaten Instanz zu machen, indem ich "Vor der Änderung folgen" sage.

Aufzählung Teil 2

Separate Instanziierung bedeutet, nur die zu generierende Klasse zu definieren Es ist neu, wenn Sie es nennen, also sieht es so aus.

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;
	}
}

Ein bisschen mehr Umbau von hier.

return c.logic.newInstance();

Zuerst NewInstance () der Klasse ist in Java9 veraltet

Klasse getDeclaredConstructor (). NewInstance ()

Ersetzen Sie es hier wie in javadoc von java9 angegeben.

Außerdem können Parameter ohnehin zum Zeitpunkt des Konstruktors übergeben werden Schreiben Sie es also so um, dass die Parameter weitergeleitet werden.

Da für jeden Aufruf eine andere Instanz erstellt wird, wird der Klassenname ebenfalls auf Factory gesetzt.

Schließlich Es wurde behoben, dass eine Ausnahme ausgelöst wurde, anstatt null zurückzugeben. (Danke für deinen Rat!)

Dies widerspiegeln ... Dies ist das fertige Produkt.

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);
	}
}

Befolgen Sie diese Korrekturen Das Nullurteil des Anrufers ist nicht mehr erforderlich. Löschen Sie es daher.


Ich persönlich denke, dass dies ein wenig sauberer ist.

Nun, diese Art der Umgestaltung wird oft als Hobby bezeichnet. Ich denke, dass es unter Berücksichtigung von Betrieb und Wartung so gut wie möglich organisiert und bewusst codiert werden sollte.

Aufzählung studieren oder überprüfen? Ich werde es für einige Zeit beschreiben.

Recommended Posts

Versuchen Sie, Klassen nach Aufzählungstyp zu sortieren
Versuchen Sie, Klassen nach Aufzählungstyp zu sortieren
java: Wie schreibe ich eine generische Typliste? [Hinweis]
Aufzählung (Aufzählungstyp)
Ich möchte nach Tabulatortrennzeichen mit Rubin sortieren
[Java] Aufzählungstyp
Versuchen Sie, die Primzahl mit dem Booleschen Typ anzuzeigen
Versuche Edelstein freizugeben
Wie man einen Schrägstrich zurückschlägt \