13
13

More than 5 years have passed since last update.

Dartで「TypeScriptでメソッドチェーンを書くとき、戻り値の型に気をつけないと継承でハマる」を解決してみた

Last updated at Posted at 2014-07-15

mzsmさんの「TypeScriptでメソッドチェーンを書くとき、戻り値の型に気をつけないと継承でハマる」という記事が面白かったので、Dartならどう書けるかという対抗記事(謎)を書きます。

基底クラス

クラス名は BaseCalcとします。足し算と引き算だけ実装します。

calc.dart
class BaseCalc {
  num number;

  BaseCalc(this.number);

  void plus(num n) {
    this.number += n;
  }

  void minus(num n) {
    this.number -= n;
  }

  num showResult() => this.number;
}

void main() {
  var c = new BaseCalc(10)
    ..plus(15)
    ..minus(5)
    ..plus(10);
  print(c.showResult());
  // 30
}

継承して拡張

BaseCalcを継承して掛け算とわり算も実装したNewCalcを定義します。

calc.dart
class BaseCalc {
  num number;

  BaseCalc(this.number);

  void plus(num n) {
    this.number += n;
  }

  void minus(num n) {
    this.number -= n;
  }

  num showResult() => this.number;
}

class NewCalc extends BaseCalc {

  NewCalc(num initial) : super(initial);

  void multiply(num n) {
    this.number *= n;
  }

  void divide(num n) {
    this.number /= n;
  }
}

void main() {
  var c = new NewCalc(10)
    ..plus(15)
    ..minus(5)
    ..multiply(10)
    ..divide(4)
    ..minus(10);
  print(c.showResult());
  // 40.0
}

このように、Dartであれば型パラメータやdynamic(TypeScriptのanyと同じ)を使わずに解決できました。

メソッドカスケーディングについて

Dartの特徴的な文法「メソッドカスケーディング」は、ドット2つの..でメンバにアクセスすることで、戻り値を強制的に呼び出し元のインスタンスで上書きできる機能です。この機能はBertrand Meyer氏の主張である 「コマンド・クエリ分離原則」 の『コマンド(副作用のあるメソッド)は値を返さない』『クエリは副作用を持たず値だけを返す』というルールを守りつつ、メソッドチェーンによる書きやすさを実現しています。

「コマンド・クエリ分離原則」については以下の記事でわかり易く説明されています。
http://d.hatena.ne.jp/m-hiyama/20101216/1292469108
http://kokudori.hatenablog.com/entry/20130206/1360170983

このメソッドカスケーディング機能、めちゃんこ便利なんですがなかなかサンプルコード等に出てきません(そもそも日本語のDart記事が少ない問題があり)。もっと知名度上げていきましょう!メソッドカスケーディング!

13
13
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13