共通物は決め切る覚悟を持つ
Article
#感想戦
#設計
私はチーム開発で実装を行う際に、スケルトン定義を実装の前に行うことが多く、他の人にもおすすめをよくする。
スケルトン定義とは詳細設計のようなもので、コード上に実際に実装する空のモジュールを定義していき、それらのモジュールの定義方法やモジュールの関係を明らかにする作業である。 これにより、実装者もレビュワーも主に設計にフォーカスしたレビューができるようになり、全体で共通認識を持つことができるようになる。
このスケルトン定義は非常に有効であり長らく(?)愛用しているが、失敗したことがある。
共通物は中途半端に決めてはいけない
とあるチーム開発のプロジェクトで、私はスケルトンを次のように定義していった(イメージ):
// あるページ
const XxxPage = () => {
return (
<article>
...
<section>
{/* TODO: 本番のカードを挿入する */}
<Card title="いい感じの機能" />
</section>
...
</article>
);
};
// 共通コンポーネント
const Card = ({
title,
// TODO: 画像が確定し次第埋めていく。sampleImage は不要になったら消す
image = sampleImage,
}) => {
return <div>{title}</div>;
};
この実装時には、各ページに配置するカードの画像がページによって決まっていたり未確定のために仮画像を配置する流れになっていた。 そのため、Card コンポーネントの image プロパティをオプショナルにし、Card コンポーネント内部で image プロパティがなければ仮画像をはめ込むようにした。
この時はこの方が実装者の手間も少なく、画像が決まっていったら挿入していき、最終的には仮画像をなくす流れとなり、スムーズと考えていた。
共通物が揺れ動く
しばらくして事件が起こった。
画像が全てのページで確定したので、image プロパティを必須にする必要が出てきた。気付けばこの Card コンポーネントは 10 を超えるページで使用されている。さらに、現在もそれらのページは開発中であり他の実装者が着手しているのである。 仮に予定通り Card コンポーネントの image プロパティを必須に変更して sampleImage を消そうとすると、依存している 10 を超えるページに少なからず影響がいってしまう。
最終的には、全作業者に共有をして削除を行い事なきを得たが、工数が想定よりかかってしまった。…精神的にもダメージはきた。
共通物の I/F は決め切る
ではどうすればよかったか。今回の例で言えば image プロパティを最初から必須にするべきだった。
// あるページ
const XxxPage = () => {
return (
<article>
...
<section>
{/* TODO: 本番のカードを挿入する */}
<Card image={sampleImage} title="いい感じの機能" />
</section>
...
</article>
);
};
// 共通コンポーネント
const Card = ({ title, image }) => {
return <div>{title}</div>;
};
スケルトンだからと思い、未確定な情報を安易に共通物で吸収してしまったが故に、いざその情報が確定すると I/F が揺れ、設計を不安定にしてしまった。
この経験により、共通物の I/F 決定の価値の高さを知り、よりスケルトン定義で決め切る覚悟を持とうと思った。