Không bao giờ sử dụng Chuỗi trong Java? [đóng cửa]


73

Tôi tình cờ thấy một mục blog không khuyến khích việc sử dụng Chuỗi trong Java để làm cho mã của bạn thiếu ngữ nghĩa, đề nghị rằng bạn nên sử dụng các lớp trình bao bọc mỏng thay thế. Đây là ví dụ trước và sau khi mục nói trên cung cấp để minh họa vấn đề:

public void bookTicket(
  String name,
  String firstName,
  String film,
  int count,
  String cinema);

public void bookTicket(
  Name name,
  FirstName firstName,
  Film film,
  Count count,
  Cinema cinema);

Theo kinh nghiệm đọc blog lập trình tôi đã đi đến kết luận rằng 90% là vô nghĩa, nhưng tôi vẫn tự hỏi liệu đây có phải là một điểm hợp lệ hay không. Bằng cách nào đó nó không phù hợp với tôi, nhưng tôi không thể xác định chính xác điều gì không ổn với phong cách lập trình.


Thảo luận có liên quan trên Wiki gốc: "toString () của cái gì?"
Christoffer Hammarström

5
Ôi chà, bài đăng trên blog đó khiến tôi cảm thấy ốm yếu
Rob

5
Tôi đã đọc ít nhất một cuốn sách (có thể là phiên bản đầu tiên của Hoàn thành mã) đề nghị nhập vào tất cả các loại nguyên thủy của bạn để có tên từ miền vấn đề. Cùng một ý tưởng.
dùng16764

9
một tuyên bố bắt đầu bằng "không bao giờ" là "luôn luôn" sai!
Florents Tselai

1
Anh chàng đó là CTO?!
Hyangelo

Câu trả lời:


88

Đóng gói là có để bảo vệ chương trình của bạn chống lại sự thay đổi . Là đại diện của một tên sẽ thay đổi? Nếu không, thì bạn đang lãng phí thời gian và áp dụng YAGNI.

Chỉnh sửa: Tôi đã đọc bài đăng trên blog và anh ấy có một ý tưởng cơ bản tốt. Vấn đề là anh ấy đã mở rộng nó quá xa. Một cái gì đó như String orderId thực sự xấu, bởi vì có lẽ "!"£$%^&*())ADAFVFkhông phải là một hợp lệ orderId. Điều này có nghĩa là Stringđại diện cho nhiều giá trị có thể hơn so với orderIds hợp lệ . Tuy nhiên, đối với một cái gì đó như a name, thì bạn không thể dự đoán cái gì có thể hoặc không phải là tên hợp lệ và bất kỳ cái nào Stringlà hợp lệ name.

Trong trường hợp đầu tiên, bạn (chính xác) giảm các đầu vào có thể xuống chỉ còn các đầu vào hợp lệ. Trong trường hợp thứ hai, bạn đã đạt được không thu hẹp các đầu vào hợp lệ có thể.

Chỉnh sửa lại: Xem xét trường hợp đầu vào không hợp lệ. Nếu bạn viết "Gareth Gobulcoque" như tên của bạn, nó sẽ trông thật ngớ ngẩn, nó sẽ không phải là ngày tận thế. Nếu bạn đặt một OrderID không hợp lệ, rất có thể là nó sẽ không hoạt động.


5
Với id đơn hàng, tôi vẫn có thể thích thêm một kiểm tra trong mã chấp nhận id và rời khỏi Chuỗi. Các lớp được cho là cung cấp các phương thức để vận hành với dữ liệu. Nếu một số lớp chỉ kiểm tra tính hợp lệ của một số dữ liệu và sau đó không làm gì, thì điều này có vẻ không phù hợp với tôi. OOP là tốt, nhưng bạn không nên quá lạm dụng nó.
Malcolm

13
@Malcolm: Nhưng sau đó bạn không có cách nào để biết Chuỗi nào được xác thực ngoại trừ xác thực chúng nhiều lần.
DeadMG

7
"[...] bạn không thể dự đoán tên nào có thể hoặc không phải là tên hợp lệ và bất kỳ Chuỗi nào cũng là tên hợp lệ." Tôi đoán một điểm mạnh của kỹ thuật này là nếu tham số của bạn thuộc loại Name, bạn không thể vô tình vượt qua một giá trị Chuỗi không liên quan khác. Nếu bạn mong đợi a Name, chỉ có một Nameý chí sẽ biên dịch và Chuỗi "Tôi nợ bạn $ 5" không thể được chấp nhận một cách tình cờ. (Lưu ý rằng điều này không liên quan đến bất kỳ loại xác nhận tên nào!)
Andres F.

