Lập trình giao diện hướng dữ liệu


9

Có một phần cơ sở mã của chúng tôi được viết theo phong cách sau:

// IScheduledTask.cs
public interface IScheduledTask
{
    string TaskName { get; set; }
    int TaskPriority { get; set; }
    List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein
}

// ScheduledTaskImpl.cs
public class ScheduledTaskImpl : IScheduledTask
{
    public string TaskName { get; set; }
    public int TaskPriority { get; set; }
    public List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein, 
    // perhaps a constructor or two for convenience.
}

Đó là, có một số lượng lớn các giao diện chỉ định một tập các thuộc tính không có hành vi nào với mỗi thực hiện tương ứng duy nhất thực hiện các giao diện này với các thuộc tính tự động. Mã được viết bởi một người khá cao cấp (nhiều hơn tôi) và ngoài việc sử dụng giao diện mã thủ tục hợp lý này. Tôi đã tự hỏi nếu có ai khác đã gặp / sử dụng phong cách này và liệu nó có bất kỳ lợi thế nào so với việc chỉ sử dụng các DTO cụ thể ở mọi nơi mà không có giao diện.


1
Một lý do tôi đã làm đó là vì khả năng tương thích COM, nhưng dường như đó không phải là lý do của bạn ở đây.
Mike hỗ trợ Monica

@Mike Thú vị, tôi chưa bao giờ sử dụng COM và nó không được sử dụng ở đây. Tôi sẽ hỏi tác giả của phần mã này xem anh ta có định sử dụng COM hay không.
walpen

Tôi đoán là anh ta hy vọng sẽ tạo ra ít nhất một trong số những tính chất đó không phải là tự động trong tương lai gần, và viết ra cái nồi hơi này khi bắt đầu là một thói quen mà anh ta có được để tiết kiệm thời gian sau đó, mặc dù tôi không phải là một anh chàng C # vì vậy đó là tất cả những gì tôi có thể nói.
Ixrec

6
IMHO đó là nỗi ám ảnh quá mức và việc áp dụng sai mã cho các giao diện không được triển khai . Một câu chuyện quan trọng là việc thực hiện duy nhất . Điểm của các giao diện là đa hình nhưng một lớp chỉ thuộc tính là đa hình theo nghĩa đơn giản là có các giá trị khác nhau. Ngay cả với hành vi - phương thức - không có điểm nào cho nó được thực hiện. Điều vô lý này là trên tất cả các cơ sở mã của chúng tôi và tốt nhất là nó cản trở bảo trì. Tôi lãng phí quá nhiều thời gian để hỏi tại sao, cái gì và ở đâu. Tại sao họ làm điều đó, tôi không thấy thiết kế nào, và các triển khai khác ở đâu?
radarbob

2
Hầu hết các ý kiến ​​tiền đề đi đến việc thực hiện "mùi mã" duy nhất của sự trừu tượng hóa sớm; tuy nhiên, cũng có một mô hình miền thiếu máu "mùi mã" ở đây, xem: martinfowler.com/bliki/AnemiaDomainModel.html
Erik Eidt

Câu trả lời:


5

Đây là hai xu của tôi:

  • Chúng tôi không chắc chắn một DTO sẽ không bao giờ có ít nhất một chút hành vi. Vì vậy, đối với tôi có những đối tượng có thể có hoặc không có hành vi trong tương lai.
  • Một nguyên nhân có thể của việc có rất nhiều lớp học duy nhất-thực hiện là một thiếu thiết kế , ví dụ thất bại để thấy rằng ScheduledTask, ScheduledJob, ScheduledEvent, ScheduledInspection, vv, nên chỉ có một tách biệt Schedulablegiao diện thực hiện bất kỳ schedulable implementor.
  • Tạo các giao diện đầu tiên là một thực hành rất tốt, nó cung cấp cho bạn cái nhìn sâu sắc về những gì bạn cần. Nhiều giao diện bắt đầu bằng cách không có triển khai nào cả. Sau đó, một người nào đó viết một thực hiện và họ có cái đó. Tình trạng có một triển khai duy nhất là tạm thời nếu bạn tránh những gì tôi đề cập trong điểm thứ hai. Làm thế nào để bạn biết trước rằng một số giao diện sẽ không bao giờ có lần thứ hai thực hiện thứ ba?
  • Tên chúng tôi chọn cho giao diện được suy nghĩ kỹ có xu hướng không thay đổi trong tương lai, vì vậy phụ thuộc vào giao diện đó sẽ không bị ảnh hưởng. Mặt khác, một lớp cụ thể dễ bị đổi tên khi một thứ quan trọng trong cách thực hiện thay đổi, ví dụ một lớp cụ TaxSheetthể có tên có thể thay đổi SessionAwareTaxSheetvì một đại tu đáng kể đã được thực hiện nhưng giao diện ITaxSheetcó thể sẽ không được đổi tên dễ dàng như vậy.

Dòng dưới cùng:

  • Thực hành thiết kế tốt cũng áp dụng cho DTOs.
  • DTO có thể được thêm một chút hành vi xuống đường.
  • Mỗi giao diện bắt đầu bằng cách chỉ có một thực hiện.
  • Mặt khác, nếu bạn có quá nhiều combo một giao diện một lớp, có thể thiếu thiết kế nên được chỉ ra. Preocupation của bạn có thể được biện minh .

4
Tôi nêu lên câu trả lời của bạn, nhưng viên đạn thứ hai của bạn ngụ ý rằng tất cả các lớp sẽ tự động có giao diện tương ứng, một vị trí mà tôi chưa bao giờ đồng ý. Viết các giao diện không có khả năng bạn có thể thực hiện lần thứ hai chỉ gây ra sự phổ biến giao diện và YAGNI.
Robert Harvey

1

Một vấn đề cụ thể tôi đã thấy với các DTO sử dụng giao diện là nó cho phép điều này:

public interface ISomeDTO { string SomeProperty { get; set; }}

public class SomeDTO : ISomeDTO
{
    public string SomeProperty { get; set; }
    string ISomeDTO.SomeProperty { get { /* different behavior */ } set { SomeProperty = value; } }
}

Tôi đã thấy mô hình này được áp dụng như một bản hack nhanh, bẩn để thực hiện một số hành vi quan trọng. Điều này dẫn đến mã có thể có hành vi rất khó hiểu:

SomeDTO a = GetSomeDTO();
ISomeDTO ia = a;
Assert.IsTrue(a.SomeProperty == ia.SomeProperty); // assert fails!

Điều này rất khó để duy trì và gây nhầm lẫn khi cố gắng gỡ rối hoặc tái cấu trúc. IMO, việc thêm hành vi vào DTO vi phạm nguyên tắc trách nhiệm duy nhất. Mục đích của DTO là thể hiện dữ liệu theo định dạng có thể được duy trì và phổ biến bởi một khung kiên trì.

DTO không phải là mô hình miền. Chúng ta không nên lo lắng nếu DTO bị thiếu máu. Để trích dẫn cuộc thảo luận của Martin Fowler về mô hình miền thiếu máu :

Cũng đáng nhấn mạnh rằng việc đưa hành vi vào các đối tượng miền không được mâu thuẫn với cách tiếp cận vững chắc của việc sử dụng phân lớp để tách logic miền khỏi những thứ như sự kiên trì và trách nhiệm trình bày.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.