2009-02-17 44 views
19

Tôi có yêu cầu xây dựng 'phiên bản' vào một ứng dụng và đang tự hỏi cách tốt nhất để tiếp cận nó.Mẫu thiết kế phiên bản nào bạn sẽ giới thiệu

Tôi có mô hình chung này:

Model A có nhiều B

ở đâu trên bản cập nhật các thuộc tính của A cần phải được phiên bản và các đối tượng liên quan của nó (B) cũng cần phải được phiên bản. Vì vậy, ứng dụng sẽ hiển thị phiên bản hiện tại của A, nhưng cũng phải có khả năng xem các phiên bản trước đó của A và các đối tượng liên quan của nó.

Tôi muốn sử dụng cửa hàng tài liệu tuy nhiên đây chỉ là một phần của ứng dụng và có cửa hàng doc và cơ sở dữ liệu quan hệ sẽ giới thiệu độ phức tạp hơn.

Tôi đã xem xét sử dụng lược đồ hình sao, nhưng trước khi tiến triển, tôi đã tự hỏi liệu có một mẫu thiết kế nổi xung quanh giải quyết vấn đề này không?

Câu hỏi này được nghiêng về phía giải quyết vấn đề lưu trữ các phiên bản của đối tượng được liên kết trong cơ sở dữ liệu quan hệ. Trường hợp có một nhu cầu vốn có để có thể có hiệu quả truy vấn dữ liệu (tức là đối tượng serializing sẽ không đủ).

Cập nhật: Những gì tôi đã suy nghĩ/đã thực hiện nhưng muốn xem nếu là "một cách tốt hơn"

,---------. 1  * ,--------. 
| Model A |----------| Model B| 
`---------'   `--------' 
|PK  |   | a_id | 
|b_version|   |version | 
|version |   `--------' 
`---------' 

đâu tôi sẽ được sao chép mô hình A và tất cả các liên quan đến B và incrementing thuộc tính phiên bản. Sau đó thực hiện lựa chọn để tham gia B bằng b_version và b.version. Chỉ cần tự hỏi nếu điều này có thể được thực hiện tốt hơn.

Trả lời

7

Tôi không nghĩ rằng không có mẫu thiết kế GoF cụ thể cho phiên bản vì có nhiều triển khai.

Triển khai phiên bản đơn giản nhất là danh sách đối tượng được liên kết. Trong đó mỗi nút trong danh sách là một phiên bản mới của bất kỳ đối tượng có thể phiên bản nào. Để tiết kiệm dung lượng, bạn cũng thực hiện một số loại diff cho biết sự khác nhau giữa các phiên bản. Bằng cách đó bạn có thể lưu trữ các khác biệt trong cơ sở dữ liệu, nhưng cũng là phiên bản cuối cùng của đối tượng có thể phiên bản kể từ khi hệ thống điều khiển phiên bản có thể lấy được các phiên bản ở giữa.

Giản đồ cơ sở dữ liệu chủ yếu có thể giống như thế này (bạn có thể thấy mô hình này trong hầu hết các hệ thống wiki):

+--------------------+ 1  * +-----------------------------+ 
| VersionableObject |---------| Diff      | 
+--------------------+   +-----------------------------+ 
| lastStateContent |   | difference     | 
| originalAuthor  |   | revision     | 
| #dates and whatnot |   | # userId, dates and whatnot |  
+--------------------+   +-----------------------------+ 

Nếu bạn muốn đi Hardcore với phân nhánh và các công cụ bạn có thể muốn xem xét có một cái nhìn tại DAG đó là những gì hiện đại phân phối phiên bản hệ thống kiểm soát sử dụng.

Bây giờ, nếu chúng ta nói về ví dụ của bạn là toàn bộ các đối tượng cần được lưu trong cấu hình. I E. chúng tôi phải chọn các bản sửa đổi của các đối tượng mà chúng tôi muốn cho mô hình. Điều đó có nghĩa là chúng tôi có mối quan hệ nhiều đến nhiều (được giải quyết với một bảng trung gian), như sau:

+---+ 1 * +---------------+ 1 * +-----------------+ * 1 +-------+ 
| B |-------| Diff   |-------| ModelSelection |-------| Model | 
+---+  +---------------+  +-----------------+  +-------+ 
      | revisionNo |  | {PK} configId | 
      | {FK} configId |  | {FK} modelId | 
      +---------------+  +-----------------+ 

