2008-12-04 29 views
10

Tôi hiểu rằng lập trình cho các giao diện sẽ giúp khớp nối lỏng lẻo. Tuy nhiên, có một hướng dẫn giải thích khi nào hiệu quả nhất? Ví dụ, tôi có một ứng dụng web đơn giản thu thập dữ liệu về nhân viên, kế hoạch đào tạo, chi phí và tính toán chi phí của họ trong năm vv Đây là một ứng dụng khá đơn giản và dĩ nhiên tôi có thể sử dụng giao diện nhưng tự hỏi liệu sẽ có bất kỳ việc sử dụng nào. Tôi sẽ sử dụng nó vì lợi ích của việc sử dụng nó.Lập trình cho giao diện. Làm thế nào để quyết định nơi cần thiết?

Nó luôn có thể được lập luận rằng khi ứng dụng phát triển phức tạp và tôi vượt qua các đối tượng, nó sẽ có ý nghĩa hơn để truyền loại (giao diện) hơn là thực hiện. Vậy, tôi có nên đợi ứng dụng trở nên phức tạp hoặc sử dụng nó ngay lập tức không? Tôi tự hỏi thực hành tốt nhất có thể hóa ra là "anh chàng này đang làm việc".

Trả lời

7

Lý do để lập trình cho giao diện là cách ly các lớp cấp cao hơn từ các thay đổi trong các lớp cấp thấp hơn. Nếu bạn không lường trước được một lớp cấp thấp hơn để thay đổi, thì nó hợp lý không phải để lập trình cho giao diện trong trường hợp đó. Điều này article (PDF) xây dựng trên ý tưởng, đặt ra thuật ngữ Nguyên tắc phụ thuộc-đảo ngược.

+0

Cảm ơn. Nó trông tương tự như DI của mùa xuân. – Shaw

3

Nếu có cơ hội tốt, ứng dụng sẽ trở nên phức tạp hơn, dễ dàng hơn để thiết lập giàn giáo sớm hơn là sau này. Tuy nhiên, nếu ứng dụng không phức tạp và có khả năng nó sẽ không trở nên phức tạp, ROI có thể không có ở đó. Bạn luôn có thể cấu trúc lại sau.

+0

Chính xác. Tôi có thể thiết lập phần giàn giáo để tránh việc không cần thiết sau này. Tuy nhiên, nó sẽ được gọi là một thực hành xấu - do sử dụng quá mức hoặc ứng dụng kém của một thực hành tốt? – Shaw

+0

Tôi nghĩ rằng đó là một cuộc gọi phán xét dựa trên những gì bạn đang thực hiện. Một ví dụ về nơi tôi sẽ nói để luôn luôn chương trình để giao diện là khi tạo một lớp DAO kể từ giao diện sẽ cho vay để sử dụng các nguồn dữ liệu khác nhau và tạo ra dữ liệu giả cho thử nghiệm đơn vị. – rich

1

Bạn phải xem giao diện dưới dạng hợp đồng. Hợp đồng này xác định bộ quy tắc và hoạt động cần được thực hiện bởi những người đã ký hợp đồng này, bất kể nó được thực hiện như thế nào.

4

Một ví dụ đơn giản mà mở mắt cho giao diện là này

class SimpleClass 
{ 
    public int A { get; set; } 
    public int B { get; set; } 
    public int C { get; set; } 
} 

List<SimpleClass> Calc(IEnumerable<SimpleClass> list) 
{ 
    foreach(SimpleClass item in list) 
    { 
    item.C = item.A * item.C: 
    } 
    return list.ToList(); 
} 

Thông báo các tham số đầu vào IEnumerable. Bằng cách sử dụng này tôi có thể vượt qua trong bất kỳ bộ sưu tập mà thực hiện IEnumerable như tham số trong. List<SimpleClass>, SimpleClass[], Collection<SimpleClass>. Giao diện IEnumerable đảm bảo với tôi rằng tôi có thể sử dụng vòng lặp foreach và cách này tôi đã thực hiện chức năng của mình chung hơn một chút và sẽ ít có cơ hội thay đổi mã này vì cơ hội thay đổi IEnumerable ít hơn f.ex. Liệt kê các thay đổi.

+0

