Vấn đề đặt tên: Có nên đổi tên thành một thứ gì đó hay không? [đóng cửa]


68

Chương của chú Bob về các tên trong Clean Code khuyên bạn nên tránh mã hóa tên, chủ yếu liên quan đến ký hiệu Hungary. Ông cũng đặc biệt đề cập đến việc loại bỏ Itiền tố khỏi các giao diện, nhưng không hiển thị các ví dụ về điều này.

Hãy giả sử như sau:

  • Sử dụng giao diện chủ yếu là để đạt được khả năng kiểm tra thông qua tiêm phụ thuộc
  • Trong nhiều trường hợp, điều này dẫn đến việc có một giao diện với một người thực hiện

Vì vậy, ví dụ, hai cái này nên được đặt tên là gì? ParserConcreteParser? ParserParserImplementation?

public interface IParser {
    string Parse(string content);
    string Parse(FileInfo path);
}

public class Parser : IParser {
     // Implementations
}

Hoặc tôi nên bỏ qua đề xuất này trong các trường hợp thực hiện đơn lẻ như thế này?


30
Điều đó không làm cho nó ít hơn một tôn giáo. Bạn phải tìm lý do, không chỉ ai đó X nói Y.
Mike Dunlavey

35
@MikeDunlavey Và đó là lý do cho câu hỏi!
Vinko Vrsalovic

14
Nếu có một bộ mã hiện có (mà bạn sẽ không viết lại), thì hãy tuân theo bất kỳ quy ước nào mà nó sử dụng. Nếu mã mới, hãy sử dụng bất cứ thứ gì mà phần lớn những người sẽ làm việc với nó là hạnh phúc nhất với / đã từng sử dụng. Chỉ khi không áp dụng ở trên, nó sẽ trở thành một câu hỏi triết học.
TripeHound

9
@TripeHound Quy tắc đa số không phải lúc nào cũng là lựa chọn tốt nhất. Nếu có lý do một số điều tốt hơn những người khác, một người duy nhất có thể thuyết phục những người còn lại trong nhóm đưa ra một trường hợp dựa trên những lý do đó. Chỉ mù quáng phục tùng đa số mà không đánh giá mọi thứ thông qua dẫn đến trì trệ. Tôi thấy từ các câu trả lời rằng đối với trường hợp cụ thể này, không có lý do chính đáng nào để loại bỏ Is, nhưng điều đó không vô hiệu khi đã hỏi ngay từ đầu.
Vinko Vrsalovic

35
Cuốn sách "Chú Bob" tập trung vào JAVA, không phải C #. Hầu hết các mô hình đều giống với C #, nhưng một số quy ước đặt tên khác nhau (cũng xem xét các tên hàm lowCamelCase trong Java). Khi bạn viết bằng C #, hãy sử dụng quy ước đặt tên C #. Nhưng dù sao đi nữa, hãy làm theo điểm chính của chương của anh ấy về cách đặt tên: tên dễ đọc truyền đạt ý nghĩa của vật phẩm!
Bernhard Hiller

Câu trả lời:


191

Trong khi nhiều người, bao gồm cả "Chú Bob", khuyên không nên sử dụng Ilàm tiền tố cho các giao diện, thì làm như vậy là một truyền thống được thiết lập tốt với C #. Nói chung, nên tránh. Nhưng nếu bạn đang viết C #, bạn thực sự nên tuân theo các quy ước của ngôn ngữ đó và sử dụng nó. Không làm như vậy sẽ gây ra sự nhầm lẫn lớn với bất kỳ ai khác quen thuộc với C #, những người cố gắng đọc mã của bạn.


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
maple_shaft

9
Bạn không cung cấp cơ sở cho "Nói chung, nên tránh". Trong Java, tôi nên tránh. Trong C # nên được chấp nhận. Các ngôn ngữ khác tuân theo quy ước riêng của họ.
Cơ bản