Tôi hy vọng điều này sẽ hữu ích.

+0

Việc triển khai này sẽ không giải quyết được vấn đề duy trì mối quan hệ giữa các phiên bản và các đối tượng liên quan của chúng – MatthewFord

+1

deimos1986: tất nhiên là có, cập nhật với một ví dụ dbschema. bạn có thể thấy cửa sổ bật lên này trong triển khai wiki. Tôi đề nghị bạn xem xét MediaWiki hoặc các hệ thống wiki mã nguồn mở khác và xem xét các mô hình cơ sở dữ liệu của chúng để lấy cảm hứng – Spoike

+0

Ồ bạn có nghĩa là bạn có một cấu hình toàn bộ các đối tượng cần được phiên bản ... – Spoike

1

Kết hợp của Memento pattern với Observer pattern phải phù hợp với nhu cầu của bạn. Ngoài ra, hãy xem Visitor pattern để có thể áp dụng trong trường hợp của bạn ...

+0

Có vẻ như nó có thể giúp tôi đoán câu hỏi của tôi liên quan đến thiết kế ở cấp DB. Làm thế nào để bạn đi về sự bền bỉ Memento khi họ có nhiều đối tượng liên quan, mà cũng cần phải được tiếp tục tồn tại. – MatthewFord

+0

Mỗi đối tượng chịu trách nhiệm lưu trữ trạng thái của nó vào bảng cơ sở dữ liệu theo. Khi mỗi đối tượng cũng giữ một thuộc tính "phiên bản", được đồng bộ hóa qua Observer trên mọi thay đổi, việc lưu trữ trạng thái nhất quán và có thể lặp lại sẽ có thể thực hiện được. – Kosi2801

2

Tôi đã giải quyết vấn đề này trong đường ray bằng cách sử dụng plugin acts_as_versioned. Khi bạn áp dụng nó cho một mô hình, nó giả định có một model_name_version ngoài bảng model_name. Mỗi khi một mô hình được lưu, phiên bản cũ cùng với một dấu thời gian được sao chép vào bảng model_name_version.

Cách tiếp cận này giữ kích thước của bảng mô hình có thể quản lý được trong khi vẫn cho phép tìm kiếm trên các phiên bản trước. Tôi không chắc plugin có xử lý chuỗi bạn muốn ra khỏi hộp hay không, nhưng sẽ không khó để thêm vào.

+0

Tôi đã xem xét actions_as_versioned và các plugin hiện có khác, dường như không có lỗi nào xử lý vấn đề này về các liên kết phiên bản. trang wiki AAV có câu hỏi mở này: Có ai đã thực hiện bất kỳ công việc nào với các mối quan hệ khóa ngoài phiên bản ... – MatthewFord

+0

Phải - tôi hy vọng nó không có. Tuy nhiên, các plugin rất dễ sửa đổi, và sự thay đổi đặc biệt này sẽ không khó. –

+0

Tôi đã viết một plugin cho phần tiếp theo thực hiện điều này dọc theo các dòng được mô tả trong câu hỏi. Tôi muốn có một đâm vào nó một lần nữa trong AR và làm điều đó một cách tốt nhất có thể. Nếu hãy xem mã plugin AAV, mở rộng nó để xử lý các liên kết n..n là không tầm thường. – MatthewFord

8

Martin Fowler có một số điều tốt về thời gian/mẫu thiết kế phiên bản dựa trên - chắc chắn giá trị một cái nhìn:

http://martinfowler.com/eaaDev/timeNarrative.html

+0

Liên kết này đã tốt cho việc khẳng định ý tưởng của tôi, vì anh ấy đang sử dụng thời gian làm thứ nguyên nơi tôi đề xuất sử dụng số phiên bản. – MatthewFord

0

gì về tiết kiệm một bản chụp XML của shema cơ sở dữ liệu bạn muốn phiên bản? Và sau đó có thể thay đổi trạng thái của cơ sở dữ liệu?

+0

để thành thật nhìn lại, tôi sắp sửa khắc phục vấn đề bằng cách lấy tất cả dữ liệu tôi cần và kết hợp nó thành một tài liệu json lớn và đổ nó vào couchdb khi tôi cần phiên bản (của một bộ sưu tập bảng). Các vấn đề không quá nhiều với lược đồ, nhưng với việc mở rộng nhiều bảng. – MatthewFord

Các vấn đề liên quan