2009-07-24 19 views
5

Vì vậy, tôi chỉ tò mò về vấn đề này:Tại sao DataMapper sử dụng mixins vs inheritance?

DataMapper sử dụng một mixin cho mô hình của nó

class Post 
    include DataMapper::Resource 

Trong khi hoạt động kỷ lục sử dụng thừa kế

class Post < ActiveRecord::Base 

Có ai biết tại sao DataMapper đã chọn để làm theo cách đó (hoặc tại sao AR chọn không)?

Trả lời

3

Tôi nghĩ ý tưởng là ActiveRecord xem xét khía cạnh cơ sở dữ liệu được hỗ trợ là tính năng chính của một lớp mô hình để nó kế thừa hành vi đó. DataMapper có vẻ như nó coi cơ sở dữ liệu được sao lưu chỉ là một khía cạnh của một lớp có thể được thêm vào một lớp.

Đó là dự đoán của tôi. Yehuda Katz có thể cho bạn biết dứt khoát.

+0

Tôi nghĩ rằng nó có thể là một lý do hoàn toàn 'philosphical' - Hãy xem những gì người khác nói. – cloudhead

5

Nó cho phép bạn kế thừa từ một lớp khác không phải là lớp DM.

Nó cũng cho phép thêm các tính năng DM vào một lớp đang bay. Dưới đây là một phương pháp học từ một module Tôi đang làm việc trên ngay bây giờ:

def datamapper_class 
    klass = self.dup 
    klass.send(:include, DataMapper::Resource) 
    klass.storage_names[:default] = @table_name 
    klass.property(:id, DataMapper::Types::Serial) 
    klass.property(:created_at, DateTime, :nullable => false) 
    klass.property(:updated_at, DateTime, :nullable => false) 
    columns_with_types { |n, t| klass.property(n, t, :field => n.to_s) } 
    klass 
end 

này cho phép tôi tham gia một lớp SAXMachine (rất nhẹ) và biến nó thành một lớp Datamapper khi đang bay, và làm DataMappery thứ với nó . Bạn thậm chí có thể đến nó với lớp đơn của một đối tượng. Tôi muốn tưởng tượng rằng điều này làm giảm bộ nhớ của tôi khi tôi đang nhập 100K đối tượng từ XML (tôi không sử dụng DM cho nhập khẩu hàng loạt) và chỉ kết hợp trong các hàm cơ sở dữ liệu phức tạp hơn khi tôi cần chúng

+0

thú vị, tôi đã không nghĩ về điều đó. – cloudhead

0

Đây thực sự là câu hỏi về việc chọn Inheritance vs Thành phần.

Cá nhân tôi ủng hộ bố cục vì nó dường như là cách xây dựng lớp và đối tượng tự nhiên hơn.

Thành phần cung cấp cho bạn nhiều quyền kiểm soát hơn đối với những hành vi bạn muốn đưa vào lớp học của mình. Đối với thừa kế bạn nhận được hoặc là tất cả mọi thứ hoặc không có gì. Thành phần cho phép anh đào chọn những hành vi bạn muốn.

+1

Mixins không có gì để làm với bố cục. Giống như thừa kế, Mixin là một đề xuất tất cả hoặc không có gì cả. Và không giống như với bố cục, bạn không thể thay đổi đối tượng được trộn lẫn trong lúc chạy. – KaptajnKold

4

Mẫu DataMapper nhằm cung cấp một lớp cho phép mô hình đối tượng tên miền phân kỳ từ lược đồ. ActiveRecord hợp nhất mô hình đối tượng và cấu trúc cơ sở dữ liệu quan hệ.

mỗi Martin Fowler:

Đối tượng và cơ sở dữ liệu quan hệ có các cơ chế khác nhau cho cấu trúc dữ liệu. Nhiều phần của một đối tượng, chẳng hạn như các bộ sưu tập và kế thừa, không có trong cơ sở dữ liệu quan hệ. Khi bạn xây dựng một mô hình đối tượng với rất nhiều logic nghiệp vụ, nó có giá trị để sử dụng các cơ chế này để tổ chức tốt hơn dữ liệu và hành vi đi kèm với nó. Làm như vậy dẫn đến các lược đồ biến thể; có nghĩa là, lược đồ đối tượng và lược đồ quan hệ không khớp với nhau.

Bạn vẫn cần truyền dữ liệu giữa hai lược đồ và việc truyền dữ liệu này trở nên phức tạp theo đúng nghĩa của nó. Nếu các đối tượng trong bộ nhớ biết về cấu trúc cơ sở dữ liệu quan hệ, các thay đổi trong một đối tượng có xu hướng gợn sóng với nhau.

Trình ánh xạ dữ liệu là một lớp phần mềm tách các đối tượng trong bộ nhớ khỏi cơ sở dữ liệu. Trách nhiệm của nó là truyền dữ liệu giữa hai người và cũng để cô lập chúng với nhau. Với Data Mapper, các đối tượng trong bộ nhớ không cần biết ngay cả khi có cơ sở dữ liệu; chúng không cần mã giao diện SQL, và chắc chắn không có kiến ​​thức về lược đồ cơ sở dữ liệu. (Lược đồ cơ sở dữ liệu luôn luôn là không biết gì về các đối tượng sử dụng nó.) Vì nó là một dạng của Mapper (473), bản thân Data Mapper thậm chí còn chưa được biết đến với lớp miền.

0

ActiveRecord thực sự không nên sử dụng thừa kế, mà đúng hơn bao gồm mô-đun để thêm hành vi (chủ yếu là sự kiên trì) vào mô hình/lớp. ActiveRecord chỉ đơn giản là sử dụng mô hình sai!

Vì lý do tương tự, tôi rất thích MongoId trên MongoMapper, bởi vì nó để cho nhà phát triển có cơ hội sử dụng thừa kế như một cách để mô hình hóa một cái gì đó có ý nghĩa trong miền vấn đề.

Thật đáng buồn khi không có ai trong cộng đồng Rails đang sử dụng "Thừa kế Ruby" theo cách nó được sử dụng - để xác định thứ bậc lớp, không chỉ để thêm hành vi.