2010-01-19 6 views
8

Cách tiếp cận tốt nhất để thực hiện khi bạn đang kéo đối tượng mô hình từ nhiều nguồn dữ liệu?Có các mẫu cho mô hình/lớp thực thể

Ví dụ tôi có một ứng dụng có một số dữ liệu được lưu trữ trong cơ sở dữ liệu mySQL bằng cách sử dụng chế độ ngủ đông. Điều gì xảy ra nếu tôi muốn lưu trữ một số đối tượng khác trong EC2 hoặc Google App Engine? Tôi hiểu rằng DAO trừu tượng thực hiện làm việc với một nguồn dữ liệu cụ thể, nhưng những gì về các thực thể mình? Lúc đầu, tôi nghĩ rằng chú thích thực thể của tôi với chú thích jpa là một giải pháp tuyệt vời, nhưng bây giờ có vẻ như tôi đã thực sự gắn các thực thể của tôi xuống một triển khai cụ thể. Ví dụ, trong trường hợp của App Engine, một số chú thích này không có ý nghĩa gì cả.

Có vẻ như tôi cần một lớp POJO thuần túy để đại diện cho các thực thể của tôi, hoàn toàn không có logic bền bỉ. Nếu tôi muốn mô hình một con chó ví dụ (có sự lựa chọn lame, nhưng bất cứ điều gì).
Sẽ có ý nghĩa khi có lớp Dog trừu tượng, sau đó xác định các lớp con để làm việc với các giải pháp kiên trì cụ thể: HibernateDog, GAEDog, v.v.

Cảm ơn.

Trả lời

4

Đây là một câu hỏi hay, ngay cả khi vấn đề không phải là mới. Là một ngành công nghiệp, chúng tôi đã thay đổi "sự khôn ngoan thông thường" về chủ đề này thường xuyên trong những năm qua. Các câu trả lời bạn nhận được hôm nay không nhất thiết là những gì bạn sẽ nhận được 5 năm trước hoặc 5 năm trong tương lai.

Trong hình dung như thế nào tôi muốn thích để xử lý mặt hàng này, tôi tự hỏi về một số điều bạn chưa biết: là ứng dụng của bạn "hệ thống của kỷ lục" cho các tổ chức Chó? Các hệ thống con/lớp/ứng dụng khác cần biết về các thực thể Dog.

Trong Java, khi bạn viết các loại hoàn toàn mới như Animal> Dog, bạn sẽ nhận được phần thưởng sau: cơ hội viết nhiều mã hơn để biết cách tương tác với các đối tượng Thú và đối tượng Dog. Tôi ít bị thuyết phục trong năm 2010 rằng đây là một ý tưởng tốt hơn tôi năm năm trước.

Bạn có chịu trách nhiệm thiết kế cơ sở dữ liệu mà thông tin về Chó được lưu trữ không? Chúng tôi đã từng làm điều đó mọi lúc, nhưng ngày nay tôi thường thấy mình tích hợp với các bản ghi dữ liệu thực sự được quản lý bởi các hệ thống khác: google API, thực thể LDAP, kho dữ liệu, các sản phẩm như peoplesoft, v.v.

Nếu bạn không phải phụ trách việc xác định Dog là gì và cách chúng tương tác với vũ trụ, tôi sẽ xem xét cách thức không phụ thuộc vào miền để mô hình hóa thông tin Dog trong bộ nhớ. Có rất nhiều: XML/DOM, JSON, Bản đồ vv

Những lợi thế của việc di chuyển dữ liệu của người khác xung quanh trong các định dạng được nhiều ...

  • bạn không phải viết POJO
  • đây là những phong phú về tính năng, tài liệu và thử nghiệm
  • có rất nhiều API hiện có để chuyển đổi, thao tác và serialize những sinh vật
  • bạn có thể nhận được để sử dụng lại mã xem/controller/khác của bạn trên các lĩnh vực khác

Mặt khác ... nếu bạn là hệ thống bản ghi cho dữ liệu Chó, hãy xem xét sử dụng giao diện thay vì các lớp trừu tượng. Hoặc có thể là các lớp trừu tượng trừu tượng. Java chỉ có thừa kế đơn; tie xem của bạn/điều khiển/mã khác để giao diện để guarentee sự linh hoạt nhất trong tương lai.

2

Một trong những vấn đề với Hibernate là nó tiêm riêng các triển khai Collection vào lớp miền của bạn, gây ra sự cố nếu bạn cố gắng gửi lớp của mình qua dây sử dụng tuần tự hóa (ví dụ: từ máy chủ đến ứng dụng khách).

Trong ví dụ trên của bạn tôi sẽ đặt câu hỏi về sự cần thiết phải cung cấp lưu trữ cụ thể phụ lớp:

Đỗ/nên các lớp học thực sự chứa nhà nước liên quan đến cách thức mà họ đã lưu trữ? tức là Đây có phải là một khái niệm tập trung vào lớp và do đó xứng đáng với việc sử dụng hết "một phát" của bạn khi thừa kế (trong Java có nghĩa là)? Tôi cho rằng một hệ thống phân cấp thừa kế hữu ích hơn trong ví dụ của bạn sẽ là một cái gì đó như:

  • Animal
    • Mammal
      • Chó
      • Cát

