iPresenceでは複数種類のロボットを1つのモバイルアプリからzoom等と連携して遠隔操作するアプリを開発しています。
その際アプリ側では1つのエントリーポイントから設定されたロボットにコマンドを渡しつつ各ロボット固有の機能も動作させる必要があります。
そこで全てのロボットに共有の動作とロボット固有の機能の動作を切り分けつつシンプルに書くためにDartのmixin/withの機能を使用します。
mixinと継承の違い
抽象クラス(abstract)を継承するのとmixinクラスを使用する際の違いは以下になります
抽象クラスの継承
- すべてのメソッドをオーバーライドし実装する必要がある。
- 1つの子クラスに対して1つの親クラスしか渡せない
mixin
- 必ずしもメソッドをオーバーライドする必要はない
- 1つのクラスに対して複数mixinすることができる
- コンストラクタを定義できない
このようにそれぞれにメリット/デメリットがありますが、うまく使い分けることで効果を発揮します
実装
以下の様に共通する機能と固有の機能の切り分けに使うことができます。
// 共通機能を定義したmixinクラス
// ロボットを操作するメソッドを仮実装する
mixin RobotCtlRepository{
void robotControl(){
throw UnimplementedError();
}
}
mixin RobotSetUpRepository{
void setup(){
throw UnimplementedError();
}
void deleteSetting(){
throw UnimplementedError();
}
}
// RobotA の固有機能のクラス
// RobotCtlRepository をmixinすることで robotControlメソッドも内包される
abstract class RobotARepository with RobotCtlRepository{
Future<void> robotAFunc();
}
// 同じようにRobotB,Cもそれぞれ専用の抽象クラスを定義してmixinさせる
// mixinをするので複数のクラスRobotCtlRepositoryとRobotSetUpRepositoryをもたせることもできる
abstract class RobotBRepository with RobotCtlRepository, RobotSetUpRepository{
String robotBFunc();
}
abstract class RobotCRepository with RobotCtlRepository, RobotSetUpRepository{
void robotCFunc();
}
このように抽象クラスに対してmixinすることで共有の機能をもたせることができるようになります。
またこれに対する実装は以下のようになります。
// メソッドの実装
class RobotARepositoryImpl extends RobotARepository{
@override
Future<void> robotAFunc() async{
await robot_a_function;
}
@override
void robotControl(){
robotA.move();
}
}
class RobotBRepositoryImpl extends RobotARepository{
@override
String robotBFunc(){
return "robotB";
}
@override
void robotControl(){
robotB.pan();
}
@override
void setup(){
robotB.setup();
}
@override
void setup(){
robotB.deleteSetting();
}
}
class RobotCRepositoryImpl extends RobotARepository{
@override
void robotCFunc(){
robot_c_function;
}
@override
void robotControl(){
robotC.tilt();
}
@override
void setup(){
robotC.setup();
}
// mixinなのでdeleteSettingはオーバーライドしなくてもいい
}
終わりに
mixinと継承を組み合わせ、使い分けることで柔軟で拡張性のある実装ができるようになります。
どのように切り分けるかなどは規模や設計・開発方針にもよってくるので適宜使っていくのがいいと思います。