web-dev-qa-db-ja.com

未知の未来のためにコードを追加した場合、私はオーバーエンジニアリングですか?

このコードを見てください:

Console.WriteLine(user.name);
Console.WriteLine("**********"); // 10 stars
//...

明日は、10スターではなく20スターを使用する必要がありました。さて、私はそれを変更します:

Console.WriteLine(user.name);
Console.WriteLine("********************"); // 20 stars
//...

それは私にこの仕事のためのメソッドを書くアイデアを与えます:

public void DisplayStars()
{
   Console.WriteLine("********************");
}

Console.WriteLine(user.name);
DisplayStars();
//remaining code

しかし、私がコードを書いているとき、私は自分自身で考えます:int countのような文字の繰り返し数を取得するための新しいパラメーターを追加することは、より良い解決策ではありませんか? char whichCharのような繰り返し文字を取得するために別のパラメーターを追加してみませんか?

public void DisplayStars(int count, char whichChar)
{
   string s=new String(whichChar, count);
   Console.WriteLine(s);
}

なぜintuintの方が良いようです。いいえ、いいえ、byteが最適です。ユーザーが空の文字を渡した場合はどうなりますか。カウントに対して大きすぎる(または小さな)数を渡した場合はどうなりますか?そして、これらは続く...

将来必要になると思うので、コードを追加することがよくあります。これらは、私の日常的なプログラミングの課題です。私はオーバーエンジニアリングですか?私は完全主義ですか?そうでない場合、オーバーエンジニアリングとは何ですか?

4
kokabi

"/\/\/\/\"が必要な場合はどうなりますか?これは単一の文字ではなく、2つの文字の組み合わせです。

"◀◼◼◼◼▶"はどうですか?大野!別の開始文字と終了文字も許可する必要があります。

クライアントが広告スペースとして販売したい場合はどうなりますか? OK、それはリスクが高いため、一歩戻りましょう。


はい、あなたは過剰設計です。まず第一に、私はこれらの変更が実際に維持することを困難にしていると主張します。

"**********"をそのまま使用すると、簡単に変更できます。新しい要件が到着した瞬間に、文字列を置き換えることができます。

複数の場所に"**********"がある場合、それを定数にするか、それを抽出すると、メソッドに意味があると私は主張します。 単一の信頼できる情報源 ※です。これらの文字列がすべて変化すると信じる理由がある場合は、それを行ってください。どうして? Bacauseを使用すると、一度にすべてを簡単に変更できるので、1つ忘れたりする心配はありません。

※:代わりに 自分を繰り返さないでください を呼び出す人もいます。しかし、定数を使用するか、メソッドを呼び出すことによって、自分自身を繰り返していると言えます...見て、DRYは、真実の単一のソースに到達するのに役立つツールです。それは手段であり、目標ではありません。極端に取らないでください。

ただし、それを超えて、クライアントが何を望むかについて議論します。あなたは知らない。起こりうる将来の変更を容易にするために行うすべての変更は、実際には他の変更を行うのを難しくします...そして、変更が何であるかわからないので、作業を取り消す必要がある状況に備えている可能性があります新しい要件を実際に満たすため。


承知しました。変更の可能性については議論があるかもしれません。確かに、"**********"から"----------"への変更は、広告スペースとして販売するよりも理にかなっています。その考えについて私が言うことは2つあります...

  • 機会費用があります。他の現在実際の要件を実装する際に、これらの仮想的な将来の要件を実装するために使用している時間を使用している可能性があります。
  • あなたは乱暴に投機をするべきではありません。実際の要件が完了したら、クライアントに製品が気に入ったかどうか、変更を希望するかどうかを尋ねます。

関数型プログラミングから学びましょう...

あなたはこれを取ることができます:

public void DisplayStars(int count, char whichChar)
{
   string s=new String(whichChar, count);
   Console.WriteLine(s);
}

そして、それを次のシグネチャを持つメソッドに変換します。

public void DisplayStars()

Addendum:実際、その依存関係をConsoleに抽出すると、古き良き純粋関数として機能するメソッドが得られます(外部システムから値を取得していません)、次の署名が付いています:

public static string DisplayStars()

これはvoidを単一の文字列にマップする関数と同等であると主張します。そして、いいえ、voidを教えないでください。つまり、ユニットは存在しません。

パラメータの値を設定する。

その後、その日が来て、あなたがしたすべてが間違っていることが判明した場合、呼び出しをDisplayStarsに変更するだけです。

そうです、これにはすべて色分けがあります。何かを破壊しやすくすることです。


そして、ええ、ええ、YAGNI。

9
Theraot

はい、あなたはこれを過度に設計しています。今日必要なもの、あるいはせいぜい知っている近い将来必要になるものを構築します。そうでなければ、あなたが発見したように、あなたは自分の時間を費やして、決して使用しない抽象化を構築します。

または短いバージョン:あなたはそれを必要としない(YAGNI).

4
Philip Kendall