Tôi biết các lợi ích có sẵn trong các loại và luôn cố gắng sử dụng chúng. Nhưng, tôi không chắc chắn về các loại tùy chỉnh - đặc biệt là câu hỏi của tôi là với nó. Cảm ơn câu trả lời và mã của bạn :) – Shaw

+0

Nguyên tắc cho việc sử dụng giao diện là hợp lệ đối với bạn đối với nhà phát triển thư viện .net, vì vậy nếu bạn hiểu tại sao họ sử dụng chúng, bạn sẽ hiểu tại sao và ở đâu bạn nên sử dụng chúng. Tất nhiên một khuôn khổ sẽ được hưởng lợi nhiều hơn từ các giao diện. – terjetyl

3

Lập trình cho giao diện trong ứng dụng đơn giản mà bạn không có kế hoạch thực hiện hoán đổi có thể có vẻ quá mức cần thiết.

Lần thứ hai bạn tham gia vào Bài kiểm tra đơn vị bạn sẽ rất vui khi được lập trình hướng tới các giao diện vì nó cho bạn khả năng dễ dàng giả lập đối tượng thực hơn với kiểm tra đôi.

+1

Rất đúng. Tôi thường nghe tuyên bố: "Không bao giờ sử dụng một giao diện trên một cái gì đó chỉ với một thực hiện". Vâng, khi bạn thử nghiệm đơn vị, bạn tạo ra một thực hiện thứ hai của các lớp bị đơn. Với một bộ kiểm tra đơn vị tốt, bạn LUÔN LUÔN có nhiều triển khai. –

7

Nếu bạn tự mình quan tâm đến Phát triển thử nghiệm, nhu cầu "lập trình cho một giao diện" thực sự trở nên rõ ràng. Nếu bạn muốn một lớp được kiểm tra trong sự cô lập các phụ thuộc của nó, bạn cần phải truyền xung quanh các giao diện thay vì các đối tượng.

+0

Đây là lý do chính tôi tránh được sự phát triển theo hướng thử nghiệm. Trên khuôn mặt của nó, TDD là một ý tưởng tuyệt vời, nhưng tôi nghĩ rằng chi phí là quá cao, vì nó đòi hỏi kiến ​​trúc quá mức của hầu hết các lớp ứng dụng. – benjismith

+0

Đây là nơi tôi không đồng ý. Phạm vi kiểm tra của tôi là rất cao và các lớp học của tôi rất tốt decoupled rằng tôi buộc phải suy nghĩ về thiết kế tốt lên phía trước một cách rất thực tế. Nó tạo ra một kiến ​​trúc mô-đun, mở rộng hơn, có đủ các kiểm tra để nó vẫn mạnh mẽ. Tôi hiếm khi viết lỗi nữa. –

1

Tôi thường nghĩ theo cách này - chỉ có hai điều mà tách một giao diện từ một thực hiện:

  1. Một đối tượng có thể kế thừa từ nhiều giao diện, nhưng chỉ có một lớp cơ sở;
  2. Giao diện không cho phép triển khai mặc định trong khi lớp cơ sở thực hiện.

Bây giờ hãy nghĩ về các đối tượng sẽ kế thừa từ "cấu trúc" của bạn. Điều gì sẽ quan trọng hơn đối với họ? Liệu chúng có được hưởng lợi nhiều nhất từ ​​việc triển khai mặc định các phương thức hay không, hay nó sẽ tốt hơn nếu chúng có thể có các lớp cơ sở khác?

Trong hầu hết các trường hợp, điều này khá rõ ràng đó là yếu tố quan trọng nhất. Nếu bạn tình cờ ở trên đường dây mỏng ... sự may mắn khó khăn. Microsoft recommends các lớp cơ sở trên giao diện.

1

Đối với bất kỳ thứ gì là một phần của API, cho dù khách hàng bên ngoài hoặc các nhóm khác sử dụng lại mã của bạn, hãy sử dụng giao diện nhiều nhất có thể. Đó là giá trị nó, bởi vì nó ẩn càng nhiều càng tốt về cách triển khai của bạn làm việc và cung cấp cho bạn tự do hơn để tăng cường chúng trong tương lai. Chỉ phơi bày một lớp bê tông nhỏ (có lẽ là tĩnh) mà từ đó các thể hiện có thể thu được.