6
Tạo các loại dành riêng cho một mục đích sử dụng cụ thể sẽ thêm sự phong phú về ngữ nghĩa và giúp thêm an toàn. Ngoài ra, việc tạo các loại để biểu thị các giá trị cụ thể giúp ích rất nhiều khi sử dụng bộ chứa IoC để tự động xác định các lớp của bạn - dễ dàng giải quyết đúng loại đậu để sử dụng khi đó là loại đậu duy nhất được đăng ký cho một lớp cụ thể. Cần nhiều nỗ lực hơn khi nó chỉ là một trong nhiều chuỗi được đăng ký.
Dathan

3
@DeadMG Đó là tranh luận, và không phải là một cái gì đó chúng ta có thể giải quyết trong các bình luận. Tôi muốn nói rằng việc đặt sai giá trị của các kiểu nguyên thủy sẽ xảy ra và làm cứng giao diện của bạn là một cách để cải thiện tình hình.
Andres F.

46

Điều đó thật điên rồ :)


2
Đó cũng là ý kiến ​​của tôi, nhưng có một điều là tôi nhớ đề xuất này trong "Hoàn thành mã". Tất nhiên không phải tất cả mọi thứ trong cuốn sách đó là không thể chối cãi, nhưng ít nhất nó khiến tôi phải suy nghĩ kỹ trước khi từ chối một ý tưởng.
DPM

8
Bạn chỉ đề cập đến một số khẩu hiệu mà không có bất kỳ biện minh thực sự. Bạn có thể giải thích ý kiến ​​của bạn? Ví dụ, một số mẫu và tính năng ngôn ngữ được chấp nhận có thể trông giống như sự phức tạp được thêm vào, nhưng cung cấp một cái gì đó có giá trị đổi lại (ví dụ: gõ tĩnh)
Andres F.

12
Tâm lý chung là bất cứ điều gì nhưng thông thường.
Kaz Dragon

1
+1, với điều này tôi sẽ nói thêm rằng khi một ngôn ngữ hỗ trợ các tham số được đặt tên và IDE tốt, chẳng hạn như trường hợp với C # và VS2010, thì người ta không phải bù đắp cho việc thiếu các tính năng trong ngôn ngữ với các mẫu điên . Không cần cho lớp có tên X và một lớp có tên Y, nếu người ta có thể viết var p = new Point(x: 10, y:20);Ngoài ra, nó không giống như Điện ảnh khác với một chuỗi. Tôi sẽ hiểu nếu một người phải đối phó với các đại lượng vật lý, chẳng hạn như áp suất, nhiệt độ, năng lượng, nơi các đơn vị khác nhau và một số không thể âm. Các tác giả của blog cần phải thử chức năng.
Công việc

1
+1 cho "Đừng quá kỹ sư!"
Ivan

23

Tôi đồng ý với tác giả, chủ yếu. Nếu có bất kỳ hành vi nào đặc biệt đối với một trường, như xác thực id đơn hàng, thì tôi sẽ tạo một lớp để thể hiện loại đó. Điểm thứ hai của anh ấy thậm chí còn quan trọng hơn: nếu bạn có một tập hợp các trường đại diện cho một số khái niệm như một địa chỉ, thì hãy tạo một lớp cho khái niệm đó. Nếu bạn đang lập trình bằng Java, bạn đang phải trả giá đắt cho việc gõ tĩnh. Bạn cũng có thể nhận được tất cả các giá trị bạn có thể.


2
Downvoter có thể bình luận?
kevin cline

Giá cao chúng tôi đang trả cho gõ tĩnh là gì?
Richard Tingle

@RichardTingle: Thời gian biên dịch lại mã và khởi động lại JVM cho mỗi thay đổi mã. Thời gian bị mất khi bạn thực hiện thay đổi tương thích nguồn nhưng không tương thích nhị phân và những thứ cần được biên dịch lại không phải là bạn và bạn nhận được "MissingMethodException".
kevin cline

Tôi chưa bao giờ gặp sự cố với các ứng dụng java (với việc biên dịch liên tục, nó thường được biên dịch vào thời điểm tôi chạy) nhưng đó là một điểm công bằng với các WAR trên web mà việc triển khai lại có vẻ chậm hơn một chút
Richard Tingle

