2009-10-31 7 views
6
のような機能を配置する場所を

必ず決して:私はきちんと別のクラスに適合しない機能のためのリポジトリとして機能し、アプリケーションごとにToolboxクラスを作成キャッチオールAppToolboxクラスを作成する - これは悪い習慣ですか?

String PrettyPhone(String phoneNumber) // return formatted (999) 999-9999 
String EscapeInput(String inputString) // gets rid of SQL-escapes like ' 

。私はそのようなクラスは悪いプログラミング練習、特に悪いオブジェクト指向設計であることを読んだ。しかし、これらの文献は、個々のデザイナーやデベロッパーの意見が、より多くの意見を共有しているように思えます。だから私の質問は、キャッチオールツールボックスは、デザインパターンが悪いですか?もしそうなら、なぜ、どのような選択肢がありますか?

答えて

6

大きな質問です。私はいつも、十分に複雑なプロジェクトには「ユーティリティ」クラスが必要であることがわかります。これは、オブジェクト指向プログラミングの本質は、常に実現可能であるとは限らない場合(例えば、哺乳類のオブジェクトモデルを作成してから、カモノハシを絞って)。これは、動機づける問題がaspect oriented programming(c.f. cross cutting concern)になります。多くの場合、ユーティリティクラスにはクロスカッティングの問題があります。

ツールボックスまたはユーティリティクラスを使用する代わりに、拡張メソッドを使用してプリミティブ型に必要な機能を追加することもできます。しかし、陪審員はそれが優れたソフトウェア設計を構成しているかどうかはまだ分かりません。

私の最後の言葉は次のとおりです。必要に応じて、より良いデザインを短くカットしていないことを確認してください。もちろん、後で必要に応じてリファクタリングすることもできます。

1

これは問題ありません。 1つは論理的な部分に分解しようとすることです。こうすることで、インテリセンスをきれいに保つことができます。

MyCore.Extensions.Formatting.People 
MyCore.Extensions.Formatting.Xml 
MyCore.Extensions.Formatting.Html 
0

私は、「ツールボックス」を育てることができますし、資源のトンにあなたが単一の関数を呼び出すするたびにロードされますので、それは眉をひそめるだ理由があると思います。

実際のクラスのオブジェクトに適用するメソッドを持つ方がよりエレガントです。ちょっと理にかなっています。

私は個人的には問題ではないと思っていますが、上記の理由から単純に回避しています。

2

これらの例では、私は、文字列拡張する傾向になります:あなたは、これらの機能を必要とするすべての場所を書き留めた場合は、あなたが実際にそれを使用するかを把握し、適切なクラスに追加することができ

class PhoneNumber extends String 
{ 
    public override string ToString() 
    { 
     // return (999) 999-9999 
    } 
} 

。それは時には難しいことですが、まだあなたが目指すべきものです。

EDIT:以下で指摘したように

、あなたがC#で文字列を上書きすることはできません。私が作るしようとしていた点は、関数が所属する場所なので、この操作は、電話番号の上に作られていることである。

interface PhoneNumber 
{ 
    string Formatted(); 
} 

あなたが異なるフォーマットを持っている場合は、if文を使用して、コードをポイ捨てせずのPhoneNumberの実装を入れ替えることができます、例えば、

の代わりに:

あなただけ使用することができます
if(country == Countries.UK) output = Toolbox.PhoneNumberUK(phoneNumber); 
else ph = Toolbox.PhoneNumberUS(phoneNumber); 

output = phoneNumber.Formatted(); 
+0

質問は、JavaではなくC#についてです。とにかくStringクラスは.NETとJavaの両方で封印されています( –

2

私は、静的なヘルパークラスが心に来る最初の事だと思います。それはオブジェクト指向設計の一部としてそれを参照する場合もあります。しかし、ヘルパークラスの最大の問題は、大きなダンプになる傾向があることです。私はこれが私が関与していた大規模なプロジェクトのいくつかで起こるのを見たと思います。あなたはクラスに取り組んでいます。あなたの援助者は、彼らがしていることをうまく伝えていません。クラス名に 'helper'または 'util'という名前は何も意味しません。 OOのほとんどの指導者は、あなたが十分な考えを持っていれば、それをもっと分かりやすいクラスに簡単に置き換えることができるので、ヘルパーを擁護していると思います。私はヘルパーが単一責任の原則に違反していると信じているので、私はこのアプローチに同意する傾向があります。正直なところ、塩の穀物でこれを取る。私はOOPで少し意見しています:)

