[JAVA] Comment standardiser les opérations sur les ensembles -Première collection de classe-

Comment standardiser les opérations sur les ensembles

introduction

J'ai résumé ce qui est populaire en moi ces jours-ci.

Être capable de lire ce contenu

Rendre les opérations sur les ensembles (listes, cartes, etc.) significatives

Ce qui était initialement préparé comme une opération sur un ensemble est ** trop fin ou trop spécifique **, et il est difficile de comprendre ce que cela signifie pour l'utilisateur du logiciel. Ici, pour un ensemble Nous résumerons les opérations avec une granularité significative pour l'utilisateur.

Limiter les opérations sur les ensembles (tableaux, listes, etc.)

Différentes méthodes sont définies à l'avance dans la classe (liste ou mappe) qui représente un ensemble. Cependant, il se peut que vous ne souhaitiez pas utiliser des méthodes dans la logique métier. Par exemple, dans le cas d'utilisation de l'agrégation sur un certain ensemble, Il n'est pas nécessaire d'écrire dans l'ensemble. Inversement, l'état de capacité d'écrire peut provoquer un bogue. La méthode d'implémentation introduite ici peut être utilisée pour limiter les opérations à l'ensemble.

Exemples traités dans l'article

Supposons qu'une application Web agrège le nombre d'événements (événements Push) qui se produisent sur GitHub pour chaque référentiel et le partage sur Twitter.

architecture

Supposons une configuration multi-modules dans laquelle les éléments suivants sont divisés en modules.

Nom du module La description
web Il existe un package Web qui gère les E / S du navigateur et un package d'application qui réalise les spécifications de l'application..
domain Exprimer la logique métier avec des entités et des modèles.
infrastructure Implémenter l'interface définie dans la couche de domaine.

Aperçu des spécifications

Le code implémente la logique pour agréger le nombre d'événements qui se sont produits sur GitHub pour chaque référentiel Git. Le code est

La classe GitEvent est définie comme suit.

domain.GitEvent.scala


class GitEvent(val gitRepository: GitRepository, val eventType: GitEventType)

Vous pouvez également obtenir une collection de GitEvents via la méthode getUserEvents de GitEventClient.

domain.client.GitEventClient.scala


trait GitEventClient {
  def getUserEvents(gitAccount: GitAccount): Seq[GitEvent]
}

Avant: créer un service d'application et un agrégat.

code

Dans un premier temps, j'ai utilisé le service d'application pour effectuer l'agrégation.Peut-être même en entreprise, le service d'application appelle souvent la méthode de la couche d'accès aux données et traite les données acquises.

web.application.GitActivitySummaryService.scala


class GitActivitySummaryService(){
  def summarize(userId: UserId): Seq[GitActivitySummary] = {
    val accountService: GitAccountService = new GitAccountService()
    val gitAccount = accountService.getByUserId(userId)

    //Obtenez des événements en fonction des informations de compte Git acquises.
    val eventClient: GitEventClient = new GitHubEventClient()
    val gitEvents: Seq[GitEvent] = eventClient.getUserEvents(gitAccount)
    
    //Regrouper par référentiel,Informations sur le référentiel,Générer une collection d'instances avec un certain nombre de fois
    events.groupBy(e => e.gitRepository).map(e => new GitActivitySummary(e._1, e._2.size)).toSeq
  }
}

problème

Le plus gros problème avec ce code est que la logique d'agrégation d'événements peut être implémentée à différents endroits. Par exemple, jusqu'à présent, seule l'agrégation en temps réel était effectuée sur le Web, mais que faire si la demande suivante se présente?

Étant donné que les autorisations sur les ressources sont différentes entre les applications Web et les lots, nous avons décidé de créer un module batch.

Bien que le lot nécessite la même logique d'agrégation que l'application Web, il ne peut pas être référencé à partir du lot car la logique a été écrite dans le module Web lors de l'implémentation de l'application Web.

I "Je ne peux pas vous aider, copiez la même classe dans le module batch." Tout le monde "Attendez, attendez, attendez."

Implémentation par collection de première classe

code

J'essaie d'automatiser l'agrégation des événements Git, donc je pense que la logique d'agrégation est la plus grande préoccupation de cette application.C'est pourquoi j'ai créé la classe GitEvents dans le module domain. ..

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 renvoie également une instance de la classe GitEvents, donc Seq [GitEvent] ne peut plus être manipulé directement en dehors de la classe GitEvents. L'encapsulation orientée objet est quelque chose comme ça.

domain.client.GitEventClient.scala


trait GitEventClient {
  def getUserEvents(gitAccount: GitAccount): GitEvents
}

De côté

En exposant la méthode de la collection de champs via la classe wrapper comme indiqué ci-dessous, il est possible d'opérer la collection de champs comme si elle était gérée directement.

def foreach(f: GitEvent => Unit) = events.foreach(f)

def map[T](f:GitEvent=>T)=events.map(f)

Si nécessaire, vous pouvez implémenter les méthodes définies dans la collection de champs pour fournir l'API à la classe appelante comme si vous manipuliez directement la collection. Vous pouvez également écrire une expression for en implémentant la méthode iterator.

def iterator = events.iterator

for ( event <- events) {
  println(event.eventType)
}

Recommended Posts

Comment standardiser les opérations sur les ensembles -Première collection de classe-
Comment déployer avec heroku
Comment utiliser la classe Java
Comment déployer Laravel sur CentOS 7
Comment "évider" une vue sur Android
Comment désassembler un fichier de classe Java
Comment utiliser Ruby on Rails
Comment déployer Bootstrap sur Rails
Pour exécuter JavaFX sur Docker
Comment utiliser les bio-formats sur Ubuntu 20.04
Comment décompiler un fichier de classe Java
Comment installer MariaDB 10.4 sur CentOS 8
Comment installer WildFly sur Ubuntu 18.04
Comment utiliser les méthodes de classe [Java]
[Java] Comment utiliser la classe Math
Comment vérifier Java installé sur Mac
Un mémorandum sur l'utilisation d'Eclipse
Comment utiliser Apache Derby sur Eclipse
[Java] Comment utiliser la classe File
Comment normaliser le pied de page d'en-tête dans Thymeleaf
Comment installer Eclipse (Photon) sur votre Mac
Étapes pour publier une application sur Heroku
Comment changer de version de Java sur Mac
Comment installer la beta php8.0 sur CentOS8
Comment définir un bean de classe interne
[Traitement × Java] Comment utiliser la classe
Comment installer kafkacat sur Amazon Linux2
[Java] Comment utiliser la classe Calendar
[Java] Comment utiliser la classe FileReader et la classe BufferedReader
Comment installer les pilotes réseau sur Ubuntu autonome
Comment enregistrer des images sur Heroku dans S3 sur AWS
Comment créer une classe qui hérite des informations de classe
Comment obtenir une classe depuis Element en Java
Comment convertir un contrat de solidité en une classe de contrat Java
Notes sur l'utilisation de chaque règle de JUnit
Comment ajouter conditionnellement une classe html.erb dans Rails
Remarquez comment restaurer Mysql déployé sur Heroku
Comment installer plusieurs JDK sur Ubuntu 18.04 LTS
[Rails MySQL] Comment réinitialiser la base de données sur heroku
Comment créer un environnement Pytorch sur Ubuntu
[Java] Mémo sur la façon d'écrire la source