16

Đừng làm điều đó; nó sẽ làm quá nhiều thứ và bạn không cần nó

... Là câu trả lời tôi đã viết ở đây 2 năm trước. Bây giờ, mặc dù, tôi không chắc chắn lắm; thực tế, trong những tháng gần đây tôi đã bắt đầu chuyển mã cũ sang định dạng này, không phải vì tôi không có gì để làm mà vì tôi thực sự cần nó để triển khai các tính năng mới hoặc thay đổi các tính năng hiện có. Tôi hiểu những ác cảm tự động mà những người khác ở đây đã nhìn thấy mã đó, nhưng tôi nghĩ đây là điều đáng được suy nghĩ nghiêm túc.


Những lợi ích

Trưởng trong số các lợi ích là khả năng sửa đổi và mở rộng mã. Nếu bạn dùng

class Point {
    int x,y;
    // other point operations
}

thay vì chỉ truyền một vài số nguyên xung quanh - đó là điều mà thật không may, nhiều giao diện thực hiện - sau đó việc thêm một chiều khác trở nên dễ dàng hơn nhiều. Hoặc thay đổi loại thành double. Nếu bạn sử dụng List<Author> authorshoặc List<Person> authorsthay vào List<String> authorsđó, việc bổ sung thêm thông tin vào những gì tác giả thể hiện sẽ trở nên dễ dàng hơn nhiều. Viết nó ra như thế này có cảm giác như tôi đang nói rõ ràng, nhưng trong thực tế, tôi đã phạm tội khi sử dụng chuỗi theo cách này nhiều lần, đặc biệt là trong trường hợp không rõ ràng khi bắt đầu thì tôi cần nhiều hơn một chuỗi.

Tôi hiện đang cố gắng cấu trúc lại một số danh sách chuỗi được đan xen trong toàn bộ mã của mình vì tôi cần thêm thông tin ở đó và tôi cảm thấy đau: \

Ngoài ra, tôi đồng ý với tác giả của blog rằng nó mang nhiều thông tin ngữ nghĩa hơn , giúp người đọc dễ hiểu hơn. Mặc dù các tham số thường được đặt tên có ý nghĩa và nhận được một dòng tài liệu chuyên dụng, nhưng điều này thường không xảy ra với các trường hoặc địa phương.

Lợi ích cuối cùng là an toàn loại , vì những lý do rõ ràng, nhưng trong mắt tôi, đó là một điều nhỏ ở đây.

Hạn chế

Phải mất nhiều thời gian để viết . Viết một lớp học nhỏ là nhanh chóng và dễ dàng nhưng không dễ dàng, đặc biệt nếu bạn cần rất nhiều các lớp học này. Nếu bạn thấy mình dừng lại cứ sau 3 phút để viết một số lớp bao bọc mới, nó cũng có thể gây bất lợi cho sự tập trung của bạn. Tuy nhiên, tôi muốn nghĩ rằng trạng thái nỗ lực này thường sẽ chỉ xảy ra ở giai đoạn đầu tiên viết bất kỳ đoạn mã nào; Tôi thường có thể có được một ý tưởng khá tốt một cách nhanh chóng về những gì các thực thể sẽ cần phải tham gia.

Nó có thể liên quan đến rất nhiều setters (hoặc công trình) và getters dự phòng . Tác giả blog đưa ra ví dụ thực sự xấu xí new Point(x(10), y(10))thay vì new Point(10, 10), và tôi muốn thêm rằng việc sử dụng cũng có thể liên quan đến những thứ như Math.max(p.x.get(), p.y.get())thay vì Math.max(p.x, p.y). Và mã dài thường được coi là khó đọc hơn, và công bằng như vậy. Nhưng thành thật mà nói, tôi có cảm giác rất nhiều mã di chuyển các đối tượng xung quanh và chỉ chọn các phương thức tạo ra nó, và thậm chí ít cần truy cập vào các chi tiết nghiệt ngã của nó (dù sao đó không phải là OOPy).

Tranh cãi

Tôi muốn nói liệu điều này có giúp ích cho tính dễ đọc của mã hay không . Có, thông tin ngữ nghĩa nhiều hơn, nhưng mã dài hơn. Vâng, dễ hiểu hơn về vai trò của từng địa phương, nhưng khó hiểu hơn những gì bạn có thể làm với nó trừ khi bạn đi và đọc tài liệu của nó.