+0

)。共通のライブラリに特定のヘルパーを作成する傾向があります。したがって、IOヘルパー関数と文字列ヘルパーの両方を含む汎用ヘルパークラスは表示されません。しかし、私は持っている:IoHelper、StringHelper、など。それが私の「懸念の分離」を得る方法です。 ;-) –

1

私の経験では、そのユーティリティ機能はめったに孤立して発生していません。電話番号をフォーマットする方法が必要な場合は、電話番号の検証と電話番号の解析も必要です。 YAGNIの原則に従えば、実際にそれらが必要になるまでそのようなことを書こうとは思わないでしょうが、そのような機能を個々のクラスに分けると便利です。シングルメソッドからマイナーサブシステムへのこれらのクラスの成長は、時間が経つにつれて自然に起こります。私はこれを、コードを長期にわたって組織的、理解可能、および維持可能な状態に保つ最も簡単な方法であることを発見しました。

1

私はアプリケーションを作成するときに、静的メソッドとプロパティを含む静的クラスを作成します。静的メソッドとプロパティは、どこに配置するかわかりません。

それは特に良いデザインではありませんが、それはポイントの一種です。それは私がまだ考え出していない設計決定の全クラスをローカライズする場所を与えてくれます。一般に、アプリケーションが成長し、リファクタリングによって洗練されるにつれて、これらのメソッドとプロパティが実際に存在する必要がある場所が明確になります。忠実に、リファクタリングツールの状態は、これらの変更が通常は例外的に苦痛を伴うことではありません。

私は他の方法でやってみましたが、他の方法は、オブジェクトモデルを適切に設計するための十分な知識を得る前に基本的にオブジェクトモデルを実装することです。私がとすると、私はかなりの時間とエネルギーを費やして、いつか再考して、ある時点で再構築しなければならない平凡な解決策を思いつきます。さて、私がこのコードをリファクタリングすることを知っていれば、本当にうまくいかない不必要に複雑なクラスを設計して構築する手順をスキップするのはどうですか?

たとえば、複数の顧客が使用しているアプリケーションを作成しました。私はかなり早い段階で、異なる顧客のために違う方法で作業する必要がある方法を分離する必要があることを理解しました。カスタマイズされたメソッドを呼び出す必要があったプログラムのどこかで呼び出し可能なstaticユーティリティメソッドを構築し、静的クラスにスタックしました。

これは数か月間うまく機能しました。しかし、それはちょうど醜く見えるようになった時点になった。そして私はそれを自分のクラスにリファクタリングすることに決めました。そして、このメソッドが呼び出された場所をすべて見てコードを調べると、カスタマイズされたメソッドはすべて抽象クラスのメンバーになる必要があり、顧客のアセンブリは単一の派生クラスすべての抽象メソッドを実装し、アセンブリと名前空間の名前を設定から取得し、起動時にカスタムフィーチャクラスのインスタンスを作成するだけで済みました。カスタマイズしなければならないすべてのメソッドを見つけることは本当に簡単でした。なぜなら、私がする必要があったのは、私のロード・カスタム・フィーチャーメソッドが呼び出されていたすべての場所を見つけることだったからです。午後には、コードベース全体を理解し、この設計を合理化するために、より良い部分がありました。最終結果は、本当に柔軟で堅牢で、正しい問題を解決します。

私が最初にその方法を実装したとき(実際には3つまたは4つの相互関連する方法でした)、それは正しい答えではないと認識しました。しかし、正解が何であるかを決めるのに十分なことは分かりませんでした。だから私は正しい答えが明らかになるまで、最も単純な間違った答えを出しました。

0

私はコメントを投稿しましたが、もう少し詳しく説明したいと思いました。

私は、[組織]。[製品] .Commonをルートとして使用し、サブネーム空間をヘルパーとする共通ライブラリを作成します。

ここでは、クラスを作成したり、そこに配置する場所がわからないものを押したりするようなことについて、ここにはごく少数の人が言います。違う。ヘルパーメソッドが必要な場合でも、それは何かに関連しているので、適切な名前のヘルパークラス(IoHelper、StringHelperなど)を作成してヘルパーの名前空間に配置します。そうすれば、構造が得られ、何らかの懸念が生じます。

ルートネームスペースでは、必要な状態(存在する!)のインスタンスユーティリティクラスを使用できます。また、言うまでもなく、適切なクラス名を使用することもできますが、ヘルパーの接尾辞は使用しないでください。

関連する問題