2009-03-10 15 views
5

幾何学的図形を作成するためのAPIを書いていますが、私のメソッドの命名にはいくつかの困難があります。メソッドのワーキングネームのアドバイスが必要

簡単な例を考えてみましょう:円を作成する。私たちのほとんどは、graphics.drawEllipse(x, y, w, h)のような方法に精通しているかもしれません。円を描くには、左上の座標、円の幅と高さを知る必要があります。

私のAPIは、円では簡単ですが他の図形ではもっと複雑な数学を使わずに、様々な情報を使用して簡単に図形を描くことを目的としています。たとえば、中心座標と半径、または左上と右下の座標を指定して円を描画することもできます。

だから私のようなファクトリメソッドでCircleクラスを持っている:

Circle.createWithCenterAndRadius(cx, cy, r) 
Circle.createWithBoundingBox(x1, y1, x2, y2) 
Circle.createWithWidthAndHeight(x, y, w, h) 

私はここで、「コードのにおい」があるかもしれないように感じるが、私はよく分かりません。一方では、これらのファクトリメソッドは必然的に説明的です。一方、私はこれらのメソッド名が制御不能になるのを待つことができます。たとえば、ポイント、1つの辺の長さ、角度、別の辺の長さを指定して三角形を作成するTriangleファクトリメソッドの名前を付ける方法はありますか? Triangle.createWithPointSideAngleAndSide(x, y, side1, angle, side2)?それはちょうど悪いですか?

このAPIを使用する場合、このようなメソッド名は大丈夫ですか?メソッド名をもっとうまくいかにすることができるかアドバイスしていますか?

+0

あなたはどうしましたか? – eglasius

+0

私はJasonの投稿のように、「from」という名前のメソッドを変更しています。私は、kevchadderの投稿に対するJoe_Mのコメントごとに、不必要な部分を削除しています。あなたの流暢なインターフェイスの考え方を考えました。私はJavaを使用しているので、名前付きパラメータはありません。私はSlimのアイデアが好きで、それが実現可能かどうかを見ています。 –

+0

そして、APIの草案を完成させると、私はすぐにやるはずです。 –

答えて

0

はい、これはメタ答えのほうが多いですが、名前付けの方法については、Apple's Cocoaでご覧ください。

11

名前付きパラメータをサポートしていない言語でも問題ありません。言語が名前付きパラメータをサポートしている場合、私は短いCreateを気に入っており、明らかなパラメータ名を持っています。名前のパラメータを持つ言語については

は、あなたが希望:

Circle.Create(
    centerX = cx, 
    centerY = cy, 
    radius = r 
); 

別のより複雑なオプション、のような流れるようなインターフェイスになります(それはおそらく多すぎる):

circleBuilder.Center(cx,cy).Radius(r) 
circleBuilder.Center(x,y).Width(w).Height(y) 
circleBuilder.BoundWith().Left(x1,y1).Right(x2,y2) 

センターに戻りますRadiusまたはWidthのみを許可する中間クラスのインスタンスです。そしてBoundWithはLeftだけを許可するものを返します。

+0

これは非常に多くのコードを作成することです。私は、コードを作成してそれを汎用化しようとすると、長方形や三角形を作成するときに多くの時間を費やすことになると思います。 – jmucchiello

+0

@Joe、それを "それはあまりにも多すぎるかもしれない"から "それはおそらくあまりにも多すぎる"から更新しました。 – eglasius

14

あなたがサポートしていない言語では...それはあなたが簡潔な方法の一種で、その異なる表現から円を作成していることを意味し

Circle.FromCenterAndRadius(...) 
Circle.FromBoundingBox(...) 
Circle.FromWidthAndHeight(...) 

+0

+1私は改善が好きです。 – eglasius

1

をサークルの方法を変更する場合がありますメソッド名を何か非常に単純なものにしてCircle.createのように単純なものにして、入力値の解釈方法を示す追加の入力フラグ文字列( "center"や "bounding"のようなもの)入力のみに基づいて差別することが困難なケースv可愛い数字とタイプ?これの欠点は、異なるタイプの入力引数を処理するためにメソッドの内部に余分なロジックが必要であり、またフラグオプションを覚えておく必要があることです。

1

私はCreateTriangleメソッドを持ち、オーバーロードに必要な情報を表示します。

など。

Circle.CreateCircle(cx, cy, r) 
Circle.CreateCircle(point1, point2) 
Circle.CreateCircle(point, width, height) 
+0

+1:同意します。これが私のやり方でもあります...オーバーロードされたパラメータを自分自身で話してみましょう。 – Cerebrus

+0

ここでは、同じパラメータを持つ2つのメソッドがあります(すべてのパラメータが整数型の場合)。 – slim

+0

あなたは正しいですが、区別するために2つのintよりもむしろPointクラスを使うほうが良いでしょう。 – cjk

8

