2010-06-25 29 views
5

Làm thế nào để thiết kế các lớp liên quan đến các bộ sưu tập của các lớp khác?Thiết kế (Hướng dẫn) của các lớp có chứa các bộ sưu tập của các lớp khác

chung Ví dụ:

Một Workspace chứa số Dự án.
A Dự án chứa số lượng lớn Tài nguyên.
Mỗi Tài nguyên có thể chứa số lượng lớn Tệp.

Vì vậy, ở đây các lớp được xác định có thể là Không gian làm việc, Dự án, Tài nguyên và Tệp. Không gian làm việc sẽ có danh sách Project.Project sẽ có danh sách Tài nguyên và Tài nguyên sẽ có danh sách tệp. Tất nhiên mỗi lớp có các thiết lập liên quan của nó.

Bây giờ, các câu hỏi cơ bản là:
a) Ai tạo và thêm lớp vào một bộ sưu tập cụ thể? Một lớp khác hoặc lớp học có chứa bộ sưu tập?
b) Cũng làm cách nào để theo dõi một bộ sưu tập cụ thể và cách lưu trữ giống nhau?
c) Ai kiểm tra các thay đổi đối với một bộ sưu tập cụ thể?
d) Các mẫu thiết kế khác nhau có thể được áp dụng trong các tình huống như thế nào?

Về cơ bản tôi muốn giảm khớp nối giữa các lớp khác nhau.

Cảm ơn tất cả mọi người

+0

Tôi cũng có câu hỏi liên quan mà tôi đã thêm ở đây .. http://stackoverflow.com/questions/3186632/a-design-for-adding-resources-to-a-project – Amitd

Trả lời

5

Có rất nhiều loại mối quan hệ - xem xét

  • ô tô và Wheels
  • ô tô và lái xe
  • ô tô và đăng ký Chủ đầu tư
  • khách hàng và Lệnh và Lệnh Dòng
  • Trường học và Lớp học và thể hiện của Lớp

Nếu bạn xem mô hình UML, bạn sẽ thấy các khái niệm như Cardinality và Direction và distictions giữa Aggegration and Composition và các câu hỏi liên quan đến vòng đời của các đối tượng liên quan.

Thật không ngạc nhiên khi chúng tôi cần một loạt các kỹ thuật và mẫu để xử lý các loại mối quan hệ khác nhau.

Về d). Có một nguyên tắc quan trọng là Law of Demeter hoặc nguyên tắc ít kiến ​​thức nhất.

Một kỹ thuật quan trọng là sau đó, Đóng gói giảm khớp nối bằng cách ẩn thông tin. Ô tô có thể có ít quan tâm đến nhiều chi tiết của mọi người, vì vậy chúng tôi có thể có một giao diện IDriver trên lớp Person của chúng tôi, IDriver cung cấp các phương pháp cụ thể mà ô tô quan tâm. Nguyên tắc chung là ưu tiên lập trình cho các giao diện.

Sau đó, chúng ta có thể suy nghĩ về a). Sự sáng tạo.Vì chúng ta đang có xu hướng sử dụng Giao diện, nên thường sử dụng các mẫu Nhà máy. Điều đó không để lại câu hỏi ai gọi cho nhà máy. Chúng ta thích:

IPerson aPerson = myAutomobile.createDriver(/* params */); 

hoặc

IPerson aPerson = aPersonFactory.create(/* params */); 
    myAutomobile.addDriver(aPerson); 

Ở đây tôi nghĩ nó khá rõ ràng rằng Ô tô không biết nhiều về con người, và do đó thứ hai là bộ phận tốt hơn về trách nhiệm. Tuy nhiên có lẽ Đơn đặt hàng có thể tạo một cách hợp lý OrderLines, Classes tạo ClassInstances?