4
Nguyên tắc "nói chung" rất đơn giản: Một khách hàng có quyền thậm chí không biết liệu nó đang nói đến một giao diện hay một triển khai. Cả hai ngôn ngữ đều sai. C # có quy ước đặt tên sai. Java có mã byte sai. Nếu tôi chuyển đổi một triển khai sang một giao diện có cùng tên trong Java, tôi phải biên dịch lại tất cả các máy khách mặc dù tên và phương thức không thay đổi. Đó không phải là "chọn chất độc của bạn". Chúng tôi đã làm sai. Vui lòng học hỏi từ điều này nếu bạn đang tạo một ngôn ngữ mới.
candied_orange

39

Giao diện là khái niệm logic quan trọng, do đó, giao diện phải mang tên chung. Vì vậy, tôi muốn có

interface Something
class DefaultSomething : Something
class MockSomething : Something

hơn

interface ISomething
class Something : ISomething
class MockSomething : ISomething

Cái sau có một số vấn đề:

  1. Một cái gì đó chỉ là một triển khai của IS Something, nhưng nó là cái có tên chung, như thể nó đặc biệt.
  2. MockS Something dường như bắt nguồn từ Something, nhưng thực hiện IS Something. Có lẽ nó nên được đặt tên là MockIS Something, nhưng tôi chưa bao giờ thấy điều đó trong tự nhiên.
  3. Tái cấu trúc là khó hơn. Nếu một cái gì đó bây giờ là một lớp và bạn chỉ phát hiện ra rằng bạn phải giới thiệu một giao diện, giao diện đó nên được đặt tên giống nhau, bởi vì nó phải trong suốt cho khách hàng cho dù loại đó là một lớp cụ thể, một lớp trừu tượng hay một giao diện . Một cái gì đó phá vỡ điều đó.

59
Tại sao bạn không tuân theo tiêu chuẩn được thiết lập tốt mà C # cung cấp? Điều này mang lại lợi ích gì cho việc vượt quá chi phí gây nhầm lẫn và khó chịu cho mọi lập trình viên C # theo bạn?
Robert Harvey

6
@wallenborn Điều đó tốt, nhưng thực tế bạn thường chỉ có một triển khai hợp pháp duy nhất cho một giao diện, bởi vì nó thường được sử dụng các giao diện cho tính nhạo báng trong các bài kiểm tra đơn vị. Tôi không muốn đặt Defaulthoặc Realhoặc Impltrong rất nhiều các tên lớp học của tôi
Ben Aaronson

4
Tôi đồng ý với bạn, nhưng nếu bạn đi trên con đường này, bạn sẽ phải chiến đấu với mọi kẻ nói dối từng làm cho C #.
RubberDuck

3
Tôi thấy không có vấn đề gì với việc có một lớp khả thi có cùng tên với một giao diện nếu phần lớn các trường hợp thực hiện giao diện sẽ là lớp đó. Ví dụ, rất nhiều mã cần triển khai mục đích chung đơn giản IList<T>và không thực sự quan tâm đến việc nó được lưu trữ nội bộ như thế nào; có thể chỉ cần Isử dụng và có một tên lớp có thể sử dụng có vẻ đẹp hơn là phải biết một cách kỳ diệu (như trong Java) rằng mã muốn triển khai thông thường List<T>nên sử dụng ArrayList<T>.
supercat

2
@ArtB Vài lý do. Một, không có ngôn ngữ mà hội nghị là một điểm đánh dấu ngắn đẹp trên lớp như thế nào CFoo : Foo. Vì vậy, tùy chọn đó không thực sự có sẵn. Hai, sau đó bạn nhận được một sự mâu thuẫn kỳ lạ bởi vì một số lớp sẽ có điểm đánh dấu và những lớp khác thì không, tùy thuộc vào việc có thể có các triển khai khác của cùng một giao diện hay không. CFoo : Foonhưng SqlStore : Store. Đó là một vấn đề tôi gặp phải Impl, về cơ bản chỉ là một điểm đánh dấu xấu hơn. Có lẽ nếu có một ngôn ngữ với quy ước luôn luôn thêm C(hoặc bất cứ thứ gì), thì có thể tốt hơnI
Ben Aaronson

27

Đây không chỉ là về quy ước đặt tên. C # không hỗ trợ nhiều kế thừa, do đó, việc sử dụng ký hiệu Hungary này có một lợi ích nhỏ dù bạn đang thừa hưởng từ một lớp cơ sở và thực hiện một hoặc nhiều giao diện. Vậy đây ...

