Qual è il nome di questo modello (se presente)?

2

C'è una sorta di schema in cui mi sono imbattuto in "scoprire" che sembra estremamente utile, ma non l'ho mai visto prima. È una specie di modo per ottenere l'ereditarietà attraverso un'interfaccia. È davvero strano dove la classe "diventa" ciò che accetta. (Scritto qui in C # ma non deve essere.)

interface IContainer {
   Thing Thing { get; }
}

class Concrete : IContainer {
   public Thing Thing { get; }

   public Concrete(IContainer container) {
      Thing = container.Thing;
   }

   // or...

   public Concrete() {
      Thing = BuildAnotherContainer().Thing;
   }
}

Un esempio più realistico che è simile a quello che uso veramente:

interface IControlContainer {
   Control Control { get; }
}

public class FancyControl : IControlContainer {
   public Control Control { get; }

   public FancyControl() {
      Control = BuildControl().Control;
   }
}

BuildControl() è veramente un codice che costruisce un oggetto da uno script. L'oggetto è uno dei molti altri oggetti IControlContainer progettati per creare controlli utilizzando determinati modelli (come il layout di una tabella).

Si noti come l'oggetto esterno "diventa" effettivamente l'oggetto interno. Ultimamente ho pensato che mi ricordasse quasi l'eredità prototipale in JavaScript, ma non ne sono sicuro. Mi piacerebbe leggere di più su questo e trovare altri modi per applicarlo, ma non penso di averlo mai visto prima e non riesco a trovare nulla al riguardo.

So che non è il pattern Composite, perché si tratta di creare una gerarchia / un albero di oggetti.

So che non è solo una composizione lineare, perché il punto qui è che per un estraneo, non c'è differenza tra gli oggetti interni ed esterni (se visualizzati come IContainer s), ma in realtà differiscono e hanno differenze implementazioni.

Ecco un esempio ancora più concreto:

interface IControlContainer {
   Control UntypedControl { get; }
}

interface IControlContainer<TControl> : IControlContainer
where TControl : Control {
   TControl Control { get; }
}

class TableLayoutHelper : IControlContainer<TableLayoutPanel> {
   public Control UntypedControl => Control;
   public TableLayoutPanel Control { get; }

   public TableLayoutHelper() {
      Control = new TableLayoutPanel { Size = new Size(500, 500) };
   }

   // lots of code that makes building a UI with a table layout nice and easy
}
class EmployeeControl : IControlContainer {
   public Control UntypedControl { get; }

   public TextBox NameBox { get; }

   public EmployeeControl() {
      var tlh = new TableLayoutHelper();

      // use tlh to build a table layout        
      NameBox = tlh.AddTextBox("Name");

      UntypedControl = tlh.UntypedControl;
   }
}

class ControlContainerForm : Form {
   // a windows form that can host any IControlContainer
}

// then compose a ControlContainerForm with a new EmployeeControl

Nota come EmployeeControl "IS" a TableLayoutHelper , almeno se considerato come IControlContainer . Lo stesso TLH può anche posizionare IControlContainer s nella sua struttura tabellare. E puoi comporre nuovi IControlContainer s su quelli esistenti, come posso mettere un EmployeeControl su un altro IControlContainer da qualche altra parte, e così via ...

Ho usato un sistema analogo anche in un quadro di reporting e fa miracoli.

    
posta Dave Cousineau 09.09.2018 - 21:07
fonte

3 risposte

2

Quello che hai mostrato nei tuoi esempi è semplicemente un Adapter a.k.a. Wrapper . Hai anche estratto un metodo get per recuperare l'oggetto spostato in un'interfaccia esplicita, che non è necessariamente parte di quel modello, ma probabilmente utile per il tuo caso.

Non è un classico Decorator , poiché ciò richiederebbe che l'adattatore abbia un'interfaccia comune con l'oggetto spostato.

    
risposta data 10.09.2018 - 02:47
fonte
0

Il pattern, se insisti a chiamarlo così, è fondamentalmente un costruttore di copia .

Il primo esempio è uno superficiale e il secondo esempio è uno profondo.

    
risposta data 09.09.2018 - 22:20
fonte
0

Questo mi sembra il modello della strategia. Il tuo ControlContainerForm è il contesto, il tuo IControlContainer è la strategia che cambia il modo in cui il modulo funziona

+--------------------+     +-----------------+
|ControlContainerForm+---->+IControlContainer|
+--------------------+     +-----+-----+-----+
                                 ^     ^
                                 |     |
                +----------------++  +-+-------------+
                |IControlContainer|  |EmployeeControl|
                +-----------------+  +---------------+
    
risposta data 10.09.2018 - 01:51
fonte

Leggi altre domande sui tag