2016-11-15 2 views
4

私は2つのクラスを持っているとしましょう。 1つのクラス、「親」には、もう1つのクラス「子」が多数あります。これは継承ではなく、私は親メソッドを子オブジェクトに作用させたくありません。私が望むのは、子オブジェクトが親オブジェクトを参照し、それから変数(child.parent.var)を取得し、親を変更する親メソッド(child.parent.update)を呼び出すことができることです。Rubyで "親"、 "子"クラス(継承ではない)

初期化時に別のオブジェクトへの参照を渡すことができる1つのオブジェクト(これは子ではなく、子ではないと考えることができます)です。私はこれを親の子関係に比較して、親の情報を格納するデータベースに入れて、すべての子に複製する必要はありません。

例:

class Parent 
    attr_accessor :var 

    def initialize(num) 
    @var = num 
    end 

    def increase 
    @var += 1 
    end 
end 

class Child 
    attr_accessor :var, :parent 

    def initialize(parent, num) 
     @parent = parent 
     @var = num 
    end 

    def sum 
     @parent.increase 
     @parent.var + var 
    end 
end 

parent1 = Parent.new(1) 

child1 = Child.new(parent1, 2) 
child2 = Child.new(parent1, 3) 

child1.parent.increase # update the parent variable 
child2.parent.var  # get the parent variable 

上記のコードは、作業を行いますが、これを達成するために、より良い(より簡潔、またはそれ以上のルビーESQ)方法はありますか?

ご協力いただきありがとうございます。

+0

ようこそ同じようにそれを呼び出すことができます。これはかなり素晴らしい最初の質問です。将来、問題の詳細をもう少し詳しく説明してください。 「あまりにも奇妙な気がする」とは、かなり曖昧な説明です。スタックオーバーフローは最近、ハードコードの問題に向いていますが、デザインやコード構造に関する質問はここでも話題になっています。あなたの実際の問題を必ず記述してください。多くの場合、http://softwareengineering.stackexchange.com/またはhttp://codereview.stackexchange.com/は、これらの種類の質問にも最適です。 –

+0

@Holger他のサイトを参照しているときは、[クロスポストがぼやけていることを指摘する]ことがよくあります(http://meta.stackexchange.com/tags/cross-posting/info) – gnat

+0

@HolgerJustあなたの知恵に感謝します。友人!まだ初心者なので、私は次の質問にあなたのアドバイスを取るでしょう:-) –

答えて

3

これは基本的にどのようになっているのでしょうか?あなたが実際に達成したいことに応じていくつかの改善があります。

現在のところ、Childインスタンスは、(parentアクセサーを使用して)外部インターフェイス上の親へのアクセスを公開しています。これは多くの場合、オブジェクトが直接隣人と話すだけであることを示すLaw of Demeterの違反です。この意味で、parentは、子オブジェクトを通してアクセスされたときに見知らぬ人です。

あなたは親オブジェクトを非表示にすることで、あなたのデザインを向上させることができます:ここで

class Child 
    extend Forwardable 

    def_delegator :@parent, :var, :parent_var 
    def_delegator :@parent, :increase 

    attr_accessor :var 

    def initialize(parent, num) 
    @parent = parent 
    @var = num 
    end 

    def sum 
    @parent.increase 
    @parent.var + var 
    end 
end 

は、我々はクライアントから親のいくつかのメソッドへのアクセスを提供するために、RubyのForwardableモジュールを使用しています。これにより、これらのメソッドは、Childクラスの単一のパブリックインターフェイスの一部になります。

parent = Parent.new(1) 

child = Child.new(parent, 2) 

child.var 
# => 2 
child.parent_var 
# => 1 
child.increase 
# => 2 
parent.var 
# => 2 
# ^^^^ the increase method was called on the parent object 

外部からは、メソッドが転送されていても、後で外部インターフェイスに影響を与えることなく変更することができます。


第2の改良点は、直接子供を生成するためにあなたのParentクラスを拡張することができます

class Parent 
    # ... 

    def child(num) 
    Child.new(self, num) 
    end 
end 

は、これは通常Factory Methodと呼ばれている、すなわち、他のオブジェクトを構築する方法。これにより、子オブジェクトを構築して親オブジェクトに追加する複雑さを隠すことができます。

あなたは、スタックオーバーフローに

parent = Parent.new(1) 
child = parent.child(2) 
関連する問題