b). Theo doi? Đó là lý do tại sao chúng tôi có nhiều bộ sưu tập các lớp học. Mà những người sử dụng phụ thuộc vào bản chất của mối quan hệ (một-một, một-nhiều, vv) và cách chúng tôi sử dụng nó. Vì vậy, chúng tôi chọn Mảng và HashMaps, vv theo nhu cầu. Đối với ô tô/bánh xe, chúng tôi thậm chí có thể sử dụng các thuộc tính tên của xe - sau khi tất cả xe có chính xác sáu bánh xe (frontLeft, frontRight, backLeft, backRight, dự phòng và lái). Nếu bằng cách "lưu trữ" bạn có nghĩa là tồn tại, thì chúng ta đang xem xét các kỹ thuật như các khóa ngoại trong một cơ sở dữ liệu quan hệ. Việc ánh xạ giữa RDBMS và các đối tượng trong bộ nhớ ngày càng được quản lý bởi các cơ chế bền vững tốt đẹp như JPA.

c). Kiểm toán? Tôi chưa thấy kiểm toán được áp dụng cụ thể ở cấp độ mối quan hệ. Rõ ràng phương thức Automobile.addDriver() có thể phức tạp tùy ý. Nếu có yêu cầu kinh doanh để kiểm tra hành động này, thì rõ ràng đây là một nơi phù hợp để làm điều đó. Đây chỉ là một câu hỏi thiết kế OO tiêu chuẩn xoay quanh những người sở hữu thông tin. Nguyên tắc chung: "Không lặp lại chính mình" vì vậy khá rõ ràng chúng tôi không muốn mọi đối tượng gọi addDriver() cần phải nhớ để kiểm toán, do đó đó là công việc của Auto.

1

Tạo thiết kế OO tốt là một chút của một biểu mẫu, nhưng có một số hiệu trưởng cần ghi nhớ.

Suy nghĩ về cách người dùng của bạn sẽ sử dụng giao diện của bạn. Người dùng của bạn là ai? Nó chỉ là bạn, và cho một mục đích cụ thể, hoặc là bạn thiết kế một cái gì đó cho các khách hàng khác nhau. Thiết kế giao diện rất khó, nhưng hãy nghĩ về những ví dụ thực sự về cách người dùng của bạn thực sự muốn sử dụng giao diện của bạn. Một cách tốt để làm điều này là viết các bài kiểm tra, điều này buộc bạn phải sử dụng các công cụ của riêng mình. Một cách khác là xem các thư viện hiện có làm điều tương tự và xem chúng được sử dụng như thế nào.

Giữ mọi thứ đơn giản, ngu ngốc. Tức là, giữ chúng đơn giản từ góc độ người gọi của bạn. Điều này áp dụng cho việc đóng gói, nơi bạn chỉ nên trưng bày các nội dung thực thi của bạn khi cần thiết. Nó áp dụng để tạo ra một giao diện nhất quán dễ hiểu. Và điều đó có nghĩa là bạn nên tránh cái bẫy tạo ra một vật thể cho mọi lớp học có thể tưởng tượng được, tạo ra hàng tấn các thuộc tính, và càng chung càng tốt. Điểm cuối cùng này là một điểm đặc biệt quan trọng; điều khiến chúng ta tốt như các nhà phát triển là chúng ta có khả năng suy đoán và trừu tượng, nhưng vì điều này, chúng ta thường rơi vào cái bẫy làm cho các hệ thống trở nên phức tạp hơn là cần thiết.

Suy nghĩ về quyền sở hữu. Mỗi đối tượng sẽ được sở hữu bởi một đối tượng khác, có nghĩa là đối tượng sẽ được tạo và hủy như một phần của đối tượng đó, hoặc nó sẽ được tham chiếu bởi một đối tượng khác. Bạn nên thiết kế giao diện của bạn cho phù hợp. Quyền sở hữu là một hình thức ghép nối, nhưng nó thường là thiết kế chính xác. Nó chắc chắn đơn giản hóa giao diện của bạn, cũng như gánh nặng cho người gọi của bạn để duy trì các đối tượng của riêng họ.