あなたの記述方法には何も問題はないと思います。コンパクトで、何が起こっているのか正確に説明しています。ライブラリのユーザーは、あなたのメソッドの機能に疑いがなく、maintananceプログラマーでもないでしょう。

プロパティクラスを持つファクトリメソッドを持つなど、多数のファクトリメソッドが公開されることが本当に心配な場合は、ここでいくつかのデザインパターンを適用することもできます。 CenterX、CenterY、Radius、(bool)UseCenterX、(bool)UseCenterYなどのプロパティを持つCirclePropertiesクラスを作成し、これをpublic factoryメソッドに渡すと、使用する(private)ファクトリメソッドがわかります。

のC#と仮定すると:

var circleProperties = new CircleProperties() 
{ 
    CenterX = 10, 
    CenterY = -5, 
    Radius = 8, 
    UseCenterX = true, 
    UseCenterY = true, 
    UseCenterRadius = true 
}; 

var circle = Circle.Create(circleProperties); 
+0

本当に "UseX"プロパティが必要ですか?どのプロパティが設定されているかを単にチェックすることはできませんでしたか?または、他のプロパティのセッターで設定します(たとえば、setCenterX()はUseCenterXを設定します)? – TMN

+0

TMN:でも、実際にあなたのマジックナンバーを正確に選ぶ必要があります...明らかに、0.0は完全に有効な座標です。これらのブール値を適切なセッターで自動的に設定することは良い考えです。 –

6

私の最初の本能は、より直感的なメソッドのオーバーロードを可能にするより多くの種類を、持っていることです。

// instead of Circle.createWithCenterAndRadius(cx, cy, r) 
Circle.create(new Point(cx,xy), r); 

// instead of Circle.createWithBoundingBox(x1, y1, x2, y2) 
Circle.create(new Point(x1,y1), new Point(x1,y1)); 
// or even... 
Circle.create(new Box(p1,p2)); 

// instead of Circle.createWithWidthAndHeight(x, y, w, h) 
Circle.create(new Point(x,y), w, h); 

と同様にポイントこのスタイルがあなたに合っている場合、あなたが代わりにコンストラクタのファクトリメソッドを必要とする理由を検討し、(異なる単位を可能にする)の距離

を定義することができます。

Circle c = new Circle(new Point(cx,xy), r); 
-1

私は知っています。これはC/C++/Javaの人々には完全に夢中に思えますが、質問とすべての回答で与えられた例は、CamelCaseNamingが実際に悪い悪いコンベンションであることをはっきりと示しています。

のは、元の例をもう一度見てみましょう:

Circle.createWithCenterAndRadius(cx, cy, r) 
Circle.createWithBoundingBox(x1, y1, x2, y2) 
Circle.createWithWidthAndHeight(x, y, w, h) 

をそして今、これがひどく見知らぬようですが、正直なところかもしれさんは、そのキャメルケース表記

Circle.create_with_center_and_radius(cx, cy, r) 
Circle.create_with_bounding_box(x1, y1, x2, y2) 
Circle.create_with_width_and_height(x, y, w, h) 

を取り除くみましょう:どのバージョンであります読みやすい?

+0

悪い例ではありませんが、実際には少し読みやすくなりますが、完全に無関係です。それは誰もが切り替えるか、何かになるようなものではありません(そして、もし誰かがしたらMANは悪いでしょう!)だからあなたは何を達成しようとしていますか? –

+0

注:私がJavaを使用しているときに私はJava構文を使用しています。私がRubyにいるとき、私はRuby構文を使用しました。私はどちらかのユーザーを他のユーザーに切り替える必要はないと感じました。どちらも可読性があります。 ps。 Rubyは少し読みやすくなっていますが、javaは入力するのが簡単です。 –

0

あなたの本能は正しい - このようなものを作成するパターン全体は - iffyです。

これらが1〜2回使用されない限り、それらはかなり乱雑になります。 5つの円と3つの三角形を持つ図形を作成していた場合、それは混乱します。

単純な例以外のものは、おそらく何らかの種類のデータ駆動型実装で最もうまくいくでしょう。

これらの目的のために、文字列、ハッシュ、またはXMLを使用してシェイプを定義すると、非常に便利です。

しかし、どのように使用するのかによって異なります。

私はJavaでSwingコントロールを作成するのと同じ種類の問題があります。あなたは、 "new Button()"の行の後に行末をつけ、最後に.setプロパティ呼び出しと、その値をオブジェクトにコピーする(またはリスナーを追加する)コード行と、その行をリセットする行値..

そのような定型文は決してコード内で起こるべきではないので、私は通常、データでそれを駆動し、オブジェクトを動的にオブジェクトにバインドする方法を見つけようとします - そしてその目的のためには、役に立った

+0

あなたの提案にはメリットがあります。データ駆動型実装の簡単な例を教えてください。 "文字列"については、ドメイン固有言語(DSL)のようなものを意味していますか? –

関連する問題