はじめに
仕事でどうやって実装すればいい?と相談いただいたので、概要と解決策を紹介します。
紹介コードはC#を用いていますが、説明自体は言語に依存しないようにしました。
問題
下記をどう実装するのがよい??
- 実装対象が複数、共通部分とそれぞれ個別部分が存在
- 将来的に、対象が増える可能性あり
- 実装対象をいくつか同時に操作したい
問題例
- 実装対象 エクレア、シュークリーム、今後カスタードロールも作る
- それぞれ作って食べる
- 作り方、食べ方は個別に実装
- まとめて食べたい
解決策
共通部分:interface
// foodでもいいが、ここではあえてお菓子とした。
// お菓子以外を実装する時に改名するか、別のinterfaceを作るか検討する方針。
interface ISweets
{
void create();
void eat();
}
個別部分:interfaceを継承したクラス
class ecrea : ISweets
{
void create()
{
// エクレアの作成工程
}
void eat()
{
// エクレアの食べ方
}
}
class creamPuff : ISweets
{
void create()
{
// シュークリームの作成工程
}
void eat()
{
// シュークリームの食べ方
}
}
まとめて食べる
void eatAll(ISweets[] sweets)
{
foreach (var sweet in sweets)
{
sweet.eat();
}
}
備考
- interfaceじゃなくて基底クラスじゃダメか?カスタードの共通化も楽になるのでは?
今後カスタードのお菓子のみなら、それでも良い
カスタード以外を使う場合などは、宣言と実装を分離した方が汎用性が高い
実装を含んだ継承は、意図しない継承、名前と乖離した継承Liskovの置換原則違反の時に解決が難しくなりやすい
そもそも違反するな、ですが
- 「カスタードを作る部分をまとめたい」のような、実装をまとめる話はまた別記事で紹介。
キーワード:strategyパターン
interface、どんどん使っていきましょう!