Problema di progettazione dell'applicazione client-server

1

Ho una collezione di client sul lato server. E ci sono alcuni oggetti che devono lavorare con quella collezione - aggiungere e rimuovere client, inviare messaggi a loro, aggiornare le impostazioni di connessione e così via. Dovrebbero eseguire queste azioni simultaneamente, quindi è richiesto mutex o un'altra primitiva di sincronizzazione. Voglio condividere un'istanza di raccolta tra questi oggetti, ma tutti richiedono l'accesso a campi privati di raccolta. Spero che l'esempio di codice renda più chiaro [C ++]:

class Collection
{
    std::vector< Client* > clients;
    Mutex mLock;
    ...
}

class ClientNotifier
{
    void sendMessage()
    {
         mLock.lock();
         // loop over clients and send message to each of them
    }
}

class ConnectionSettingsUpdater
{
    void changeSettings( const std::string& name )
    {
        mLock.lock();
        // if client with this name is inside collection, change its settings
    }
}

Come puoi vedere, tutte queste classi richiedono l'accesso diretto ai campi privati della Collezione.

Puoi darmi un consiglio su come implementare correttamente questo comportamento, ad esempio mantenendo l'interfaccia di Collection semplice senza che sia a conoscenza dei suoi utenti?

    
posta user2547823 30.09.2013 - 19:47
fonte

2 risposte

1

Dal tuo snippet di codice limitato, quello che capisco è che la classe Collection è una classe data-centrica che contiene un vettore di Client* e così via. Le altre 2 classi sono metodo-centrica e usano un oggetto Collection (non sono sicuro di come, ma presumibilmente l'oggetto è un membro di questa classe o viene passato in qualche modo ai metodi).

Il mio suggerimento sarebbe di unire queste classi incentrate sui dati e basate sui metodi. La classe Collection rappresenta correttamente un insieme di Client s in modo che il disegno sia puntuale. Ma le altre classi stanno effettivamente eseguendo operazioni su Collection - ecco perché si finisce per richiedere l'accesso ai membri privati. Qualsiasi operazione eseguita su un'istanza di una classe dovrebbe essere funzioni membro di quella classe stessa.

Pertanto, sendMessage() dovrebbe essere un membro della classe Collection , poiché stai inviando un messaggio a tutti Client s in Collection .

Ora, questo potrebbe sembrare un suggerimento ingenuo dal momento che sembra che tu stia cercando di raggruppare i metodi relativi alla notifica dei client nella classe ClientNotifier . Se vuoi rimanere con questo approccio, ecco una soluzione che potrebbe aiutarti:

class Collection
{
    private:
        std::vector< Client* > m_clients;
        Mutex m_mLock;

    public:
        void sendMessage()
        {
            ClientNotifier objClientNotifier;  // Create an instance of the ClientNotifier class that provides this functionality

            /* Loop through all clients in the member vector to send a message to each of them */
            for (std::vector<Client*>::iterator itrClients = m_clients.begin(); itrClients != m_clients.end(); ++itrClients) {
                m_mLock.lock();  // Member mutex access through a member function, which is acceptable
                objClientNotifier.sendMessage(*itrClients);
                m_mLock.unlock();
            }
        }
}

class ClientNotifier
{
    public:
        void sendMessage(Client* pobjClient)
        {
             /* Use the pointer to a Client object to send a message to that client */
        }
}
    
risposta data 17.11.2013 - 09:08
fonte
0

Potresti implementare una semplice funzione di blocco e funzioni di iterazione per evitare di esporre le variabili private. Se si desidera riutilizzarlo, è possibile utilizzare un pattern di mixaggio. Ad esempio (pseudo codice):

class Collection {
    bool getLock(){};
    bool unlock(){};
    Client* getClient(){};
    Client* getNextClient(){
        // returns null when there are no more clients
     }
 }

A search for mixins will show you how to abstract this idea.
    
risposta data 06.10.2013 - 07:50
fonte

Leggi altre domande sui tag