Đối với các bộ phận bên trong thiết kế, bạn có tùy chọn bắt đầu với tham chiếu lớp bê tông ở mọi nơi và chỉ giới thiệu các giao diện có ý nghĩa đối với thiết kế.

Nhưng điều quan trọng khác cần xem xét là thử nghiệm đơn vị. Bạn hoàn toàn có thể "chế giễu" một giao diện trong CLR mà không gặp khó khăn về kỹ thuật, nhưng chế nhạo những thứ khác là không thể hoặc sẽ yêu cầu một số thủ thuật nghiêm trọng. Vì vậy, một kỷ luật cần xem xét là phát triển thử nghiệm: viết các bài kiểm tra cho mã của bạn khi bạn làm theo, và bạn sẽ khám phá ra rằng bạn cần một số thứ nhất định được thể hiện bằng giao diện để bạn có thể cung cấp các phiên bản giả của chúng.

1

Nếu bạn muốn có thể kiểm tra ứng dụng của mình và không phải sử dụng (và sau đó không phải xây dựng) đối tượng nhân viên đầy đủ, bạn có thể tạo giao diện IEmployee và sau đó tạo nhân viên thử nghiệm thân thiện với trọng lượng nhẹ đối tượng để kiểm tra. Đó có thể là một lợi ích lớn nếu tạo ra một nhân viên là khó khăn hoặc thậm chí không thể làm bằng tay hoặc không có cơ sở dữ liệu.

Một lý do chính đáng khác là nó giúp bạn xác định chính xác những gì bạn đang phụ thuộc vào trong lớp nhân viên của bạn. Bạn có thể nghĩ rằng bạn chỉ sử dụng một vài phương pháp công cộng, nhưng sau đó phát hiện ra rằng bạn đang sử dụng 10 phương pháp và chúng được kết hợp chặt chẽ hơn bạn nghĩ. Cuối cùng, nếu bạn cần thay đổi mã của bạn để sử dụng SuperEmployee thay vì Employee, nếu bạn đã sử dụng các giao diện thì tất cả những gì bạn cần làm là để SuperEmployee triển khai IEmployee và bạn sẽ được thiết lập.

1

Hãy duyệt qua cuốn sách Mẫu thiết kế đầu tiên ... bạn sẽ thấy các đối số tốt cho việc sử dụng giao diện không liên quan gì tới TDD hoặc đa hình.

Giao diện cho phép bạn thay đổi hành vi của đối tượng trong thời gian chạy ... Hãy nghĩ về những nơi bạn cần một trình xử lý cho một hành vi cụ thể, nhưng có thể không biết hành vi nào là cần thiết cho đến khi chạy. Trong trường hợp chi phí máy tính cho nhân viên ... Người quản lý có thể có mức phụ cấp 'giải trí' cao hơn so với nhân viên thông thường.

Nếu đối tượng nhân viên của bạn có tham chiếu đến giao diện IExpenseCalculator, bạn có thể gán cho nó máy tính của người quản lý hoặc máy tính của nhân viên khi chạy. Gọi Employee.GetExpenses() sẽ cung cấp cho bạn một kết quả được tính toán khác cho người quản lý so với một nhân viên thông thường. Bên trong, các mã sẽ trông như thế này:

public class Employee { 
    private IExpenseCalculator expenses; 

    public ExpenseSheet GetExpenses() { 
    return expenses.CalcExpenses(); 
    } 
} 

dụ này giả định rằng 'chi phí' được tiếp xúc như một tài sản, và rằng IExpenseCalculator có một phương pháp để CalcExpenses().

Giao diện cũng gắn liền với khái niệm nhà máy đối tượng ... nghĩ lớp cơ sở dữ liệu. Khi bạn đã định cấu hình lớp dữ liệu của mình làm nhà máy, bạn có thể tạo các đối tượng để kết nối với Sql Server, Oracle hoặc MySql động, vào thời gian chạy, dựa trên các cài đặt cấu hình. Nhưng khách hàng cần một xử lý cụ thể cho đối tượng lớp cơ sở dữ liệu ... nhập Giao diện.

Giao diện là một công cụ mạnh mẽ, một công cụ thường bị lạm dụng. Sử dụng chúng đúng cách sẽ thay đổi cách suy nghĩ của bạn, nhưng có thể giúp cấu trúc ứng dụng của bạn rất nhiều.

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