Senden Sie Daten auf verschiedene Arten, je nachdem, wie Sie sie senden möchten

8

Ich habe eine Menge Schlüssel und Werte, die ich an unsere Nachrichtenwarteschlange senden möchte, indem wir sie in ein Byte-Array packen. Ich werde ein Byte-Array aller Schlüssel und Werte machen, die immer weniger als 50K sein sollten und dann an unsere Nachrichtenwarteschlange senden.

Paketklasse :

%Vor%

Unten ist die Art, wie ich Daten sende. Ab sofort erlaubt mein Design nur das asynchrone Senden von Daten durch den Aufruf von sendToQueueAsync method in der obigen sendData() Methode.

%Vor%

Jetzt muss ich mein Design erweitern, damit ich Daten auf drei verschiedene Arten senden kann. Es liegt am Benutzer zu entscheiden, auf welche Art er Daten senden will, entweder "sync" oder "async".

  • Ich muss Daten asynchron senden, indem ich sender.sendToQueueAsync method.
  • aufruft
  • oder ich muss Daten synchron senden, indem ich sender.sendToQueueSync method.
  • aufruft
  • oder ich muss Daten synchron aber an einem bestimmten Socket senden, indem ich sender.sendToQueueSync method aufruft. In diesem Fall muss ich irgendwie socket Variable übergeben, damit sendData von dieser Variable weiß.

SendRecord-Klasse :

%Vor%

Anrufer rufen nur eine der folgenden drei Methoden auf:

  • sendToQueueAsync durch Übergabe von zwei Parametern
  • sendToQueueSync durch Übergabe von zwei Parametern
  • sendToQueueSync durch Übergeben von drei Parametern

Wie soll ich meine Packet und SendRecord Klasse entwerfen, damit ich Packet class sagen kann, dass diese Daten auf eine der drei oben genannten Arten an meine Nachrichtenwarteschlange gesendet werden müssen. Der Benutzer muss entscheiden, auf welche Weise er Daten an die Nachrichtenwarteschlange senden möchte. Ab jetzt, wie meine Packet Klasse strukturiert ist, kann sie Daten nur auf eine Art senden.

    
user1950349 11.01.2018, 07:35
quelle

6 Antworten

4

Ich denke, Ihre beste Option ist das Strategie-Muster ( Ссылка ).

Mit diesem Muster können Sie das Verhalten jedes Typs von "send" kapseln, z. B. eine AsynchronousSend-Klasse, eine SynchronousSend-Klasse und eine AsynchronousSocketSend-Klasse. (Sie könnten wahrscheinlich bessere Namen finden). Die Klasse Packet kann dann basierend auf einer Logik entscheiden, welche Klasse verwendet werden soll, um die Daten an die Warteschlange zu senden.

    
Kerri Brown 11.01.2018, 08:36
quelle
2

Ich sehe die Definition von sender in Packet nicht. Ich nehme an, dass es als private Instanzvariable definiert ist?

Das Design muss in der Tat repariert werden. Wenn die Packet -Klasse das Senden durchführt, verstößt das Design gegen das Prinzip der einheitlichen Verantwortlichkeit . Es sollte eine separate (möglicherweise abstrakte) Klasse geben, die die zu sendenden Daten vorbereitet (bereitet eine java.nio.Buffer -Instanz vor) und sie kann eine oder mehrere Unterklassen haben, von denen eine eine java.nio.ByteBuffer -Instanz zurückgibt.

Eine separate Klasse, die ein Buffer erhält und das Senden durchführt. Diese (möglicherweise abstrakte) Klasse kann Unterklassen für die verschiedenen sendenden Plattformen und Methoden haben.

Dann benötigen Sie eine andere Klasse, die das Builder-Muster implementiert. Clients, die Pakete senden möchten, verwenden den Builder, um konkrete Packet und Sender (und möglicherweise andere erforderliche Eigenschaften wie eine Socket-Nummer) anzugeben, und rufen dann send() auf, das das Senden durchführt.

    
Sharon Ben Asher 11.01.2018 08:24
quelle
2

Sie könnten eine enum-Klasse haben, sagen wir PacketTransportionMode, bei der eine 'send' -Methode für verschiedene Arten von Enum-Werten überschrieben werden würde (SYNC, ASYNC, SYNC_ON_SOCKET), Beispiel:.

%Vor%

Außerdem muss in der Paketklasse die Variable transportationMode eingeführt werden. In der Implementierung von packet.send () kann this.packetTransportationMode.send (this)

aufgerufen werden

Der Client kann ein Paketobjekt erstellen und seinen transportationMode am Anfang einstellen, ähnlich wie bei RecordPartition. Dann kann der Client packet.send ();

aufrufen

Oder anstatt die transportationMode-Variable innerhalb der Paketklasse zu setzen und this.packetTransportationMode.send (this) aufzurufen, kann der Client auch ein Packet-Objekt erstellen und PacketTransportionMode.SYNC.send (packet) direkt aufrufen.

    
gargkshitiz 12.01.2018 06:46
quelle
2