Ngoài ra, với thiết kế bạn đề xuất bạn có thể gặp sự cố nếu, ví dụ bạn muốn lưu một ví dụ Dog thành Hibernate nhưng không biết liệu Dog có phải là HibernateDog, GAEDog, v.v ... không và phải thực hiện kiểm tra/downcasting tại điểm này.

1

Điều bạn có vẻ là cách chính xác. Thiết kế tốt không có nghĩa là các thực thể không bị ràng buộc với công nghệ, điều đó chỉ có nghĩa là nếu bạn thay đổi công nghệ, bạn chỉ chỉ thay đổi 1 lớp ứng dụng của bạn.

Thực thể có JPA là giải pháp tốt nếu bạn đang sử dụng JPA. Bên cạnh những thực thể đó, bạn có thể có nhiều "thực thể" (POJO) được kết nối với GAE, v.v.

Giới thiệu về chó trừu tượng và phân lớp, có vẻ quá mức cần thiết, ngoại trừ nếu bạn thực sự cần.Nếu bạn thực sự cần, hãy kiểm tra đối tượng DTO: http://en.wikipedia.org/wiki/Data_transfer_object

DTO được sử dụng để chuyển đối tượng sang lớp trên (trên DAO) một cách nhất quán (và làm cho nó có thể tuần tự hóa) ngay cả khi xử lý nhiều nguồn dữ liệu/công nghệ trong lớp kiên trì.

2

Chú thích JPA có thể đẹp ở chỗ chúng cho phép bạn đặt siêu dữ liệu ánh xạ đối tượng (ORM) trong cùng một tệp với các lớp thực thể của bạn, nhưng bạn hoàn toàn đúng là có sự pha trộn các mối quan tâm khi bạn kết hợp JPA siêu dữ liệu với POJO "thuần túy". Đó là một sự đánh đổi.

Tuy nhiên, có một sự thay thế. Bạn có thể mở rộng cấu hình ORM trong các tệp XML và theo cách đó, hãy giữ các chi tiết đó khỏi các lớp thực thể của bạn. JPA cung cấp cú pháp cấu hình XML, nhưng đối với các dự án của tôi, tôi thích sử dụng ánh xạ XML Hibernate nguyên bản để có thêm tính linh hoạt mà chúng cung cấp. Nó có thể không phải là thời trang như một cách tiếp cận dựa trên chú thích, nhưng theo kinh nghiệm của tôi, nó hoạt động khá tốt.

2

Bạn đang sử dụng lớp DAO để trừu tượng hóa chi tiết nguồn dữ liệu từ các lớp khác. Vì vậy, lớp mô hình thực sự không có kiến ​​thức về kỹ thuật lưu trữ dữ liệu hoặc cơ sở dữ liệu nào đang được sử dụng.

Câu trả lời cho câu hỏi của bạn sẽ là: Sử dụng lớp Dịch vụ. Đây là lớp nơi bạn đặt tất cả mã doanh nghiệp của mình. Thực thể nào để khởi tạo, mà DAO để sử dụng, làm thế nào để chứng thực dữ liệu, phân tích giao dịch, v.v.

Vì vậy, lớp dịch vụ phải được in nghiêng/kiên trì các thực thể của bạn. Và đó là nơi bạn nên nhúng logic về những gì datasource/cơ sở dữ liệu để sử dụng. Sử dụng tiêm phụ thuộc của Spring để giúp bạn với điều đó. Tiêm lựa chọn các DAO, Entities của bạn vào lớp Service.

Entity lớp: Chó, Mèo

lớp dịch vụ: AnimalCenterService

lớp DAO: AnimalCenterHibernate, AnimalCenterJDBC

Hãy cho tôi biết nếu giải thích thêm là cần thiết. Chỉ 2 xu của tôi

1

Bạn sẽ không muốn có mã cụ thể bền bỉ được thừa kế từ các lớp thực thể của bạn vì điều đó sẽ không thể sử dụng thừa kế cho các lớp thực thể miền của bạn. Ví dụ nếu bạn có HibernateDog kế thừa từ Dog thì bạn sẽ không được phép có Poodle kế thừa từ Dog mà không buộc Poodle trở thành Hibernate cụ thể.

Một cách tiếp cận hoạt động là sử dụng Thực thể dữ liệu kiên trì cụ thể. Các lớp thực thể miền của bạn sẽ ủy quyền cho đối tượng thực thể dữ liệu cho các thuộc tính liên tục của nó thông qua một giao diện. Sau đó, bạn có thể thay thế các lớp thực thể dữ liệu cụ thể của các thực thể tồn tại khác nhau miễn là chúng tuân theo giao diện thực thể dữ liệu của bạn.

Tham khảo về chó (và người được ủy quyền) Giao diện DogEntity. Poodle kế thừa từ Dog, PoodleEntity thừa kế từ DogEntity.

HibernateDog triển khai DogEntity
HibernatePoodle triển khai PoodleEntity và kế thừa từ HibernateDog.
...
StubDog thực hiện DogEntity
StubPoodle thực hiện PoodleEntity và được thừa hưởng từ StubDog
...

Bạn có thể có bao nhiêu loại thực thể dữ liệu tùy thích. Các thực thể dữ liệu sẽ rất mỏng và sẽ chỉ giữ các biến thành viên liên tục và các chú thích hoặc bất kỳ mã nào khác là cần thiết cho sự kiên trì.

Thực thể miền sẽ chứa logic nghiệp vụ cụ thể của thực thể.