[JAVA] So standardisieren Sie Operationen an Mengen - Sammlung erster Klassen -

So standardisieren Sie Operationen an Sets

Einführung

Ich habe zusammengefasst, was heutzutage in mir beliebt ist.

Diesen Inhalt lesen können

Machen Sie Operationen an Sets (Listen, Karten usw.) sinnvoll

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.

Beschränken Sie Operationen auf Sets (Arrays, Listen usw.).

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.

Beispiele im Artikel behandelt

Angenommen, eine Webanwendung aggregiert die Anzahl der Ereignisse (Push-Ereignisse), die auf GitHub für jedes Repository auftreten, und gibt sie auf Twitter frei.

die Architektur

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.

Überblick über die Spezifikationen

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

Vorher: Erstellen Sie einen Anwendungsdienst und aggregieren Sie.

Code

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

Problem

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

Implementierung durch erstklassige Sammlung

Code

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
}

Beiseite

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

So standardisieren Sie Operationen an Mengen - Sammlung erster Klassen -
Wie man mit Heroku einsetzt
Verwendung der Java-Klasse
So stellen Sie Laravel für CentOS 7 bereit
Wie man eine Ansicht auf Android "aushöhlt"
So zerlegen Sie eine Java-Klassendatei
Verwendung von Ruby on Rails
So stellen Sie Bootstrap auf Rails bereit
So führen Sie JavaFX unter Docker aus
Verwendung von Bio-Formaten unter Ubuntu 20.04
So dekompilieren Sie eine Java-Klassendatei
So installieren Sie MariaDB 10.4 unter CentOS 8
So installieren Sie WildFly unter Ubuntu 18.04
Verwendung von Klassenmethoden [Java]
[Java] Verwendung der Math-Klasse
So überprüfen Sie, ob Java auf einem Mac installiert ist
Ein Memorandum zur Verwendung von Eclipse
Verwendung von Apache Derby unter Eclipse
[Java] Verwendung der File-Klasse
So standardisieren Sie die Kopfzeile in Thymeleaf
So installieren Sie Eclipse (Photon) auf Ihrem Mac
Schritte zum Veröffentlichen einer Anwendung auf Heroku
So wechseln Sie Java-Versionen auf dem Mac
So installieren Sie Beta PHP8.0 unter CentOS8
So definieren Sie eine Bean der inneren Klasse
[Verarbeitung × Java] Verwendung der Klasse
So installieren Sie kafkacat unter Amazon Linux2
[Java] Verwendung der Calendar-Klasse
[Java] Verwendung der FileReader-Klasse und der BufferedReader-Klasse
So installieren Sie Netzwerktreiber unter eigenständigem Ubuntu
So speichern Sie Bilder auf Heroku in S3 unter AWS
So erstellen Sie eine Klasse, die Klasseninformationen erbt
So erhalten Sie eine Klasse von Element in Java
So konvertieren Sie einen Soliditätsvertrag in eine Java-Vertragsklasse
Hinweise zur Verwendung der einzelnen JUnit-Regeln
So fügen Sie die html.erb-Klasse in Rails bedingt hinzu
Beachten Sie, wie Sie auf Heroku bereitgestelltes MySQL zurücksetzen können
So installieren Sie mehrere JDKs unter Ubuntu 18.04 LTS
[Rails MySQL] So setzen Sie die Datenbank auf Heroku zurück
So erstellen Sie eine Pytorch-Umgebung unter Ubuntu
[Java] Memo zum Schreiben der Quelle