Zuerst müssen Sie eine klare Antwort auf die Frage haben, wer (oder welcher Teil Ihres Codes) verantwortlich ist für die Entscheidung, welche Methode verwendet werden soll.

  • Basiert es auf einer externen Konfiguration?
  • Basiert es auf einer (dynamischen) Benutzerentscheidung?
  • Basiert es auf der verarbeiteten Partition?
  • Basiert es auf Nachrichteninhalt?

(Nur um ein paar Möglichkeiten zu nennen)

Die Antwort bestimmt, welche Struktur am besten geeignet ist.

Dennoch ist es klar, dass die aktuelle sendData() -Methode der Ort ist, an dem die Entscheidung in Kraft tritt. Daher muss diese Methode bereitgestellt werden, um die Implementierung zu verwenden. Die tatsächliche send() Wahrscheinlichkeit ist in allen Fällen ähnlich. Es wird vorgeschlagen, die Funktionalität sending in eine Schnittstelle zu kapseln, die die Methodensignatur send() bereitstellt:

%Vor%

Wenn der Ziel-Socket aus den tatsächlichen Nachrichtendaten bestimmt werden soll, bevorzugen Sie möglicherweise eine allgemeine Signatur von

%Vor%

und machen Sie diesen Socket-Wert optional oder verwenden Sie einen bestimmten Wert für die Codierung "keine spezifischen Socket" Fälle. Andernfalls könnten Sie eine bestimmte Sender -Instanz verwenden, bei der der Socket über Konstruktor übergeben wurde.

Ich sehe derzeit keinen gültigen Grund für die von Ihnen zur Verfügung gestellten Aufrufe, die drei verschiedenen Sendemethoden als drei verschiedene Methoden innerhalb einer Klasse zu implementieren. Wenn gemeinsamer Code ein Grund ist, ermöglicht die Verwendung einer gemeinsamen Basisklasse eine angemessene Freigabe.

Damit bleibt die Frage, wie die spezifische Instanz der entsprechenden Sender Implementierung in sendData() zur Verfügung gestellt werden soll.

Soll die sendende Strategie außerhalb von sendData() ermittelt werden, muss die Implementierung übergeben werden. Entweder als Parameter oder als Feld aus der aktuellen Klasseninstanz. Wenn die lokalen Daten die sendende Strategie bestimmen, sollten Sie die Bestimmung der richtigen Implementierung an eine Selektionsklasse delegieren, die die korrekte Implementierung zurückgibt. Der Anruf sieht dann ähnlich aus:

%Vor%

Obwohl es kein klareres Bild davon gibt, was festgelegt ist und was bei der Ausführung variabel ist, ist es schwierig, best approach zu empfehlen.

Falls die Entscheidung auf Daten basiert, ist der gesamte Auswahl- und Umleitungsprozess lokal für Packet class.

Wenn die Entscheidung extern zu Packet getroffen wird, möchten Sie vielleicht eine sendende Strategie-Implementierung an diesem Ort bekommen und diese als Parameter nach unten in addAndSendJunked() (oder genauer gesagt bis zu sendData() ) übergeben.

    
rpy 11.01.2018 13:28
quelle
2

Verwenden Sie enum varibale zum Definieren der Typen der Nachricht senden

%Vor%     
DHARMENDRA SINGH 17.01.2018 03:40
quelle
1

Strategie. Der Unterschied zu Kerri Browns Antwort ist, dass Packet keine Entscheidungen zwischen Strategien treffen sollte. Entscheiden Sie stattdessen außerhalb der Paketklasse.

Die Schnittstelle für einzelne sendende Strategien sollte von drei verschiedenen Klassen implementiert werden, die jeweils einem der genannten sendenden Ansätze entsprechen. Inject Strategie-Schnittstelle in das Paket, so dass Packet nicht ändern muss, unabhängig davon, welche Strategie es behandelt.

Sie sagten, dass es auf der Wahl des Benutzers basieren muss. So können Sie den Benutzer im Voraus fragen, was die Wahl ist, und dann basierend darauf die Implementierung einer sendenden Strategie-Schnittstelle instanziieren, die der Wahl des Benutzers entspricht. Instanziieren Sie dann das Paket mit der ausgewählten sendenden Strategie-Instanz.

Wenn Sie glauben, dass die spätere Wahl nicht vom Benutzer abhängt, dann machen Sie das zu einer Fabrik. So wird Ihre Lösung zu einer Kombination aus Fabrik und Strategie.

In diesem Fall kann Packet die Factory-Schnittstelle injizieren. Das Paket fragt die Factory nach der Sendungsstrategie. Als nächstes sendet es mit der von der Fabrik erworbenen Strategie. Factory fragt nach Benutzereingaben, die später ersetzt werden können, indem eine Auswahl basierend auf einer anderen Bedingung getroffen wird und nicht die Benutzereingabe. Dies erreichen Sie, indem Sie die Factory-Schnittstelle in Zukunft anders implementieren und diese neue Fabrik anstelle dieser einspeisen (d. H. Fabrik mit Benutzereingabe statt mit einer anderen auf Bedingungen basierenden Fabrik).

Beide Ansätze geben Ihnen einen Code, der dem Open / Close-Prinzip folgt. Aber versuchen Sie nicht zu übertreiben, wenn Sie keine Fabrik brauchen.

    
Tengiz 19.01.2018 22:54
quelle