2009-04-03 10 views
4

かなり大きなRubyアプリケーションでは、特定のオブジェクトが名前とIDの2つのものによって識別される状況があります。これらの値の型はどちらかといえば多少異なる目的を持っているので、全く同じではありません(idとnameは別の場所に残っています)。したがって、アプリケーション(ID、名前、およびオブジェクト)の周りにさまざまな値が渡されています。この状況は、ある種の関数にどの型を渡すべきか明確ではないバグにすでに噛まれているので、少なくともある程度は問題のように思えます。私は実際には何年もの間、同じ問題コードを数多くのアプリケーションで見てきましたが、私はもう一度特定の名前を付けませんでした。"messy-polymorphism" anti-pattern

Rubyは、型のない言語として、C++のやり方で古典的な型ベースの多型関数を使用できません。回避策として、同僚は、多くの場合、この種のコードを頼っています

def initialize starting_value 
    if starting_post.kindof? Foo 
     @starting_id = get_id_from_foo starting_value 
    elsif starting_post.kindof? Bar 
     @starting_id = get_id_from_bar starting_value 
    else 
     raise "illegal type" 
    end 
    end 

私は「乱雑 - ポリモーフィズム」と呼ぶもので、当社のコードベース(だけでなく、初期化子)の結果の周りにこのコードの増殖を。それはしばしば動作しますが、時には非常に混乱した状況を作ります。

私はこれに関する3つの質問があります。

  • 正式名称は ですが、アンチパターンはありますか? "メッシーなインタフェース?"、 "メッシー多相性?"または、他の何か?
  • これは人がいかに悪いと思いますか?
  • リファクタリングの体系的な方法はありますか? 私たちが作成した多くのテストではこのように多くのテストが作成されているという挑戦は ルース型であるため、 のテストと実装を同時に変更しなければならないので、通常のテストの足場効果はありませんベースの リファクタリング。私は実際にこの緩い多形性を「強化」して、 をコード化し、即座にコードを関数に抽象化できると思っています。しかし、 これは良い考えですか?
+0

これはRailsアプリケーションですか? –

答えて

7

idが自分自身を返すように、ある種のget_idメソッドを定義することはできません。オブジェクトはIDを返し、名前はIDを取得するために何をする必要がありますか?それで、あなたは、3つのうちの1つになることがわかっているものは、いつも標準化することができます。同様に、get_nameメソッドとget_objectメソッドが必要な場合はそれらを使用します。

つまり、暗黙的なThingWhatHasAnIDインターフェイスを定義し、その関数パラメータのduck-typeを作成しました。

私が何かが欠けていない限り、私はこの反パターン「抽象化を作成する機会がなくなった」と呼んでいます。

4

ほとんどの場合、オブジェクトのクラスを切り替えるといつでも、その動作はオブジェクト自体のメソッドでなければならないという手掛かりです。メッセージ送信は、受信者に基づいて多形であるです。

def initialize starting_value 
    @starting_id = starting_value.id 
end 

行うために使用されるものは何でも様々なget_id_from_*方法を行うためにidを定義します。この場合、それはのようなものでなければなりません。あなたがNoMethodErrorを取得するので、違法型のケースは既に発生します。

これを何と呼ぶか​​は、「OO言語で手続き型プログラミング」と呼んでいます。"