class Foo : BarB, IBarA
{
    // Better...
}

... thích hơn thế này ...

class Foo : BarB, BarA
{
    // Dafuq?
}

IMO


7
Điều đáng chú ý là Java tránh được vấn đề này một cách gọn gàng bằng cách sử dụng các từ khóa khác nhau để kế thừa lớp và triển khai giao diện, tức là inheritsso với implements.
Konrad Rudolph

6
@KonradRudolph ý bạn là extends.
OrangeDog

2
@Andy Giá trị gia tăng là chúng ta có thể tránh được hành trình ký hiệu Hungary, nhưng vẫn giữ được tất cả sự rõ ràng được chào hàng trong câu trả lời này.
Konrad Rudolph

2
Thực sự không nên có bất kỳ sự nhầm lẫn nào; nếu bạn kế thừa một lớp, nó PHẢI đứng đầu trong danh sách, trước danh sách các giao diện được triển khai. Tôi khá chắc chắn rằng điều này được thực thi bởi trình biên dịch.
Andy

1
@Andy ... nếu bạn kế thừa một lớp, nó phải đứng đầu trong danh sách Điều đó thật tuyệt nhưng không có tiền tố bạn sẽ không biết nếu bạn đang xử lý một vài giao diện hoặc một lớp cơ sở và một giao diện ...
Robbie Dee

15

Không không không.

Các quy ước đặt tên không phải là một chức năng của fandom chú Bob của bạn. Chúng không phải là một chức năng của ngôn ngữ, c # hoặc cách khác.

Chúng là một chức năng của cơ sở mã của bạn. Ở một mức độ thấp hơn nhiều của cửa hàng của bạn. Nói cách khác, cái đầu tiên trong cơ sở mã đặt tiêu chuẩn.

Chỉ sau đó bạn có thể quyết định. Sau đó chỉ cần nhất quán. Nếu ai đó bắt đầu không nhất quán hãy lấy đi súng nerf của họ và khiến họ cập nhật tài liệu cho đến khi họ hối cải.

Khi đọc một cơ sở mã mới nếu tôi không bao giờ thấy Itiền tố tôi ổn, bất kể ngôn ngữ. Nếu tôi thấy một cái trên mọi giao diện thì tôi ổn. Nếu tôi đôi khi nhìn thấy một, ai đó sẽ trả tiền.

Nếu bạn thấy mình trong bối cảnh hiếm hoi của việc thiết lập tiền lệ này cho cơ sở mã của bạn, tôi khuyên bạn nên xem xét điều này:

Là một lớp khách hàng, tôi có quyền không nói những gì tôi đang nói. Tất cả những gì tôi cần là một cái tên và một danh sách những thứ tôi có thể gọi với cái tên đó. Những điều đó có thể không thay đổi trừ khi tôi nói như vậy. Tôi sở hữu phần đó. Những gì tôi đang nói, giao diện hay không, không phải là bộ phận của tôi.

Nếu bạn lẻn Ivào tên đó, khách hàng không quan tâm. Nếu không có I, khách hàng không quan tâm. Những gì nó đang nói có thể là cụ thể. Nó có thể không. Vì nó không gọi newnó theo bất kỳ cách nào nó làm cho không có sự khác biệt. Là khách hàng, tôi không biết. Tôi không muốn biết.

Bây giờ là một con khỉ mã nhìn vào mã đó, ngay cả trong java, điều này có thể quan trọng. Rốt cuộc, nếu tôi phải thay đổi một triển khai thành một giao diện, tôi có thể làm điều đó mà không cần nói với khách hàng. Nếu không có Itruyền thống tôi thậm chí không thể đổi tên nó. Đó có thể là một vấn đề vì bây giờ chúng tôi phải biên dịch lại máy khách vì mặc dù nguồn không quan tâm đến nhị phân. Một cái gì đó dễ bỏ lỡ nếu bạn không bao giờ thay đổi tên.

Có lẽ đó không phải là vấn đề với bạn. Có thể không. Nếu có, đó là một lý do tốt để quan tâm. Nhưng đối với tình yêu của đồ chơi bàn không yêu cầu chúng ta chỉ nên mù quáng làm điều này bởi vì đó là cách nó được thực hiện trong một số ngôn ngữ. Hoặc có một lý do tốt chết tiệt hoặc không quan tâm.

