Come ottenere la classe di comportamento dalla sua classe di dati quando sono separati ai fini della comunicazione server-client?

2

Sto scrivendo un programma client-server con la seguente idea (analogia per il mio vero programma). Ci sono molti tipi di forme. Il client rappresenta le forme all'utente che può accodare le operazioni (come la traduzione, la rotazione ...) su di esse. Il client invia al server id e tipo di operazione. Il server esegue l'operazione e invia i nuovi dati di forma al client.

Nel mio attuale design ho le classi che dettaglio di seguito.

La classe Shape si trova solo sul server, le sue sottoclassi contengono algoritmi per eseguire le operazioni per ogni forma (fingere che ruotare un triangolo e un quadrato sia molto diverso). Non voglio né ho bisogno che siano accessibili al cliente.

abstract class Shape {

    ShapeData data; // see below
    int[] plane; // some non-static parameter used by the server

    abstract void rotate();
    abstract void translate();
    abstract void rescale();
    // ... 10 more
}

Anche le sottoclassi siedono solo sul server

class Square extends Shape {

    void rotate()    { /* using ShapeData data and int[] plane ...*/ }
    void translate() { /*    "   */ };
    void rescale()   { /*    "   */ };
}

class Circle extends Shape {

    // same structure as square
}

// many more shapes

ShapeData è una classe che contiene i dati di una forma (stessa struttura dati per tutte le forme). È la classe che viene trasferita dal server al client da cui il client può, ad esempio, disegnare la forma. La classe viene anche utilizzata dal server per eseguire i calcoli come visto sopra.

abstract class ShapeData implements Serializeable {

    int id; // after manipulating the shape represented by this class, the
            // client send this id back to the server

    int edgesNum;
    int width;
    int height;
    // ...

    // setters and getters
}

Comprendo che separare dati e comportamenti non è un approccio OO, ma considero questa classe come un DTO ( riferimento )-classi-senza-metodi chiamare.

Ottenere i dati di forma dalla forma è semplice poiché è "composto" in esso, il problema è il contrario. Il server conserva un List<ShapeData> che recupero da id , ma non esiste un modo ovvio per ottenere Shape su cui applicare la trasformazione. Questo mi ha portato a pensare che il design sia pessimo.

In questo momento tengo un Map<ShapeData, Shape> per recuperare Shape . Un altro modo è quello di aggiungere un campo id a Shape con lo stesso valore di ShapeData e mantenere un List<Shape> da cui recupero anche per id .

Il design è brutto o ci sono solo alcune modifiche che posso fare per farlo funzionare "correttamente"?

    
posta user1803551 14.12.2015 - 22:30
fonte

1 risposta

1

Il design non è intrinsecamente cattivo. Prendiamo il caso che le trasformazioni da eseguire sulle forme consumino risorse e questa è una ragione sufficiente per avere il comportamento sul server.

In MHO l'id corrispondente è la strada da percorrere. Quindi si passa un oggetto List<ShapeData> avanti e indietro. Il client riceve tale lista e rende grafica. Il server riceve un elenco di questo tipo e confronta ogni ShapeData con il corrispondente Shape per effettuare le trasformazioni.

Modifica

(1) Perché preferisci questo approccio?

Per me ogni diverso tipo di Shape è un oggetto peso piuma , i dati vengono iniettati ogni volta che è necessaria una trasformazione.

L'id potrebbe aiutare a implementare il Chain-of_responsability modello in cui ogni oggetto del processore vede se i dati sono per farli funzionare devono passare al processore successivo.

(2) Il client invia solo l'id e la richiesta di trasformazione (non inclusa nelle mie classi sopra), non vedo perché dovrebbe passare l'intera classe di dati invariata.

Quindi i server non devono avere una copia permanente di ogni oggetto dell'utente. Gli oggetti vivono nel client, vengono inviati al server e il server li restituisce trasformati, servder non ha bisogno di avere una copia sincronizzata di essi. IMHO.

(3) Quindi suggerisci di mantenere un List<Shape> e cercarlo per id

In questo modo puoi implementare modelli chain-of_responsability e flyweight.

    
risposta data 15.12.2015 - 21:13
fonte

Leggi altre domande sui tag