Pattern degli oggetti di estensione

0

In questo MSDN Magazine articolo Peter Vogel descrive Extension Objects partten .

Ciò che non è chiaro è se le estensioni possono essere successivamente implementate dal codice client che risiede in un assembly separato .
E se è così come in questo caso l'estensione può accedere ai membri privati dell'obiettivo che sono stati estesi ?

Ho abbastanza spesso bisogno di impostare diversi livelli di accesso per classi diverse.
A volte ho davvero bisogno che i discendenti non abbiano accesso al mebmer ma la classe separata lo fa. (buone classi di vecchio amico)

Ora risolvo questo in C # esponendo le proprietà callback nell'interfaccia della classe esterna e impostandole con metodi privati. Ciò consente anche di regolare l'accesso: sola lettura o lettura | scrittura in base all'interfaccia desiderata.

class Parent
{
    private int foo;

    public void AcceptExternal(IFoo external)
    {
        external.GetFooCallback = () => this.foo;
    }
}

interface IFoo
{
    Func<int> GetFooCallback {get;set;}
}

L'altro modo è implementare esplicitamente una particolare interfaccia.

Ma sospetto che esistano altri attacchi di sospetto.

Aggiornamento 1
Il articolo di New Peter lo rende un po 'più chiaro.

    
posta Pavel Voronin 27.04.2013 - 10:22
fonte

1 risposta

2

Penso che tu abbia perso un po 'del punto dell'articolo. Quando parlava di pensare nell'estensione, stava parlando di un concetto, e non di un particolare modello di design. Esistono diversi modelli di progettazione che consentono l'estensione dei tuoi oggetti, questo dipende molto da come lo vuoi fare. Lasciatemi citare ciò che secondo 2 potrebbe essere il migliore per consentire l'estensione:

Motivo decoratore:

private interface IPrice
{
    int Price { get; }
}

private class PriceDecorator : Pizza
{
    IPrice _price;

    protected virtual int OriginalPrice { get { return 0; } }

    public virtual int Price
    {
        get { return OriginalPrice + _price.Price; }
    }
    protected PriceDecorator() { }

    public PriceDecorator(IPrice price)
        : this()
    {
        _price = price;
    }
}

private class Pizza : PriceDecorator
{
    public Pizza(IPrice price) : base(price){}
    protected Pizza()  { }

    protected override int OriginalPrice
    {
        get { return 10; }
    }
}

class Cheese : PriceDecorator
{
    protected Cheese()  {    }
    public Cheese(IPrice price) : base(price) { }

    protected override int OriginalPrice
    {
        get { return 2; }
    }
}

class Pepperoni : PriceDecorator
{
    protected Pepperoni() {}
    public Pepperoni(IPrice price) : base(price){ }

    protected override int OriginalPrice
    {
        get { return 1; }
    }
}

class test
{
    void run()
    {
        var pizzaWithCheese = new Pizza(new Cheese());
        var pizzaWithCheeseAndPepperoni = new Pizza(new Cheese(new Pepperoni()));
    }
}

Modello di progettazione della strategia:

Puoi leggere più qui

abstract class StrategyBase
{
    public abstract void DoSomething();
}

class ConcreteStrategyA : StrategyBase
{
    public override void DoSomething()
    {
        Console.WriteLine("Called ConcreteStrategyA.DoSomething()");
    }
}

class ConcreteStrategyB : StrategyBase
{
    public override void DoSomething()
    {
        Console.WriteLine("I did something!");
    }
}

/// This is the class that you allow extension, using any of the strategies 
class Context
{
    private StrategyBase _strategy;

    public Context(StrategyBase strategy)
    {
        this._strategy = strategy;
    }

    public void DoSomething()
    {
        _strategy.DoSomething();
    }
}

// Use it like this:
var c = new Context(new ConcreteStrategyA());
c.DoSomething();
    
risposta data 24.05.2013 - 00:27
fonte

Leggi altre domande sui tag