インターフェイスとabstract class / インターフェイスとジェネリック


インターフェイス多態性 (WWWの生成)

// WWwの生成
public interface IRequest {
  UnityEngine.WWW create();
}

// リクエストに必要なデータを追加
public abstract class Request : IRequest {
  public abstract UnityEngine.WWW create();

  protected readonly Dicitionary<string, string> param;
  protected readonly string url;

  public Request(string _url, Dictionary<string, string> param) {
    url = _url;
    param = _param;
  }
}

// Getリクエスト
public class GetRequest: Request {
  public GetRequest(string url, Dictionary<string, string> param): base(url, param) { }

  public override UnityEngine.WWW create() {
    var _url = paramToUrl(url, param);
    return new WWW(_url);
  }

  private string paramToUrl(string url, Dictionary<string, string> param) {
    if (param == null || param.Keys.Count == 0) { return url; }
    
    var firstKey = param.Keys.First();
    var first = string.Format("?{0}={1}", firstKey, param[firstKey]);
    var ary = param.Keys.Skip(1).Select(key => string.Format("&{0}={1}", key, param[key])).ToArray();
    var paramStr = first + string.Join("", ary);

    return url + paramStr;
  }
}

// Postリクエスト
public class PostRequest: Request {
  public PostRequest(string url, Dictionary<string, string> param): base(url, param) { }

  public override UnityEngine.WWW create() {
    var form = paramToForm(param);
    return new WWW(url, form);
  }

  private WWWForm paramToForm(Dicitionary<string, string> param) {
    if (param == null || param.Keys.Count == 0) { return null; }

    var form = new WWWForm();
    foreach (var key in param.Keys) {
      form.AddField(key, param[key]);
    }

    return form;
  }
}



インターフェイスを利用しながらも継承先のデータも取得したい場合にGeneric型<T>を使用

// jsonからmodelデータへの変換
public interface IModel {
  void fromJson(Dictionary<string, object> json);
}

// モデルデータの生成
public class ModelFactory<T> where T: IModel, new() {
  public static T create(Dictionary<string, object> json) {
    var model = new T();
    model.fromJson(json);
    return model;
  }
}
class TestModel : IModel {
  public string ip;
  public string state;
  public string request;
  public string response;

  public void fromJson(Dictionary<string, object> json) {
    ip = json["ip"].ToString();
    state = json["state"].ToString();
    request = json["request"].ToString();
    response = json["response"].ToString();
  }
}

class TestScene : MonoBehaviour {
  TestModel model;

  void Start() {

    // 本来は通信で持ってくる
    var json = new Dictionary<string, object> {
      {"ip": "192.168.1.1"},
      {"state": "200"},
      {"request": "post"},
      {"response": "0"},
    };

    model = ModelFactory<TestModel>.create(json);
  }
}