Mặc dù phải biết và sử dụng thư viện thu thập thông tin. Biết thư viện sưu tập của bất kỳ ngôn ngữ/khung bạn đang sử dụng và sử dụng chúng.Ngoài ra, hãy cố gắng làm cho giao diện của riêng bạn phù hợp với các thư viện đó về mặt đặt tên và hành vi.

Về kiểm tra. Bạn có thể thực hiện kiểm tra (ghi nhật ký, lưu giữ số liệu thống kê) từ bên trong lớp học, nhưng nếu nhu cầu kiểm toán của bạn phức tạp (cần phải biết khi nào dữ liệu của bạn thay đổi), có thể sử dụng mẫu Observer tốt hơn.

2

Khi thiết kế phần mềm, tôi thấy hữu ích khi nhìn vào mọi thứ từ quan điểm lý thuyết loại và xem nó dẫn tôi đến đâu.

Một WorkSpace là dự án loại + Dự án^2 + Dự án^3 ... (có nghĩa là bất cứ điều gì là đúng của một danh sách các dự án là đúng của một WorkSpace)

Tương tự,

Một dự án là loại Resource + Resource^2 + Resource^3 ...

Một Resource là loại file + file^2 + Fil e^3 ...

Vì vậy, trong một ngôn ngữ như C# † bạn có thể xác định bạn WorkSpace lớp thusly:

public class WorkSpace : IList<Project> //the important thing here is that you're declaring that things that are true for a list of Projects is true for a WorkSpace. The WorkSpace class may in fact do other stuff too... 
{ 

} 

và tương tự cho các lớp khác.

Sau đó, trong mã khách hàng của bạn, bạn muốn sử dụng nó như thế này:

foreach (var project in WorkSpace) 
{ 
    //do stuff 
} 

hoặc

Projects.Add(new Resource() { file1, file2, file3, file4, /* etc */}); 

Hãy suy nghĩ về các loại và các mối quan hệ của họ đầu tiên. Đóng gói là một chút của một khái niệm vệ sinh cấp thấp. Nguyên tắc có để giữ mã liên quan gần nhau và mã không liên quan cách nhau xa nhau (cách xa nhau có nghĩa là tách biệt hoặc đằng sau một số loại ranh giới, ví dụ: hàm hoặc lớp hoặc bất kỳ khái niệm ranh giới nào khác có thể cung cấp).

† Từ lịch sử đăng của bạn, tôi phỏng đoán rằng bạn đã quen thuộc với C# nhưng điều này áp dụng cho các ngôn ngữ khác.

+2

+1 cho 'Không gian làm việc: IList 'cách tiếp cận. Không bao giờ tưởng tượng làm theo cách này. –

+3

Ưu tiên ngăn chặn để thừa kế ở đây. Một không gian làm việc không thực sự là một danh sách các dự án theo nghĩa là bạn sẽ muốn có thể thay thế một vùng làm việc ở mọi nơi bạn sử dụng một danh sách các dự án; và hơn nữa, một không gian làm việc có lẽ là một danh sách rất nhiều thứ khác nữa, như danh sách các thiết lập dự án và danh sách các sở thích của người dùng. Việc sử dụng ngăn chặn có nghĩa là đóng gói tốt hơn và giao diện đơn giản hơn cho người dùng của bạn. – nas

+0

@nstoertz Bạn có thể làm cho Workspace là một IList và IList cũng như kể từ khi bạn đang thực hiện một giao diện (mặc dù tôi có lẽ sẽ không thực hiện những giao diện khác). Tất cả những gì bạn đang nói là mọi thứ đúng với danh sách các dự án cũng đúng với WorkSpace nhưng những thứ đúng của WorkSpace có thể không đúng với danh sách các dự án. Ngoài ra, trong khi việc thực hiện kế thừa có thể nguy hiểm (và tôi muốn các lớp trừu tượng không được niêm phong theo mặc định), giao diện thừa kế khá an toàn và không gây tranh cãi. –

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