2

これは不自然な例です。たとえば、ある人が友達を持っている国の人口をリストしたい場合、以下に2つの設定を示します。モデルでデータを繰り返すのが最善でしょうか?

デメテルの法則に従うことが重要だと言われました。例としては、犬に歩くように指示する場合、足に歩くように命令するのは愚かです。

People.where(:country => friend.country)私の豊富な経験のなさ(noob)で、モデルがデータを繰り返す場合、 (これまで不可能だった)連鎖した関連付けがあるコレクションと比較して、クエリがはるかに簡単になることがわかりました:(People.where(:city => { :county => { :region => { :country => friend.city.county.region.country }}}) これは本当にこのnoobに役立ちますここで、正しい工夫されたLoDの設定と構文を想像できれば、概念を理解できます。デメテルの法則とは関係のない例を使用しなかったことを願っています)LoDを適用してみdelegateたところ、まだ連鎖している(私はそうです)が、私が考えることができる唯一の解決策は、関連付けを介してアクセスできるデータを繰り返すことです。

しかし、私はデータを繰り返すのが嫌いです!これは、Twitterを再作成するDHHのRailsのチュートリアルをフォローしているためです。彼は、関係を作成することとデータを繰り返すことの素晴らしさを示しました。

アソシエーションの連鎖を少なくするには、データを繰り返すことが適切である必要がありますか?

モデル、繰り返しデータ

class Country < ActiveRecord::Base    
  has_many :regions    
  has_many :counties    
  has_many :cities    
  has_many :people
end

class Region < ActiveRecord::Base
  has_one :country
  has_many :counties
  has_many :cities    
  has_many :people
end

class County < ActiveRecord::Base
  has_one :country
  has_one :region
  has_many :cities    
  has_many :people
end

class City < ActiveRecord::Base
  has_one :country
  has_one :region
  has_one :county    
  has_many :people
end

class Person < ActiveRecord::Base
  has_one :country
  has_one :region
  has_one :county    
  has_one :city
  has_many :relationships
  has_many :friends, :through => :relationships
end

vs連鎖関連のあるモデル

class Country < ActiveRecord::Base    
  has_many :regions   
end

class Region < ActiveRecord::Base
  belongs_to :country
  has_many :counties
end

class County < ActiveRecord::Base
  belongs_to :region
  has_many :cities
end

class City < ActiveRecord::Base
  belongs_to :county
end

class Person < ActiveRecord::Base
  belongs_to :city
end
4

3 に答える 3

1

これは、データベース設計とデータ整合性の問題であるほど、デメテルの法則の問題ではないようです。最初のオプションは、第3正規形(3NF)に間違いなく違反するデータベースを作成するため、除外する必要があります。

最初の例では、国のHM都市の場合、その都市を更新して、その国に属していない別の地域に属するようにするとどうなりますか?->バム!データの整合性が失われました!もちろん、都市が別のに移動する可能性は低いですが、あなたが言ったように、これは不自然な例であり、私は一般的なケースについて話している

詳細については、データベースの正規化と第3正規形をグーグルで検索する必要があります。

また、この場合、3NFに違反しているのは、そうすることで「パフォーマンスを向上させる」ことができると考えているからです。これは事前最適化のケースであり、悪い習慣です。場合によっては、非正規化が管理されたリスクですが、ここにドラゴンがいます。レールでアプリを起動したばかりの場合は、これは間違いなく当てはまりません。DBにデータの迅速なフェッチについて心配させてください。あなたは良いインデックスを提供することによってそれを助けることができます。

また、あなたが探しているのは、ネストされたものを作成する方法であると思います。次のような場合になります。

地域を通じた国HM郡

そしてそれ、

郡を通じた国HM都市

3.0を使用している場合、これは3.1で標準になります。その後、

https://github.com/ianwhite/nested_has_many_through

私が現在使用している宝石で、とても満足しています。

于 2011-06-19T18:55:45.050 に答える
1

ああ、「デメテルの時々役に立つ提案」。(マーティン・ファウラー。)

DIE / DRYと正規化はより基本的な原則だと思いますが、最終的には、常識を適用する必要がある矛盾するガイドライン間の争いになるでしょう。

ある特定のプロジェクトのオブジェクトクラスに適用される「法則」は、クラス階層設計モデルとして明らかな価値があります。

しかし、特にRailsビューに関して、Demeterのアプリケーションについては論争があります。定義上、これらはレポートであるため、デメテルの提案が適用可能かどうかは疑問です。

于 2011-06-19T18:59:16.170 に答える
0

私の意見では、可能な限りデータの繰り返しを避けるべきです。ただし、データを結合できる集約オブジェクトを作成することはできます。したがって、コアエンティティをクリーンに保つことができますが、オブジェクトを集約する追加のサポートエンティティを使用できます。

SQLのビューの例を使用すると、多くのエンティティの組み合わせである結果を取得できます。この結果は集約エンティティである可能性があり、データを「繰り返す」ための完全に正当な手段です。

于 2011-06-19T18:53:45.480 に答える