デザインパターンが速く書けるNemerleのマクロ

# 概要
Nemerle Macro Libraryにある，デザインパターンを実装するために作られたマクロを紹介します．筆者のNemerleのバージョンは 1.1 on VisualStudio 2015です．
***
[Design patterns ・ rsdn/nemerle Wiki](https://github.com/rsdn/nemerle/wiki/Design-patterns)の内容沿って作成しています．
一部，例を引用しているところがあります．これから紹介するマクロは[このソースコード](https://github.com/rsdn/nemerle/blob/master/macros/DesignPatterns.n)によって実装されているので，不明なことがあれば，実装を見れば良いでしょう．

# Abstract factoryパターン
.Netの標準ライブラリでこのデザインパターンを作ったものは見たことがありませんが， インスタンスの生成専用のクラスを用意して，整合性が必要な一連のクラスを近い場所に記述することによってコードのミスを減らすという狙いがあるデザインパターンです．詳しくは[この記事](http://qiita.com/toshi0607/items/b8a19a4328849cdf1d99)を読むとわかりやすいかもしれません．

```nemerle
class Factory 
{
  public virtual CreateWidget (name : string) : Widget {
    Widget (x)
  }
  public virtual CreateWorker (name : string, tasks : int) : Worker {
    Worker (name, tasks)
  }
}

class MyFactory : Factory 
{
  public override CreateWidget (name : string) : Widget {
    MyWidget (x)
  }
  public override CreateWorker (name : string, tasks : int) : Worker {
    MyWorker (name, tasks)
  }
}
```
これを，クラスにマクロをつけて簡単に書くことができます．

```nemerle
[Nemerle.DesignPatterns.AbstractFactory (Widget, Worker)]
class Factory {}

[Nemerle.DesignPatterns.AbstractFactory (Override (MyWidget, Widget), Override (MyWorker, Worker))]
class MyFactory : Factory {}
```

# Composite(Aggregate)パターン
ディレクトリ構造を例に考えてみるとわかりやすい[このデザインパターン](http://qiita.com/takehiro224/items/e8ebc98d4eff29d3805c)ですが，このようなコードを，

```nemerle
[Nemerle.DesignPatterns.Aggregate (ReadUtil, WriteUtil)]
class ReadWriteUtil { 
  public this (inp : string, outp : string) {
    _initReadUtil (inp);   
    _initWriteUtil (outp);   
  }

  Run () : void {
    this.WriteFile (this.ReadFile ());
  }
}
```
こんな感じに展開してくれるそうです．

```nemerle
/*
 ReadFile()というメソッドを持つReadUtilとWriteFile(string)というメソッドを持つWriteUtilというクラスが別にある．
*/
class ReadWriteUtil {
   _ReadUtil : ReadUtil;
   _WriteUtil : WriteUtil;
   
   public this (inp : string, outp : string) {
       _initReadUtil(inp);
       _initWriteUtil(outp);
   }
   public _initReadUtil (x : string) : void { this._ReadUtil = new ReadUtil(x); }
   public _initWriteUtil (x : string) : void { this._WriteUtil = new WriteUtil(x); }

   public ReadFile () : string { this._ReadUtil.ReadFile(); }
   public WriteFile (x : string) : void { this._WriteUtil.WriteFile(x); }
}
```

# Proxy パターン
生のオブジェクトのメソッドなどをラップするProxyクラス(代理人のクラス)を作るデザインパターンです．[Wikipedia](https://ja.wikipedia.org/wiki/Proxy_パターン)がわかりやすいかなと思います．以下に例を示します．

```nemerle
using System;
using System.Runtime.Remoting;

// "Subject"

public interface IMath
{
  // Methods
   Add( x :  double, y : double ) : double;
   Sub( x :  double, y : double ) : double;
   Mul( x :  double, y : double ) : double;
   Div( x :  double, y : double ) : double;
}

// "RealSubject"

class Math : MarshalByRefObject, IMath
{
  // Methods
  public Add(x : double, y : double ) : double { x + y; }
  public Sub(x : double, y : double ) : double { x - y; }
  public Mul(x : double, y : double ) : double { x * y; }
  public Div(x : double, y : double ) : double { x / y; }
}

// Remote "Proxy Object"
class MathProxy : IMath
{
  // the stubs implementing IMath by calling math.* are automatically generated
  // (that macro is not included in the standard library;
  // there is another proxy macro down the page)
  [DesignPatterns.Proxy (IMath)]
  math : Math;
  
  // Constructors
  public this()
  {
    // Create Math instance in a different AppDomain
    def ad = System.AppDomain.CreateDomain( "MathDomain",null, null );
    def o =
      ad.CreateInstance("Proxy_RealWorld", "Math", false,
                        System.Reflection.BindingFlags.CreateInstance, null, 
                        null, null,null,null );
    math = ( o.Unwrap() :> Math);
  }
}

public class ProxyApp
{
  public static Main() :  void
  {
    // Create math proxy
    def  p =  MathProxy();

    // Do the math
    Console.WriteLine( "4 + 2 = {0}", p.Add( 4.0, 2.0 ) );
    Console.WriteLine( "4 - 2 = {0}", p.Sub( 4.0, 2.0 ) );
    Console.WriteLine( "4 * 2 = {0}", p.Mul( 4.0, 2.0 ) );
    Console.WriteLine( "4 / 2 = {0}", p.Div( 4.0, 2.0 ) );
  }
}
```
個人的には，そんままラップしたりすることはないと思うので，あんまり使わないかなと思います．

# シングルトンデザインパターン
日本語の説明サイトが多いシングルトンデザインパターンです．使う人も結構多いと思います．Nemerleで普通に書くと以下のようになります．

```nemerle
using Nemerle.Collections;
using System;
using System.Console;

module Program
{
     Main() : void
    {
        def serv1 = Server.Instance;
        def serv2 = Server.Instance;
        serv1.AddMessage("Hoge");
        WriteLine(serv2.LatestMessage);
    }
}

class Server {
    private static _Instance : Server = Server();

    private mutable Messages : list[string] = [];
    protected this() {}
    
    public static Instance : Server {
        get {
            _Instance
        }
    } 
    
    public LatestMessage : string {
        get {
            Messages.Head;   
        }
    }
    public AddMessage(s : string) : void {
        Messages = s :: Messages;
    }
}
```

出力は同じインスタンスの`Server.Messages`を参照しているわけなので，`serv1`で追加された`"Hoge"`が出力されます．`DesignPatterns.Singleton`マクロを使うと少し短く書けます．

```nemerle
using Nemerle.Collections;
using System;
using System.Console;

module Program
{
     Main() : void
    {
        def serv1 = Server.Instance;
        def serv2 = Server.Instance;
        serv1.AddMessage("Hoge");
        WriteLine(serv2.LatestMessage);
    }
}

[Nemerle.DesignPatterns.Singleton()]
class Server {
    private mutable Messages : list[string] = [];
    
    protected this() {} // privateにした方がいいって警告が出る．
    
    public LatestMessage : string {
        get {
            Messages.Head;   
        }
    }
    
    public AddMessage(s : string) : void {
        Messages = s :: Messages;
    }
}
```
Githubドキュメントだと，`Instance`に当たるメンバの名前をマクロの引数で変えられるよと書いてありましたが，最新版では`Instance`という名前から変えられないようです．