Nó không phải là sống với nó mãi mãi. Đó là về việc không cho tôi tào lao về cơ sở mã không tuân theo tâm lý cụ thể của bạn trừ khi bạn chuẩn bị khắc phục "sự cố" ở mọi nơi. Trừ khi bạn có lý do chính đáng, tôi không nên đi theo con đường ít kháng cự nhất đối với tính đồng nhất, đừng đến với tôi để giảng về sự phù hợp. Tôi có nhiều thứ tốt hơn để làm.


6
Tính nhất quán là chìa khóa, nhưng trong một ngôn ngữ được gõ tĩnh và với các công cụ tái cấu trúc hiện đại là khá dễ dàng và an toàn để thay đổi tên. Vì vậy, nếu nhà phát triển đầu tiên đưa ra một lựa chọn tồi trong việc đặt tên, bạn không phải sống với nó mãi mãi. Nhưng bạn có thể thay đổi cách đặt tên trong cơ sở mã của riêng bạn, nhưng bạn không thể thay đổi nó trong khung hoặc thư viện của bên thứ ba. Vì tiền tố I (thích hay không) là một quy ước được thiết lập trên toàn thế giới .net, tốt hơn là nên tuân theo quy ước hơn là không tuân theo nó.
JacquesB

Nếu bạn đang sử dụng C #, bạn sẽ thấy những cái Iđó. Nếu mã của bạn sử dụng chúng, bạn sẽ thấy chúng ở mọi nơi. Nếu mã của bạn không sử dụng chúng, bạn sẽ thấy chúng từ mã khung, dẫn chính xác đến hỗn hợp bạn không muốn.
Sebastian Redl

8

Có một sự khác biệt nhỏ giữa Java và C # có liên quan ở đây. Trong Java, mọi thành viên đều là ảo theo mặc định. Trong C #, mọi thành viên đều được niêm phong theo mặc định - ngoại trừ các thành viên giao diện.

Các giả định đi kèm với điều này ảnh hưởng đến hướng dẫn - trong Java, mọi loại công khai nên được coi là không phải là cuối cùng, theo Nguyên tắc thay thế của Liskov [1]. Nếu bạn chỉ có một triển khai, bạn sẽ đặt tên cho lớp Parser; nếu bạn thấy rằng bạn cần nhiều triển khai, bạn sẽ chỉ cần thay đổi lớp thành một giao diện có cùng tên và đổi tên triển khai cụ thể thành một mô tả.

Trong C #, giả định chính là khi bạn nhận được một lớp (tên không bắt đầu bằng I), đó là lớp bạn muốn. Xin lưu ý bạn, đây không phải là chính xác gần 100% - một ví dụ điển hình sẽ là các lớp như Stream(mà thực sự phải là một giao diện, hoặc một vài giao diện), và mọi người đều có hướng dẫn và nền tảng riêng từ các ngôn ngữ khác. Ngoài ra còn có các trường hợp ngoại lệ khác như Basehậu tố được sử dụng khá rộng rãi để biểu thị một lớp trừu tượng - giống như với một giao diện, bạn biết loại được cho là đa hình.