Như với hầu hết các trường phái lập trình khác, tôi nghĩ thật không lành mạnh khi đưa cái này đến mức cực đoan. Tôi không thấy mình tách biệt tọa độ x và y thành mỗi loại khác nhau. Tôi không nghĩ Countlà cần thiết khi intđủ. Tôi không thích unsigned intcách sử dụng trong C - mặc dù về mặt lý thuyết là tốt, nhưng nó không cung cấp cho bạn đủ thông tin và việc cấm mở rộng mã của bạn sau này để hỗ trợ phép thuật -1 đó. Đôi khi bạn cần sự đơn giản.

Tôi nghĩ rằng bài viết trên blog là một chút về phía cực đoan. Nhưng nhìn chung, tôi đã học được từ kinh nghiệm đau đớn rằng ý tưởng cơ bản đằng sau nó được tạo ra từ những thứ phù hợp.

Tôi có ác cảm sâu sắc với mã quá kỹ thuật. Tôi thực sự làm. Nhưng được sử dụng đúng, tôi không nghĩ rằng kỹ thuật quá mức này.


5

Mặc dù nó là loại quá mức cần thiết, nhưng tôi thường nghĩ rằng hầu hết những thứ tôi thấy là thay thế.

Đó không chỉ là "An toàn", Một trong những điều thực sự hay về Java là nó giúp bạn rất nhiều trong việc ghi nhớ / tìm ra những gì mà bất kỳ cuộc gọi phương thức thư viện nào cũng cần / mong đợi.

Thư viện Java WORST (cho đến nay) mà tôi đã làm việc được viết bởi một người rất thích Smalltalk và mô hình hóa thư viện GUI sau khi nó làm cho nó hoạt động giống như smalltalk - vấn đề là mọi phương thức đều lấy cùng một đối tượng cơ sở, nhưng thực tế không thể sử dụng mọi thứ mà đối tượng cơ sở có thể sử dụng, vì vậy bạn quay lại đoán những gì cần truyền vào các phương thức và không biết liệu bạn có thất bại cho đến khi chạy không (Tôi thường phải xử lý mọi lúc đã làm việc tại C).

Một vấn đề khác - Nếu bạn chuyển xung quanh chuỗi, ints, bộ sưu tập và mảng không có đối tượng, tất cả những gì bạn có là những quả bóng dữ liệu không có ý nghĩa. Điều này có vẻ tự nhiên khi bạn nghĩ về các thư viện mà "một số ứng dụng" sẽ sử dụng, nhưng khi thiết kế toàn bộ ứng dụng, việc gán ý nghĩa (mã) cho tất cả dữ liệu của bạn ở nơi dữ liệu được xác định và chỉ nghĩ đến điều khoản về cách các đối tượng cấp cao tương tác. Nếu bạn đang đi xung quanh nguyên thủy thay vì các đối tượng thì bạn - theo định nghĩa - thay đổi dữ liệu ở một nơi khác với nơi được xác định (Đây cũng là lý do tại sao tôi thực sự không thích Setters và Getters - cùng một khái niệm, bạn đang vận hành trên dữ liệu không phải của bạn).

Cuối cùng, nếu bạn xác định các đối tượng riêng biệt cho mọi thứ bạn luôn có một nơi tuyệt vời để xác thực mọi thứ - ví dụ: nếu bạn tạo một đối tượng cho mã zip và sau đó thấy rằng bạn phải đảm bảo rằng mã zip luôn bao gồm phần mở rộng 4 chữ số bạn có nơi hoàn hảo để đặt nó.

Đó thực sự không phải là một ý tưởng tồi. Nghĩ về điều đó tôi thậm chí không chắc là tôi đã nói rằng nó quá phức tạp, gần như dễ dàng hơn để làm việc với mọi cách - một ngoại lệ là sự phổ biến của các lớp nhỏ nhưng các lớp Java rất nhẹ và dễ dàng để viết rằng đây hầu như không phải là một chi phí (chúng thậm chí có thể được tạo ra).

Tôi thực sự thích thú khi thấy một dự án java được viết tốt thực sự có quá nhiều lớp được định nghĩa (Trường hợp làm cho việc lập trình trở nên khó khăn hơn), tôi bắt đầu nghĩ rằng không thể có quá nhiều lớp.


3

