Java von den Grundlagen bis zum Profi — Folge 10
Erstellen Sie wartbare Apps mit Ebenen und Tests
Die in diesem Blog verfassten Artikel wurden mit dem Ziel erstellt, zu unterrichten. Außerdem können die Informationen im Artikel falsch sein, also seien Sie bitte vorsichtig.
Wenn ein Programm wächst, wird das Ausmaß der Verbreitung von Änderungen wichtiger als die Anzahl der Kurse. Lassen Sie uns unsere Java-Serie abschließen, indem wir Regeln, Speicher und Bildschirmgrenzen aufteilen und das Verhalten testbar machen.
Hierarchie der Verantwortung
public final class OrderService {
private final ItemRepository repository;
public OrderService(ItemRepository repository) {
this.repository = repository;
}
public OrderResult buy(int itemId, int gold) {
Item item = repository.find(itemId)
.orElseThrow(() -> new ItemNotFoundException(itemId));
if (gold < item.getPrice()) {
return OrderResult.notEnoughGold();
}
return OrderResult.success(item, gold - item.getPrice());
}
}
Der Dienst ist für die Kaufregeln verantwortlich und kennt die Datenbank- oder HTTP-Implementierungsdetails nicht direkt. Der Controller oder Bildschirm übergibt Eingaben an den Dienst und präsentiert das Ergebnis.
Abhängigkeiten außen vor lassen
public interface ItemRepository {
Optional<Item> find(int id);
}
ItemRepository repository = new FileItemRepository(path);
OrderService service = new OrderService(repository);
Wenn der konkrete Speicher außerhalb des Konstruktors ausgewählt wird, können Tests ihn durch eine Speicherimplementierung ersetzen. Schnittstellen sind nicht Dekorationen für jede Klasse, sondern werden an der Grenze platziert, an der sich externe Technologien ändern.
Testbetrieb
@Test
void purchaseKeepsRemainingGold() {
ItemRepository repository = new MemoryItemRepository(
new Item(10, "Potion", 30)
);
OrderService service = new OrderService(repository);
OrderResult result = service.buy(10, 100);
assertEquals(70, result.getRemainingGold());
}
Der Test überprüft extern sichtbare Regeln und nicht die interne Methodenaufrufreihenfolge. Selbst wenn Sie die Implementierung bereinigen, können Sie sehen, ob derselbe Vertrag für dieselbe Eingabe gilt.
Projektwerkzeuge
Gradle oder Maven führen Kompilierung, Tests, Bibliotheksversionierung und Verpackung in wiederholbare Befehle durch. Platzieren Sie Build-Dateien und Tests gemeinsam im Repository, damit das Projekt nicht nur in der Entwicklungsumgebung ausgeführt wird.
Eine gute Java-Struktur besteht nicht aus vielen Hierarchien. Es handelt sich um eine Struktur, in der die Regeln für Statusänderungen, externe Ressourcen und die Lebensdauer gleichzeitiger Aufgaben klar sind und in kleinen Einheiten überprüft werden können.