Ngoài ra còn có một tính năng tiện dụng tuyệt vời khi để lại tên không có tiền tố I cho chức năng liên quan đến giao diện đó mà không phải dùng đến việc biến giao diện thành một lớp trừu tượng (sẽ bị tổn thương do thiếu tính kế thừa nhiều lớp trong C #). Điều này đã được phổ biến bởi LINQ, sử dụng IEnumerable<T>làm giao diện và Enumerablelà kho lưu trữ các phương thức áp dụng cho giao diện đó. Điều này là không cần thiết trong Java, nơi các giao diện cũng có thể chứa các triển khai phương thức.

Cuối cùng, Itiền tố được sử dụng rộng rãi trong thế giới C # và bằng cách mở rộng, thế giới .NET (vì phần lớn mã .NET được viết bằng C #, nên tuân theo hướng dẫn C # cho hầu hết các giao diện công cộng). Điều này có nghĩa là bạn gần như chắc chắn sẽ làm việc với các thư viện và mã theo ký hiệu này và việc áp dụng truyền thống để ngăn ngừa sự nhầm lẫn không cần thiết - không giống như bỏ qua tiền tố sẽ giúp mã của bạn trở nên tốt hơn :)

Tôi cho rằng lý luận của chú Bob là như thế này:

IBananalà khái niệm trừu tượng của chuối. Nếu có thể có bất kỳ lớp triển khai nào không có tên nào tốt hơn Banana, thì sự trừu tượng hóa là hoàn toàn vô nghĩa, và bạn nên bỏ giao diện và chỉ sử dụng một lớp. Nếu có một tên tốt hơn (giả sử, LongBananahoặc AppleBanana), không có lý do gì để không sử dụng Bananalàm tên của giao diện. Do đó, việc sử dụng Itiền tố biểu thị rằng bạn có một sự trừu tượng hóa vô dụng, điều này làm cho mã khó hiểu hơn mà không có lợi ích. Và vì OOP nghiêm ngặt sẽ giúp bạn luôn mã hóa các giao diện, nên nơi duy nhất bạn không thấy Itiền tố trên một loại sẽ là trên một hàm tạo - tiếng ồn khá vô nghĩa.

Nếu bạn áp dụng điều này cho IParsergiao diện mẫu của mình , bạn có thể thấy rõ rằng sự trừu tượng hoàn toàn nằm trong lãnh thổ "vô nghĩa". Hoặc là có điều gì đó cụ thể về việc thực hiện cụ thể của một phân tích cú pháp (ví dụ JsonParser, XmlParser...), hoặc bạn chỉ nên sử dụng một lớp. Không có thứ gọi là "triển khai mặc định" (mặc dù trong một số môi trường, điều này thực sự có ý nghĩa - đáng chú ý là COM), hoặc có một triển khai cụ thể hoặc bạn muốn có một lớp trừu tượng hoặc các phương thức mở rộng cho "mặc định". Tuy nhiên, trong C #, trừ khi cơ sở mã của bạn đã bỏ qua I-prefix, hãy giữ nó. Chỉ cần ghi chú tinh thần mỗi khi bạn thấy mã như thế class Something: ISomething- điều đó có nghĩa là ai đó không giỏi làm theo YAGNI và xây dựng trừu tượng hợp lý.

[1] - Về mặt kỹ thuật, điều này không được đề cập cụ thể trong bài viết của Liskov, nhưng nó là một trong những nền tảng của bài báo OOP gốc và trong bài đọc về Liskov của tôi, cô ấy đã không thách thức điều này. Theo cách hiểu ít nghiêm ngặt hơn (một ngôn ngữ được sử dụng bởi hầu hết các ngôn ngữ OOP), điều này có nghĩa là bất kỳ mã nào sử dụng loại công khai nhằm thay thế (tức là không phải là cuối cùng / niêm phong) phải hoạt động với bất kỳ triển khai tuân thủ nào của loại đó.


3
Nitpick: LSP không nói rằng mọi loại nên không phải là cuối cùng. Nó chỉ nói rằng với nhiều loại đó không chính thức, người tiêu dùng phải có khả năng sử dụng các lớp con một cách minh bạch. - Và tất nhiên Java cũng có các loại cuối cùng.
Konrad Rudolph

@KonradRudolph Tôi đã thêm một chú thích về điều này; cảm ơn vì đã phản hồi :)
Luaan 24/8/2016

4

Vì vậy, ví dụ, hai cái này nên được đặt tên là gì? Trình phân tích cú pháp và ConcreteParser? Trình phân tích cú pháp và Trình phân tích cú pháp?

Trong một thế giới lý tưởng, bạn không nên đặt tiền tố tên của mình bằng một tay ngắn ("Tôi ...") mà chỉ để tên thể hiện một khái niệm.

Tôi đã đọc ở đâu đó (và không thể cung cấp nó) ý kiến ​​rằng quy ước IS Something này dẫn bạn xác định khái niệm "IDollar" khi bạn cần một lớp "Dollar", nhưng giải pháp chính xác sẽ là một khái niệm gọi đơn giản là "Tiền tệ".

