Composite Pattern and simplificaton

Kenji Hara k.hara.pg at gmail.com
Wed Jul 3 22:57:30 PDT 2013


2013/7/4 JS <js.mdnq at gmail.com>

> I'm trying to write a mixin that will solve the problem but since I can't
> seem to build up strings progressively it's a huge pain in the ass.
>

How about this?
Unfortunately this code doesn't work with git head, because it requires
both one small std.typecons.wrap bug fix and its one small improvement. But
I'll make a PR to fix them soon.

// -------------
// core side

import std.typecons : Proxy;
import std.typecons : wrap, unwrap;
import std.typecons : WhiteHole, NotImplementedError;
import std.exception : enforce;

public interface Interface
{
    int foo();
    int bar();
}

private class Pluggable
{
    Interface impl;
    mixin Proxy!impl;

    static Interface defaultImpl;
    static this() { defaultImpl = new WhiteHole!Interface(); }

    this() { impl = defaultImpl; }

    int foo() { return 1; }     // pre-defined default behavior
}

public Interface createPluggable()
{
    return new Pluggable().wrap!Interface;
}
public Interface setPlugin(Interface i, Interface plugin)
{
    Pluggable p = enforce(i.unwrap!Pluggable);
    p.impl = plugin ? plugin : Pluggable.defaultImpl;
    return i;
}

// -------------
// user side

class Plugin : Interface
{
    override int foo() { return 10; }
    override int bar() { return 20; }
}

void main()
{
    import std.exception : assertThrown;

    Interface i = createPluggable();

    assert(i.foo() == 1);
    assertThrown!NotImplementedError(i.bar());

    i.setPlugin(new Plugin());  // set plug-in

    assert(i.foo() == 1);
    assert(i.bar() == 20);

    i.setPlugin(null);          // remove plug-in

    assert(i.foo() == 1);
    assertThrown!NotImplementedError(i.bar());
}

Kenji Hara
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20130704/6e4564cd/attachment.html>


More information about the Digitalmars-d mailing list