Tôi nghĩ rằng bạn phải xem xét khái niệm này từ một điểm khởi đầu khác. Hãy nhìn từ quan điểm của một nhà thiết kế cơ sở dữ liệu: các kiểu được truyền trong ví dụ đầu tiên không xác định các tham số của bạn theo một cách riêng, chứ đừng nói đến một cách hữu ích.

public void bookTicket(
  String name,
  String firstName,
  String film,
  int count,
  String cinema);

Cần hai tham số để chỉ định người bảo trợ thực tế là đặt vé, bạn có thể có hai phim khác nhau có tên giống nhau (ví dụ: làm lại), bạn có thể có cùng một phim với các tên khác nhau (ví dụ: bản dịch). Một chuỗi nhất định của rạp chiếu phim có thể có văn phòng chi nhánh khác nhau, vậy làm thế nào thì bạn sẽ đối phó với điều đó trong một chuỗi và theo một cách phù hợp (ví dụ như bạn đang sử dụng $chain ($city)hoặc $chain in $cityhoặc thậm chí cái gì khác và làm thế nào bạn đang đi để đảm bảo rằng đây là Điều tồi tệ nhất thực sự là chỉ định người bảo trợ của bạn bằng hai tham số, thực tế là cả tên và họ đều được cung cấp không đảm bảo khách hàng hợp lệ (và bạn không thể phân biệt hai John Does).

Câu trả lời cho điều này là khai báo các loại, nhưng đây sẽ hiếm khi là các hàm bao mỏng như tôi trình bày ở trên. Nhiều khả năng, chúng sẽ hoạt động như lưu trữ dữ liệu của bạn hoặc được kết hợp với một số loại cơ sở dữ liệu. Vì vậy, một Cinemađối tượng có thể sẽ có tên, địa điểm, ... và theo cách đó bạn sẽ thoát khỏi sự mơ hồ như vậy. Nếu chúng là giấy gói mỏng, chúng là do sự trùng hợp.

Vì vậy, IMHO bài đăng trên blog chỉ nói "đảm bảo bạn vượt qua các loại chính xác", tác giả của nó chỉ đưa ra lựa chọn quá hạn chế để chọn các loại dữ liệu cơ bản cụ thể (đó là thông báo sai).

Đề xuất thay thế là tốt hơn:

public void bookTicket(
  Name name,
  FirstName firstName,
  Film film,
  Count count,
  Cinema cinema);

Mặt khác, tôi nghĩ rằng bài viết trên blog đi quá xa với việc gói mọi thứ. Countquá chung chung, tôi có thể đếm táo hoặc cam với điều đó, thêm chúng và vẫn có một tình huống trong tay nơi hệ thống loại cho phép tôi thực hiện các hoạt động vô nghĩa. Tất nhiên bạn có thể áp dụng logic tương tự như trong blog và xác định các loại CountOfOranges, v.v., nhưng điều đó cũng thật ngớ ngẩn.

Đối với những gì nó có giá trị, tôi thực sự viết một cái gì đó như

public Ticket bookTicket(
  Person patron,
  Film film,
  int numberOfTickets,
  Cinema cinema);

Câu chuyện dài ngắn: bạn không nên vượt qua các biến vô nghĩa; lần duy nhất bạn thực sự chỉ định một đối tượng có giá trị không xác định đối tượng thực tế là khi bạn chạy truy vấn (ví dụ public Collection<Film> findFilmsWithTitle(String title)) hoặc khi bạn kết hợp một khái niệm bằng chứng. Giữ hệ thống loại của bạn sạch sẽ, vì vậy đừng sử dụng loại quá chung chung (ví dụ: phim được đại diện bởi a String) hoặc quá hạn chế / cụ thể / bị tước đoạt (ví dụ Countthay vì int). Sử dụng một loại xác định đối tượng của bạn duy nhất và rõ ràng bất cứ khi nào có thể và khả thi.

chỉnh sửa : một bản tóm tắt thậm chí ngắn hơn. Đối với các ứng dụng nhỏ (ví dụ bằng chứng về các khái niệm): tại sao phải bận tâm với một thiết kế phức tạp? Chỉ cần sử dụng Stringhoặc intvà có được với nó.

Đối với các ứng dụng lớn: có thực sự có khả năng là bạn có nhiều lớp bao gồm một trường duy nhất với kiểu dữ liệu cơ bản không? Nếu bạn có ít lớp như vậy, bạn chỉ có các đối tượng "bình thường", không có gì đặc biệt xảy ra ở đó.

Tôi cảm thấy ý tưởng đóng gói các chuỗi, ... chỉ là một thiết kế chưa hoàn chỉnh: quá phức tạp cho các ứng dụng nhỏ, không đủ hoàn chỉnh cho các ứng dụng lớn.


Tôi thấy quan điểm của bạn, nhưng tôi cho rằng bạn đang giả định nhiều hơn tác giả đang nêu. Đối với tất cả những gì chúng ta biết, mô hình của anh ta chỉ có một Chuỗi cho một người bảo trợ, một Chuỗi cho một bộ phim và như vậy. Chức năng bổ sung giả thuyết đó thực sự là mấu chốt của vấn đề nên anh ta rất "đãng trí" để bỏ qua điều đó khi đưa ra trường hợp của mình hoặc anh ta nghĩ rằng chúng ta nên cung cấp thêm sức mạnh ngữ nghĩa chỉ vì. Một lần nữa, đối với tất cả những gì chúng ta biết, đó là cái sau mà anh ấy có trong tâm trí.
DPM

@Jubbat: thực sự tôi giả định nhiều hơn những gì tác giả nêu. Nhưng quan điểm của tôi là hoặc bạn có một ứng dụng đơn giản, trong trường hợp một trong hai cách là quá phức tạp. Đối với quy mô đó, khả năng bảo trì không phải là một vấn đề và sự phân biệt ngữ nghĩa cản trở tốc độ mã hóa của bạn. Mặt khác, ứng dụng của bạn lớn, việc xác định đúng các loại của bạn trở nên đáng giá (nhưng không chắc là các trình bao bọc đơn giản). IMHO, ví dụ của anh ta chỉ không thuyết phục hoặc có lỗi thiết kế lớn ngoài điểm anh ta đang cố gắng thực hiện.
Egon

2

Đối với tôi, việc này giống như sử dụng các vùng trong C #. Nói chung nếu bạn cảm thấy điều này là cần thiết để làm cho mã của bạn có thể đọc được thì bạn có vấn đề lớn hơn bạn nên dành thời gian cho nó.


2
+1 để ngụ ý điều trị các triệu chứng hơn là nguyên nhân.
Công việc

2

Tôi muốn nói rằng đó là một ý tưởng thực sự tốt trong một ngôn ngữ có tính năng đánh máy được gõ mạnh.

Trong Java, bạn không có điều này để tạo ra lớp hoàn toàn mới cho những thứ này có nghĩa là chi phí có thể vượt xa lợi ích. Bạn cũng có thể nhận được 80% lợi ích bằng cách cẩn thận về việc đặt tên biến / tham số.


0

Sẽ tốt hơn, Chuỗi IF (Số nguyên cuối và ... chỉ nói về Chuỗi) không phải là cuối cùng, vì vậy các lớp này có thể là một số Chuỗi (bị hạn chế) có ý nghĩa và vẫn có thể được gửi đến một số đối tượng độc lập biết cách xử lý loại cơ sở (không nói chuyện qua lại).

Và "goodnes" của nó tăng lên khi có ví dụ. hạn chế về tất cả các tên.

Nhưng khi tạo một số ứng dụng (không phải thư viện), luôn có thể cấu trúc lại nó. Vì vậy, tôi prefare để bắt đầu mà không có nó.


0

Để đưa ra một ví dụ: trong hệ thống hiện đang phát triển của chúng tôi, có rất nhiều thực thể khác nhau có thể được xác định bằng nhiều loại định danh (do sử dụng các hệ thống bên ngoài), đôi khi thậm chí là cùng một loại thực thể. Tất cả các mã định danh là Chuỗi - vì vậy nếu ai đó trộn lẫn loại id nào sẽ được chuyển qua làm tham số, không có lỗi thời gian biên dịch được hiển thị, nhưng chương trình sẽ nổ tung khi chạy. Điều này xảy ra khá thường xuyên. Vì vậy, tôi phải nói rằng mục đích chính của nguyên tắc này không phải là để bảo vệ chống lại sự thay đổi (mặc dù nó cũng phục vụ điều đó), mà là để bảo vệ bản thân khỏi các lỗi. Và dù sao đi nữa, nếu ai đó thiết kế API, nó phải phản ánh các khái niệm của miền, do đó, rất hữu ích khi xác định các lớp dành riêng cho miền - mọi thứ phụ thuộc vào việc có thứ tự trong tâm trí của nhà phát triển hay không,


@downvoter: bạn có thể vui lòng cho một lời giải thích?
thSoft
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.