Ich habe zusammengefasst, was heutzutage in mir beliebt ist.
Was ursprünglich als Operation an einem Set vorbereitet wurde, ist ** zu fein oder zu spezifisch **, und es ist schwer zu verstehen, was es für den Benutzer der Software bedeutet. Hier für ein Set Wir werden die Operationen in einer Granularität zusammenfassen, die für den Benutzer von Bedeutung ist.
In der Klasse (Liste oder Zuordnung), die eine Menge darstellt, werden im Voraus verschiedene Methoden definiert. Es kann jedoch Methoden geben, die Sie in der Geschäftslogik nicht verwenden möchten. Es ist nicht erforderlich, in die Menge zu schreiben. Umgekehrt kann der Status des Schreibens einen Fehler verursachen. Die hier vorgestellte Implementierungsmethode kann verwendet werden, um die Operationen auf die Menge zu beschränken.
Angenommen, eine Webanwendung aggregiert die Anzahl der Ereignisse (Push-Ereignisse), die auf GitHub für jedes Repository auftreten, und gibt sie auf Twitter frei.
Nehmen Sie eine Konfiguration mit mehreren Modulen an, bei der die folgenden Elemente in Module unterteilt sind.
Modulname | Erläuterung |
---|---|
web | Es gibt ein Webpaket, das die E / A des Browsers verwaltet, und ein Anwendungspaket, das die Spezifikationen der Anwendung realisiert.. |
domain | Drücken Sie Geschäftslogik mit Entitäten und Modellen aus. |
infrastructure | Implementieren Sie die in der Domänenschicht definierte Schnittstelle. |
Der Code implementiert die Logik, um die Anzahl der auf GitHub aufgetretenen Ereignisse für jedes Git-Repository zu aggregieren. Der Code ist
Die GitEvent-Klasse ist wie folgt definiert.
domain.GitEvent.scala
class GitEvent(val gitRepository: GitRepository, val eventType: GitEventType)
Sie können eine Sammlung von GitEvents auch über die getUserEvents-Methode von GitEventClient abrufen.
domain.client.GitEventClient.scala
trait GitEventClient {
def getUserEvents(gitAccount: GitAccount): Seq[GitEvent]
}
Zuerst habe ich den Anwendungsdienst verwendet, um eine Aggregation durchzuführen. Vielleicht ruft der Anwendungsdienst sogar im Geschäftsleben häufig die Methode der Datenzugriffsschicht auf und verarbeitet die erfassten Daten.
web.application.GitActivitySummaryService.scala
class GitActivitySummaryService(){
def summarize(userId: UserId): Seq[GitActivitySummary] = {
val accountService: GitAccountService = new GitAccountService()
val gitAccount = accountService.getByUserId(userId)
//Erhalten Sie Ereignisse basierend auf den erfassten Git-Kontoinformationen.
val eventClient: GitEventClient = new GitHubEventClient()
val gitEvents: Seq[GitEvent] = eventClient.getUserEvents(gitAccount)
//Nach Repository gruppieren,Repository-Informationen,Generieren Sie eine Sammlung von Instanzen mehrmals
events.groupBy(e => e.gitRepository).map(e => new GitActivitySummary(e._1, e._2.size)).toSeq
}
}
Das größte Problem bei diesem Code ist, dass die Ereignisaggregationslogik an verschiedenen Stellen implementiert werden kann. Bisher wurde beispielsweise nur eine Echtzeitaggregation im Web durchgeführt. Was ist jedoch zu tun, wenn die folgende Anforderung auftritt?
Da die Berechtigungen für Ressourcen zwischen Web-Apps und Batch unterschiedlich sind, haben wir beschlossen, ein Batch-Modul zu erstellen.
Obwohl für Batch dieselbe Aggregationslogik wie für die Webanwendung erforderlich ist, kann nicht auf Batch verwiesen werden, da die Logik bei der Implementierung der Webanwendung in das Webmodul geschrieben wurde.
I "Ich kann nicht anders, kopiere ich dieselbe Klasse in das Batch-Modul?" Alle "Warte, warte, warte."
Ich versuche, die Aggregation von Git-Ereignissen zu automatisieren, daher denke ich, dass die Aggregationslogik das Hauptanliegen in dieser App ist. Deshalb habe ich die "GitEvents" -Klasse im "Domain" -Modul erstellt. ..
domain.gitEvents.scala
class GitEvents (private val events: Seq[GitEvent]) {
def countByRepository() = {
val gitActivitySummaries = events.groupBy(e => e.gitRepository).map(e => new GitActivitySummary(e._1, e._2.size)).toSeq
new GitActivitySummaries(gitActivitySummaries)
}
}
GitEventClient gibt auch eine Instanz der GitEvents-Klasse zurück, sodass Seq [GitEvent] nicht mehr direkt außerhalb der GitEvents-Klasse bearbeitet werden kann. Die objektorientierte Kapselung ist ungefähr so.
domain.client.GitEventClient.scala
trait GitEventClient {
def getUserEvents(gitAccount: GitAccount): GitEvents
}
Indem Sie die Methode der Feldsammlung über die Wrapper-Klasse wie unten gezeigt verfügbar machen, können Sie die Feldsammlung so betreiben, als ob sie direkt behandelt würde.
def foreach(f: GitEvent => Unit) = events.foreach(f)
def map[T](f:GitEvent=>T)=events.map(f)
Bei Bedarf können Sie die in der Feldsammlung definierten Methoden implementieren, um der aufrufenden Klasse die API bereitzustellen, als würden Sie die Sammlung direkt bearbeiten. Sie können auch einen for-Ausdruck schreiben, indem Sie die Iteratormethode implementieren.
def iterator = events.iterator
for ( event <- events) {
println(event.eventType)
}
Recommended Posts