Nói cách khác, quy ước đưa ra một cách dễ dàng cho những khó khăn trong việc đặt tên và những điều dễ hiểu là sai một cách tinh tế .


Trong thế giới thực, các khách hàng của mã của bạn (có thể là "bạn đến từ tương lai") cần có thể đọc nó sau và làm quen với nó càng nhanh (hoặc càng ít nỗ lực) càng tốt (cung cấp cho khách hàng mã của bạn những gì họ mong đợi để có được).

Công ước IS Something, giới thiệu tên cruft / bad. Điều đó nói rằng, cruft không phải là cruft thực *), trừ khi các quy ước và thực tiễn được sử dụng trong việc viết mã không còn thực tế nữa; nếu quy ước nói "sử dụng IS Something", thì tốt nhất là sử dụng nó, để phù hợp (và hoạt động tốt hơn) với các nhà phát triển khác.


*) Tôi có thể thoát khỏi việc nói rằng "cruft" này không phải là một khái niệm chính xác nào :)


2

Như các câu trả lời khác đề cập, tiền tố tên giao diện của bạn Ilà một phần của hướng dẫn mã hóa cho khung .NET. Vì các lớp cụ thể thường được tương tác nhiều hơn so với các giao diện chung trong C # và VB.NET, nên chúng là lớp đầu tiên trong các sơ đồ đặt tên và do đó nên có các tên đơn giản nhất - do đó, IParsercho giao diện và Parsercho việc triển khai mặc định.

Nhưng trong trường hợp Java và các ngôn ngữ tương tự, nơi các giao diện được ưa thích thay vì các lớp cụ thể, chú Bob đã đúng ở chỗ Icần loại bỏ và các giao diện nên có tên đơn giản nhất - Parserví dụ như giao diện trình phân tích cú pháp của bạn. Nhưng thay vì một tên dựa trên vai trò như thế ParserDefault, lớp nên có một tên mô tả cách trình phân tích cú pháp được triển khai :

public interface Parser{
}

public class RegexParser implements Parser {
    // parses using regular expressions
}

public class RecursiveParser implements Parser {
    // parses using a recursive call structure
}

public class MockParser implements Parser {
    // BSes the parsing methods so you can get your tests working
}

Đây là, ví dụ, làm thế nào Set<T>, HashSet<T>TreeSet<T>được đặt tên.


5
Các giao diện cũng được ưu tiên trong C #. Bất cứ ai nói với bạn rằng nó được ưa thích sử dụng các loại bê tông trong dotnet?
RubberDuck

@RubberDuck Nó ẩn trong một số giả định mà ngôn ngữ áp đặt cho bạn. Ví dụ, thực tế là các thành viên sealedtheo mặc định và bạn phải làm cho họ rõ ràng virtual. Là ảo là trường hợp đặc biệt trong C #. Tất nhiên, vì cách tiếp cận được đề xuất để viết mã đã thay đổi qua nhiều năm, nhiều di tích của quá khứ cần để duy trì tính tương thích :) Điểm quan trọng là nếu bạn có giao diện trong C # (bắt đầu bằng I), bạn biết đó hoàn toàn là một giao diện loại trừu tượng; nếu bạn nhận được một giao diện không có giao diện, giả định điển hình là đó là loại bạn muốn, LSP bị nguyền rủa.
Luaan

1
Các thành viên được niêm phong theo mặc định để chúng tôi rõ ràng về những gì người thừa kế có thể đi xe @Luaan. Phải thừa nhận rằng, đôi khi nó là PITA, nhưng không liên quan gì đến sở thích cho các loại cụ thể. Ảo chắc chắn không phải là trường hợp đặc biệt trong C #. Có vẻ như bạn đã không may làm việc trong một cơ sở mã C # được viết bởi những người nghiệp dư. Tôi xin lỗi đó là kinh nghiệm của bạn với ngôn ngữ. Tốt nhất nên nhớ rằng nhà phát triển không phải là ngôn ngữ và ngược lại.
RubberDuck

