C#符号化単純性の汎用編(短いC#コードの作成方法、随時更新)
これは符号化単純性シリーズの1つであり、前のいくつかの編はコード編/関数編/意味編を含む.ケースを蓄積するため、随時更新します.
前に述べたように、符号化の簡単さの「ハート法」は、画面に2つのコードが似ているように見える限り、必ず統合する方法があるということです.似ているといえば、switch-caseの各セグメントコードほど似ているものはない.自分の製品の中で最も長い関数を細かく数えれば、中にはswitch-case、あるいはif-else ifがほとんど肯定されています(両者は実際に同じです).一般的に各セグメントのコードは同じように見えますが、少し違います.関数にもクラスにもなれません.どうすればいいですか.
臭いの長いswitch-caseを解決する最善の方法は、汎用(C++時代にテンプレートと呼ばれていた)である.汎用型は勉強しにくいが、重要だ.02年頃にプロセス改善員としてコード審査を行っていたが、pagedownの時に波状に起伏するコードを何気なく発見し、65個の関数が1個の関数(間違いなく65:1)に縮小できることを観察した.その内容は5種類のint定数で13種類の異なる変数を処理し、処理方法は完全に同じである.このコードは4000行あり、すでに1ヶ月かかり、プログラミング者の月給は7000元(それは10年前、7000元で5平方メートルの小財産権住宅、または2平方メートルの大財産権住宅を購入することができます).同日午後には1つの関数になり、長さは55行未満だった.このことから、毎年汎用型を活用できないことによる経済損失は、億元以上に達する可能性があると推定されている.
ケース1 2011-05-27単純汎用クラス
次のコードは短くて、改造する価値がないように見えますが、実はDisplayのほかにも多くの関数があります.その中のいくつかのcase体は長いし、いろいろなtypeが後を絶たないので、改造せざるを得ません.
Displayの目的は、様々なudcたちにValueの数値を独自の方法で表示させることです.
この関数を分解するには、宣言が必要です.
次に、このインタフェースをクラス(このクラスは一般的に存在します)に継承し、メソッドを実装します.
また、表示方式も@Html.Display(udc)が@udcになります.Display.
このコード全体の修正後、元の5つのswitch-caseは1つしか残っていません.コードは明らかに集約されています.つまり、1つのタイプを増やすたびに、基本的には1つの場所(partial class)内で修正を完了するだけでいいです.修正の結果はコンパイル時に十分で正しいかどうかを確認できます(switch-caseでは1つのタイプが漏れており、実行時にcaseが見つからない場合にのみわかります).ケース2 2011-05-29汎用関数
この汎用関数は、クラステーブルからレコードを取り出し、ない場合は作成します.作成時にnewの新しいレコードが必要であり、tableによってデフォルト値が異なるフィールドもあります.従来の方法では多くの関数を記述する必要があり、新しいテーブルが現れるたびに、新しい関数を記述する必要があります.本稿で最初に述べた65の関数は,そのために生成されたものである.
このような状況を処理する心法は,タイプの違いで似ているように見えるコードが関数に結合できないことが分かった場合,汎用型を用いるべきである.
この場合,汎用型ではnew()とIxxx(あるInterface)の2つの主要技術を習得する必要がある.newの目的はTを作成できるようにすること(関数で作成しなければ不要)であり,Interfaceの目的はコンパイル時刻が将来の新しいタイプが依然としてこの関数を使用できることを保証することである(C++の時代は新しいタイプを使用する場合にのみ確認できる).
ここでは、汎用的な応用思想についてのみ説明します.汎用的な応用技術については、MSDNで参考になる良い文章があります.http://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx.この文章はC#汎型の発展過程全体を最初から最後まで話した.
前に述べたように、符号化の簡単さの「ハート法」は、画面に2つのコードが似ているように見える限り、必ず統合する方法があるということです.似ているといえば、switch-caseの各セグメントコードほど似ているものはない.自分の製品の中で最も長い関数を細かく数えれば、中にはswitch-case、あるいはif-else ifがほとんど肯定されています(両者は実際に同じです).一般的に各セグメントのコードは同じように見えますが、少し違います.関数にもクラスにもなれません.どうすればいいですか.
臭いの長いswitch-caseを解決する最善の方法は、汎用(C++時代にテンプレートと呼ばれていた)である.汎用型は勉強しにくいが、重要だ.02年頃にプロセス改善員としてコード審査を行っていたが、pagedownの時に波状に起伏するコードを何気なく発見し、65個の関数が1個の関数(間違いなく65:1)に縮小できることを観察した.その内容は5種類のint定数で13種類の異なる変数を処理し、処理方法は完全に同じである.このコードは4000行あり、すでに1ヶ月かかり、プログラミング者の月給は7000元(それは10年前、7000元で5平方メートルの小財産権住宅、または2平方メートルの大財産権住宅を購入することができます).同日午後には1つの関数になり、長さは55行未満だった.このことから、毎年汎用型を活用できないことによる経済損失は、億元以上に達する可能性があると推定されている.
ケース1 2011-05-27単純汎用クラス
次のコードは短くて、改造する価値がないように見えますが、実はDisplayのほかにも多くの関数があります.その中のいくつかのcase体は長いし、いろいろなtypeが後を絶たないので、改造せざるを得ません.
Displayの目的は、様々なudcたちにValueの数値を独自の方法で表示させることです.
-
- [csharp] view plaincopy
- 01.
- 02.public static MvcHtmlString Display(this HtmlHelper htmlHelper, UDC udc)
- 03. {
- 04. switch (udc.Type)
- 05. {
- 06. case "Text100":
- 07. return new MvcHtmlString((udc.Value != null) ? udc.Value.ToString() : "NULL");
- 08. case "Text20":
- 09. return new MvcHtmlString((udc.Value != null) ? udc.Value.ToString() : "NULL");
- 10. case "Date":
- 11. return new MvcHtmlString(((DateTime)udc.Value).ToShortDateString());
- 12. default: return new MvcHtmlString(string.Format("Unknown UDC type: {0}", udc.Type));
- 13. }
- 14. }
この関数を分解するには、宣言が必要です.
-
- [csharp] view plaincopy
- 01.
- 02.public interface IUDC
- 03. {
- 04. ……
- 05.
- 06. MvcHtmlString Display { get; }
- 07. ……
- 08.
- 09. }
次に、このインタフェースをクラス(このクラスは一般的に存在します)に継承し、メソッドを実装します.
-
- [csharp] view plaincopy
- 01.
- 02.public partial class UDCText100 : IUDC
- 03. {
- 04. ……
- 05.
- 06. public MvcHtmlString Display { get { return new MvcHtmlString((Value != null) ? Value.ToString() : "NULL"); } }
- 07. ……
- 08.
- 09. }
また、表示方式も@Html.Display(udc)が@udcになります.Display.
このコード全体の修正後、元の5つのswitch-caseは1つしか残っていません.コードは明らかに集約されています.つまり、1つのタイプを増やすたびに、基本的には1つの場所(partial class)内で修正を完了するだけでいいです.修正の結果はコンパイル時に十分で正しいかどうかを確認できます(switch-caseでは1つのタイプが漏れており、実行時にcaseが見つからない場合にのみわかります).ケース2 2011-05-29汎用関数
-
- [csharp] view plaincopy
- 01.
- 02.private IUDC GetOrDefaultUDC<T, V>(Table<T> table, ..., V defaultValue) where T : class, IUDC, new()
- 03. {
- 04. var t = table.SingleOrDefault(...);
- 05. if (t == null)
- 06. {
- 07. t = new T();
- 08. ...
- 09. t.OValue = defaultValue;
- 10. ...
- 11.
- 12. }
- 13. return t;
- 14. }
この汎用関数は、クラステーブルからレコードを取り出し、ない場合は作成します.作成時にnewの新しいレコードが必要であり、tableによってデフォルト値が異なるフィールドもあります.従来の方法では多くの関数を記述する必要があり、新しいテーブルが現れるたびに、新しい関数を記述する必要があります.本稿で最初に述べた65の関数は,そのために生成されたものである.
このような状況を処理する心法は,タイプの違いで似ているように見えるコードが関数に結合できないことが分かった場合,汎用型を用いるべきである.
この場合,汎用型ではnew()とIxxx(あるInterface)の2つの主要技術を習得する必要がある.newの目的はTを作成できるようにすること(関数で作成しなければ不要)であり,Interfaceの目的はコンパイル時刻が将来の新しいタイプが依然としてこの関数を使用できることを保証することである(C++の時代は新しいタイプを使用する場合にのみ確認できる).
ここでは、汎用的な応用思想についてのみ説明します.汎用的な応用技術については、MSDNで参考になる良い文章があります.http://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx.この文章はC#汎型の発展過程全体を最初から最後まで話した.