Estendi una classe in un'architettura esistente?

0

La domanda è rilevante solo per i linguaggi di programmazione tipizzati, le soluzioni dinamiche non sono soddisfacenti. Supponiamo che il linguaggio sia C ++.

Architettura di esempio:

- DisplayObject (base class)
-- Container (derived from DisplayObject)
-- Sprite (derived from DisplayObject)

Quindi ho un motore di gioco tra le mani e ha solo le coordinate X e Y. Diciamo che voglio aggiungere una coordinata Z. Per fare questo, dovrei modificare la classe base DisplayObject . Perché se ne derivassi semplicemente per aggiungere la funzionalità dell'asse Z, renderebbe impossibile utilizzare le classi Container e Sprite nel mio codice senza inviarle al mio nuovo DisplayObject .

La domanda è, come risolverlo senza usare il casting?
Esistono dozzine di classi derivate da DisplayObject , quindi modificarle tutte una ad una apparirebbero molto strane.
Mi è stata suggerita anche la delega, ma non vedo come applicarla qui.

    
posta ohyou 30.12.2016 - 12:33
fonte

2 risposte

1

Se la funzionalità dell'asse Z deve essere supportata da tutte le classi derivate da DisplayObject , o se la funzionalità deve essere esposta nell'interfaccia della classe base, l'unica opzione efficace è modificare DisplayObject classe stessa.

Se la funzionalità dell'asse Z è rilevante solo per un sottoinsieme delle classi derivate, puoi creare una nuova classe DisplayObject3D e modificare l'albero di ereditarietà in modo che le classi che necessitano dell'asse Z derivino da DisplayObject3D . Ad esempio:

- DisplayObject (base class)
-- Container (derived from DisplayObject; doesn't need Z-axis)
-- DisplayObject3D (derived from DisplayObject)
--- Sprite (derived from DisplayObject3D)

In entrambi i casi, stai apportando una modifica così fondamentale che è necessario rivedere le classi derivate tutte per vedere come la funzionalità dell'asse Z le influenza. E possibilmente apportare modifiche a un numero di essi.

    
risposta data 30.12.2016 - 13:42
fonte
0

L'aggiunta di una terza dimensione alla classe base con Z predefinita a 0 risolverebbe il tuo problema senza rompere nulla. Tuttavia questo è solo caso specifico e in un esempio non banale potrebbe essere molto più difficile ri-implementare la classe esistente senza distruggere il caos nel tuo progetto. Inoltre, considera che le classi che non richiedono la terza dimensione ora conterranno il membro Z inutilizzato, che odora di odore di codice.

Secondo me, il problema risiede nel fatto che DisplayObject non è stato progettato come tale:

template <class DisplayObjectImpl>
class DisplayObject
{

  DisplayObject()
  : impl(new DisplayObjectImpl)
  {}

  virtual void render()
  {
    impl -> render
  }

  DisplayObject * impl;
}

class DisplayObject2D : public DisplayObject<DisplayObject2D>
{
  void render()
  {
    // some specific implementation of render
  }
}

class DisplayObject3D : public DisplayObject<DisplayObject3D>
{
  void render()
  {
    // some specific implementation of render
  }
}

o

class DisplayObject
{
  static DisplayObject getDisplayObject2D()
  {
    DisplayObject object;
    impl = new DisplayObject2D;
    return object;
  }
  static DisplayObject getDisplayObject3D()
  {
    DisplayObject object;
    impl = new DisplayObject3D;
    return object;
  }
  virtual void render()
  {
    impl -> render
  }

  DisplayObject * impl;
}

class DisplayObject2D : public DisplayObject
{
  void render()
  {
    // some specific implementation of render
  }
}

class DisplayObject3D : public DisplayObject
{
  void render()
  {
    // some specific implementation of render
  }
}

A mio avviso, puoi ricorrere all'hacking della classe esistente con risultati insoddisfacenti (aggiungi semplicemente z) o correggere la radice del problema (ridefinirlo come una delle soluzioni precedenti) e probabilmente sprecare un sacco di tempo su nulla produttivo (a meno che tu non abbia intenzione di supportare il rendering 4-dimensionale e 5-dimensionale in futuro;))

    
risposta data 30.12.2016 - 16:48
fonte

Leggi altre domande sui tag