@RubberDuck Hah, tôi chưa bao giờ nói tôi không thích nó. Tôi rất thích nó, bởi vì hầu hết mọi người không hiểu được sự thiếu quyết đoán . Ngay cả trong số các lập trình viên. Theo mặc định là tốt hơn theo ý kiến ​​của tôi. Và khi tôi bắt đầu với C #, mọi người đều là một người nghiệp dư, bao gồm cả nhóm .NET :) Trong "OOP thực", mọi thứ đều được coi là ảo - mọi loại nên được thay thế bằng một loại dẫn xuất, có thể ghi đè mọi hành vi . Nhưng "OOP thực" được thiết kế cho các chuyên gia, không phải những người chuyển từ thay thế bóng đèn sang lập trình vì nó ít tốn công hơn :)
Luaan

Không ... Không. Đó không phải là cách "OOP thực sự" hoạt động. Trong Java, bạn nên dành thời gian để đóng dấu các phương thức không nên bị ghi đè, không để nó giống như miền Tây hoang dã nơi bất kỳ ai cũng có thể lái xe mọi thứ. LSP không có nghĩa là bạn có thể ghi đè bất cứ điều gì bạn muốn. LSP có nghĩa là bạn có thể thay thế một lớp một cách an toàn. Smh
RubberDuck

-8

Bạn đúng ở chỗ quy ước I = giao diện này phá vỡ quy tắc (mới)

Ngày xưa, bạn sẽ thêm tiền tố vào mọi thứ với kiểu intCount boolFlag, v.v.

Nếu bạn muốn đặt tên cho những thứ không có tiền tố, nhưng cũng nên tránh 'ConcreteParser', bạn có thể sử dụng các không gian tên

namespace myapp.Interfaces
{
    public interface Parser {...
}


namespace myapp.Parsers
{
    public class Parser : myapp.Interfaces.Parser {...
}

11
Mới? cũ? Đợi đã, tôi nghĩ lập trình là về sự hợp lý hơn là sự cường điệu. Hay là ngày xưa?

3
không có tất cả về việc tạo nên các quy ước và viết blog về cách họ 'cải thiện khả năng đọc'
Ewan

8
Tôi tin rằng bạn đang nghĩ về ký hiệu Hungary, trong đó bạn thực sự đã đặt tên tiền tố với các loại. Nhưng không có thời gian mà bạn viết một cái gì đó như intCounterhoặc boolFlag. Đó là những "loại" sai. Thay vào đó, bạn sẽ viết pszName(con trỏ tới một chuỗi kết thúc NUL có chứa tên), cchName(số ký tự trong chuỗi "tên"), xControl(tọa độ x của điều khiển), fVisible(cờ biểu thị điều gì đó hiển thị), pFile(con trỏ tới một tập tin), hWindow(xử lý một cửa sổ), v.v.
Cody Grey

2
Vẫn còn rất nhiều giá trị trong việc này. Một trình biên dịch sẽ không bắt lỗi khi bạn thêm xControlvào cchName. Cả hai đều thuộc loại int, nhưng chúng có ngữ nghĩa rất khác nhau. Các tiền tố làm cho những ngữ nghĩa này rõ ràng đối với một con người. Một con trỏ tới một chuỗi kết thúc NUL trông giống hệt như một con trỏ tới một chuỗi kiểu Pascal cho trình biên dịch. Tương tự, Itiền tố cho các giao diện xuất hiện trong ngôn ngữ C ++, nơi các giao diện thực sự chỉ là các lớp (và thực sự đối với C, trong đó không có thứ gọi là lớp hoặc giao diện ở cấp độ ngôn ngữ, tất cả chỉ là quy ước).
Cody Grey

4
@CodyGray Joel Spolsky đã viết một bài viết hay, Làm cho Mã sai Nhìn sai về ký hiệu Hungary và cách hiểu (mis). Ông có một quan điểm tương tự: tiền tố phải là loại cấp cao hơn, không phải loại lưu trữ dữ liệu thô. Anh ta sử dụng từ "tử tế", giải thích, "Tôi đang sử dụng từ loại này nhằm mục đích, bởi vì Simonyi đã sử dụng nhầm loại từ trong bài báo của mình và các thế hệ lập trình viên đã hiểu sai ý anh ta."
Joshua Taylor
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.