Có bao giờ một lý do để làm tất cả công việc của một đối tượng trong một hàm tạo không?


49

Hãy để tôi mở đầu điều này bằng cách nói rằng đây không phải là mã của tôi cũng không phải mã của đồng nghiệp. Nhiều năm trước, khi công ty của chúng tôi nhỏ hơn, chúng tôi đã có một số dự án chúng tôi cần thực hiện mà chúng tôi không có năng lực, vì vậy họ đã thuê ngoài. Bây giờ, tôi không có gì chống lại việc thuê ngoài hoặc các nhà thầu nói chung, nhưng cơ sở mã họ sản xuất là một khối WTF. Điều đó đang được nói, nó (hầu hết) hoạt động, vì vậy tôi cho rằng nó nằm trong top 10% các dự án thuê ngoài mà tôi đã thấy.

Khi công ty của chúng tôi phát triển, chúng tôi đã cố gắng phát triển hơn nữa. Dự án đặc biệt này đã nằm trong lòng tôi vì vậy tôi đã trải qua nó, dọn dẹp, thêm các bài kiểm tra, v.v.

Có một mô hình tôi thấy lặp đi lặp lại rất nhiều và dường như rất kinh khủng đến nỗi tôi tự hỏi liệu có thể có một lý do và tôi chỉ không nhìn thấy nó. Mẫu này là một đối tượng không có các phương thức hoặc thành viên công khai, chỉ là một hàm tạo công khai thực hiện tất cả công việc của đối tượng.

Ví dụ: (mã là trong Java, nếu điều đó quan trọng, nhưng tôi hy vọng đây sẽ là một câu hỏi tổng quát hơn):

public class Foo {
  private int bar;
  private String baz;

  public Foo(File f) {
    execute(f);
  }

  private void execute(File f) {
     // FTP the file to some hardcoded location, 
     // or parse the file and commit to the database, or whatever
  }
}

Nếu bạn đang tự hỏi, loại mã này thường được gọi theo cách sau:

for(File f : someListOfFiles) {
   new Foo(f);
}

Bây giờ, tôi đã được dạy từ lâu rằng các đối tượng khởi tạo trong một vòng lặp thường là một ý tưởng tồi và các nhà xây dựng nên thực hiện tối thiểu công việc. Nhìn vào mã này, có vẻ như sẽ tốt hơn nếu bỏ hàm tạo và tạo executemột phương thức tĩnh công khai.

Tôi đã hỏi nhà thầu tại sao nó được thực hiện theo cách này và câu trả lời tôi nhận được là "Chúng tôi có thể thay đổi nếu bạn muốn". Điều đó không thực sự hữu ích.

Dù sao, có bao giờ một lý do để làm một cái gì đó như thế này, trong bất kỳ ngôn ngữ lập trình, hoặc đây chỉ là một đệ trình khác cho Daily WTF?


18
Có vẻ như nó được viết bởi những nhà phát triển biết public static void main(string[] args)và đã nghe về các vật thể, sau đó cố gắng trộn chúng lại với nhau.
Andy Hunt

Nếu bạn không bao giờ được gọi lại, bạn phải làm điều đó ở đó. Nhiều khung hiện đại, ví dụ như tiêm phụ thuộc cần các hạt được tạo ra, thiết lập các thuộc tính và THEN được gọi, và sau đó bạn không thể sử dụng các công nhân nặng này.

4
Câu hỏi liên quan: Bất kỳ vấn đề với việc thực hiện công việc chính của một lớp trong hàm tạo của nó? . Tuy nhiên, điều này hơi khác một chút, vì thể hiện đã tạo được sử dụng sau đó.
sleske


Tôi thực sự không muốn mở rộng điều này thành một câu trả lời đầy đủ, nhưng hãy để tôi nói: có những kịch bản, trong đó điều này được cho là có thể chấp nhận được. Điều này là rất xa từ nó. Ở đây một đối tượng được khởi tạo mà không thực sự cần đối tượng. Ngược lại, nếu bạn đang tạo một loại cấu trúc dữ liệu từ tệp XML, thì việc khởi tạo phân tích cú pháp từ hàm tạo không hoàn toàn khủng khiếp. Trong thực tế, trong các ngôn ngữ cho phép quá tải các nhà xây dựng, không có gì tôi sẽ giết bạn vì là người bảo trì;)
back2dos

Câu trả lời:


60

Ok, đi xuống danh sách:

Tôi đã được dạy từ lâu rằng các đối tượng khởi tạo trong một vòng lặp thường là một ý tưởng tồi

Không có ngôn ngữ nào tôi đã sử dụng.

Trong C, bạn nên khai báo các biến của mình trước, nhưng nó khác với những gì bạn đã nói. Nó có thể nhanh hơn một chút nếu bạn khai báo các đối tượng phía trên vòng lặp và sử dụng lại chúng, nhưng có rất nhiều ngôn ngữ trong đó việc tăng tốc độ này sẽ vô nghĩa (và có lẽ một số trình biên dịch ngoài đó thực hiện tối ưu hóa cho bạn :)).

Nói chung, nếu bạn cần một đối tượng trong vòng lặp, hãy tạo một đối tượng.

nhà xây dựng nên làm tối thiểu công việc

Các nhà xây dựng nên khởi tạo các trường của một đối tượng và thực hiện bất kỳ khởi tạo nào khác cần thiết để làm cho đối tượng sẵn sàng sử dụng. Điều này thường có nghĩa là các nhà xây dựng là nhỏ, nhưng có những kịch bản trong đó đây sẽ là một khối lượng công việc đáng kể.

Có bao giờ một lý do để làm một cái gì đó như thế này, trong bất kỳ ngôn ngữ lập trình, hoặc đây chỉ là một đệ trình khác cho Daily WTF?

Đó là một đệ trình lên WTF hàng ngày. Cấp, có những điều tồi tệ hơn bạn có thể làm với mã. Vấn đề là tác giả có một sự hiểu lầm lớn về các lớp là gì và làm thế nào để sử dụng chúng. Cụ thể, đây là những gì tôi thấy là sai với mã này:

  • Lạm dụng các lớp: Lớp về cơ bản hoạt động như một hàm. Như bạn đã đề cập, nó nên được thay thế bằng một hàm tĩnh hoặc hàm chỉ nên được thực hiện trong lớp đang gọi nó. Phụ thuộc vào những gì nó làm và nơi nó được sử dụng.
  • Chi phí hoạt động: Tùy thuộc vào ngôn ngữ, việc tạo một đối tượng có thể chậm hơn so với việc gọi một chức năng.
  • Nhầm lẫn chung: Nói chung là gây nhầm lẫn cho người lập trình cách sử dụng mã này. Nếu không thấy nó được sử dụng, không ai có thể biết tác giả dự định sử dụng mã được đề cập như thế nào.

Cám ơn phản hồi của bạn. Liên quan đến "khởi tạo các đối tượng trong một vòng lặp", đây là điều mà rất nhiều công cụ phân tích tĩnh cảnh báo, và tôi cũng đã nghe điều đó từ một số giáo sư đại học. Cấp, đó có thể là một nắm giữ từ những năm 90 khi hiệu suất đạt được lớn hơn. Tất nhiên, nếu bạn cần nó, hãy làm nó, nhưng tôi ngạc nhiên khi nghe một quan điểm trái ngược. Cảm ơn đã mở rộng tầm nhìn của tôi.
Kane

8
Khởi tạo các đối tượng trong một vòng lặp là một mùi mã nhỏ; bạn nên nhìn vào nó và hỏi "tôi có thực sự cần phải khởi tạo đối tượng này nhiều lần không?". Nếu bạn đang khởi tạo cùng một đối tượng với cùng một dữ liệu và bảo nó làm điều tương tự, bạn sẽ lưu các chu kỳ (và tránh đập bộ nhớ) bằng cách khởi tạo nó một lần và sau đó chỉ lặp lại hướng dẫn với bất kỳ thay đổi gia tăng nào có thể cần thiết cho trạng thái đối tượng . Tuy nhiên, ví dụ, nếu bạn đang đọc một luồng dữ liệu từ DB hoặc đầu vào khác và tạo ra một loạt các đối tượng để giữ dữ liệu đó, bằng mọi cách có thể ngay lập tức.
KeithS

3
Phiên bản ngắn: Không sử dụng tức thời đối tượng như chúng là một chức năng.
Erik Reppen

27

Đối với tôi, có một chút bất ngờ khi bạn bắt một đối tượng thực hiện nhiều công việc trong hàm tạo, vì vậy tôi chỉ khuyên bạn nên chống lại nó (nguyên tắc ít gây bất ngờ nhất).

Một nỗ lực tại một ví dụ tốt :

Tôi không chắc cách sử dụng này có phải là kiểu chống mẫu hay không, nhưng trong C # tôi đã thấy mã nằm dọc theo dòng (ví dụ được tạo ra phần nào):

using (ImpersonationContext administrativeContext = new ImpersonationContext(ADMIN_USER))
{
    // Perform actions here under the administrator's security context
}
// We're back to "normal" privileges here

Trong trường hợp này, ImpersonationContextlớp thực hiện tất cả các công việc của nó trong hàm tạo và phương thức Vứt bỏ. Nó tận dụng usingcâu lệnh C #, được các nhà phát triển C # hiểu khá rõ và do đó đảm bảo rằng thiết lập xảy ra trong hàm tạo được khôi phục sau khi chúng ta nằm ngoài usingcâu lệnh, ngay cả khi có ngoại lệ xảy ra. Đây có lẽ là cách sử dụng tốt nhất tôi từng thấy cho việc này (tức là "công việc" trong hàm tạo), mặc dù tôi vẫn không chắc chắn tôi coi nó là "tốt". Trong trường hợp này, nó khá tự giải thích, chức năng và succint.

Một ví dụ về một mẫu tốt và tương tự sẽ là mẫu lệnh . Bạn chắc chắn không thực hiện logic trong hàm tạo ở đó, nhưng nó tương tự theo nghĩa là toàn bộ lớp tương đương với một lời gọi phương thức (bao gồm các tham số cần thiết để gọi phương thức). Theo cách này, thông tin gọi phương thức có thể được tuần tự hóa hoặc được thông qua để sử dụng sau này, điều này rất hữu ích. Có lẽ các nhà thầu của bạn đã cố gắng làm điều gì đó tương tự, mặc dù tôi rất nghi ngờ điều đó.

Nhận xét về ví dụ của bạn:

Tôi có thể nói đó là một mô hình chống rất rõ ràng. Nó không thêm gì, đi ngược lại với những gì được mong đợi và thực hiện quá trình xử lý quá lâu trong hàm tạo (FTP trong hàm tạo? WTF thực sự, mặc dù tôi đoán mọi người đã biết gọi các dịch vụ web theo cách này).

Tôi đang vật lộn để tìm trích dẫn, nhưng cuốn sách "Giải pháp đối tượng" của Grady Booch có một giai thoại về một nhóm các nhà phát triển C đang chuyển sang C ++. Rõ ràng họ đã trải qua đào tạo, và được quản lý nói rằng họ hoàn toàn phải làm những việc "hướng đối tượng". Mang lại những gì sai, tác giả đã sử dụng một công cụ số liệu mã và thấy rằng số phương thức trung bình cho mỗi lớp là chính xác 1 và là các biến thể của cụm từ "Làm điều đó". Tôi phải nói rằng, tôi chưa bao giờ gặp phải vấn đề đặc biệt này trước đây, nhưng rõ ràng nó có thể là một triệu chứng của những người bị buộc phải tạo mã hướng đối tượng, mà không thực sự hiểu làm thế nào để làm như vậy, và tại sao.


1
Ví dụ điển hình của bạn là một ví dụ của Phân bổ tài nguyên là Khởi tạo . Đây là một mẫu được đề xuất trong C ++ vì nó giúp viết mã an toàn ngoại lệ dễ dàng hơn nhiều. Tôi không biết liệu điều đó mang đến C #, mặc dù. (Trong trường hợp này, "tài nguyên" được phân bổ là đặc quyền quản trị.)
zwol

@Zack Tôi chưa bao giờ nghĩ về điều đó, mặc dù tôi đã biết về RAII trong C ++. Trong thế giới C #, nó được gọi là mẫu dùng một lần và rất khuyến khích mọi thứ có tài nguyên (thường không được quản lý) giải phóng sau thời gian tồn tại. Sự khác biệt chính trong ví dụ này là bạn thường không thực hiện các toán tử đắt tiền trong hàm tạo. Ví dụ, một phương thức Open () của SqlConnection vẫn cần được gọi sau hàm tạo.
Daniel B

14

Không.

Nếu tất cả các công việc được thực hiện trong hàm tạo, điều đó có nghĩa là đối tượng không bao giờ cần thiết ở vị trí đầu tiên. Nhiều khả năng, nhà thầu chỉ đơn thuần sử dụng đối tượng cho mô đun. Trong trường hợp đó, một lớp không khởi tạo với một phương thức tĩnh sẽ có được lợi ích tương tự mà không tạo ra bất kỳ trường hợp đối tượng thừa nào.

Chỉ có một trường hợp trong đó thực hiện tất cả các công việc trong một hàm tạo đối tượng là chấp nhận được. Đó là khi mục đích của đối tượng là đặc biệt để đại diện cho một bản sắc duy nhất dài hạn, thay vì thực hiện công việc. Trong trường hợp như vậy, đối tượng sẽ được giữ xung quanh vì những lý do khác hơn là thực hiện công việc có ý nghĩa. Ví dụ, một ví dụ đơn lẻ.


7

Tôi chắc chắn đã tạo ra nhiều lớp làm rất nhiều công việc để tính toán một cái gì đó trong hàm tạo, nhưng đối tượng là bất biến, do đó, nó làm cho kết quả tính toán đó có sẵn thông qua các thuộc tính, và sau đó không bao giờ làm gì khác. Đó là sự bất biến bình thường trong hành động.

Tôi nghĩ điều kỳ lạ ở đây là đặt mã với các tác dụng phụ vào một hàm tạo. Xây dựng một đối tượng và ném nó đi mà không truy cập vào các thuộc tính hoặc phương thức có vẻ kỳ lạ (nhưng ít nhất trong trường hợp này, rõ ràng là có một cái gì đó khác đang diễn ra).

Điều này sẽ tốt hơn nếu hàm được chuyển sang một phương thức công khai, và sau đó có một thể hiện của lớp được chèn, sau đó lặp lại vòng lặp for gọi phương thức đó.


4

Có bao giờ một lý do để làm tất cả công việc của một đối tượng trong một hàm tạo không?

Không.

  • Một nhà xây dựng không nên có bất kỳ tác dụng phụ.
    • Bất cứ điều gì nhiều hơn khởi tạo trường riêng nên được xem là một tác dụng phụ.
    • Một nhà xây dựng với các tác dụng phụ phá vỡ Nguyên tắc Đơn trách nhiệm (SRP) và chạy ngược lại với tinh thần của lập trình hướng đối tượng (OOP).
  • Một nhà xây dựng nên nhẹ và không bao giờ thất bại.
    • Chẳng hạn, tôi luôn rùng mình khi thấy một khối thử bắt bên trong một hàm tạo. Một constructor không nên ném ngoại lệ hoặc lỗi log.

Người ta có thể đặt câu hỏi một cách hợp lý các hướng dẫn này và nói, "Nhưng tôi không tuân theo các quy tắc này và mã của tôi hoạt động tốt!" Về điều đó, tôi sẽ trả lời, "Điều đó có thể đúng, cho đến khi nó không."

  • Các ngoại lệ và lỗi bên trong của một constructor là rất bất ngờ. Trừ khi họ được yêu cầu làm như vậy, các lập trình viên trong tương lai sẽ không có xu hướng bao quanh các cuộc gọi của nhà xây dựng này với mã phòng thủ.
  • Nếu bất cứ điều gì thất bại trong sản xuất, dấu vết ngăn xếp được tạo ra có thể khó phân tích. Phần đầu của dấu vết ngăn xếp có thể trỏ đến lệnh gọi của hàm tạo, nhưng nhiều điều xảy ra trong hàm tạo và nó có thể không trỏ đến LỘC thực tế đã thất bại.
    • Tôi đã phân tích nhiều dấu vết ngăn xếp .NET trong trường hợp này.

1
"Trừ khi họ được yêu cầu làm như vậy, các lập trình viên trong tương lai sẽ không có xu hướng bao quanh các cuộc gọi của nhà xây dựng này với mã phòng thủ." - Điểm tốt.
Graham

2

Dường như với tôi, người làm việc này đã cố gắng hack xung quanh giới hạn của Java không cho phép vượt qua các chức năng xung quanh với tư cách là công dân hạng nhất. Bất cứ khi nào bạn phải truyền một hàm, bạn phải bọc nó bên trong một lớp bằng một phương thức giống applyhoặc tương tự.

Vì vậy, tôi đoán anh ta chỉ sử dụng một phím tắt và sử dụng trực tiếp một lớp để thay thế chức năng. Bất cứ khi nào bạn muốn thực thi chức năng, bạn chỉ cần khởi tạo lớp.

Nó chắc chắn không phải là một mô hình tốt, ít nhất là vì chúng ta đang ở đây cố gắng tìm ra nó, nhưng tôi đoán đó có thể là cách ít dài dòng nhất để làm một cái gì đó tương tự như lập trình chức năng trong Java.


3
Tôi khá chắc chắn rằng lập trình viên đặc biệt này chưa bao giờ nghe cụm từ 'lập trình chức năng'.
Kane

Tôi không nghĩ rằng các lập trình viên đã cố gắng tạo ra một sự trừu tượng hóa đóng. Tương đương Java sẽ yêu cầu một đa hình phương pháp trừu tượng (lập kế hoạch cho khả năng). Không có bằng chứng về điều đó ở đây.
Kevin A. Naudé

1

Đối với tôi quy tắc của ngón tay cái là không làm bất cứ điều gì trong hàm tạo, ngoại trừ việc khởi tạo các biến thành viên. Lý do đầu tiên cho điều đó là nó giúp tuân theo nguyên tắc SRP, vì thông thường quá trình khởi tạo dài là một dấu hiệu cho thấy lớp làm nhiều hơn những gì nên làm và việc khởi tạo nên được thực hiện ở đâu đó bên ngoài lớp. Lý do thứ hai là theo cách này chỉ có các tham số cần thiết được thông qua, do đó bạn tạo mã ít kết hợp hơn. Một constructor có khởi tạo phức tạp thường cần các tham số chỉ được sử dụng để xây dựng một đối tượng khác, nhưng không được sử dụng bởi lớp ban đầu.


1

Tôi sẽ đi ngược lại thủy triều ở đây - trong các ngôn ngữ mà mọi thứ phải ở trong một lớp nào đó VÀ bạn không thể có một lớp tĩnh, bạn có thể gặp phải trường hợp bạn có một chức năng riêng biệt cần phải có đặt ở đâu đó và không phù hợp với bất cứ điều gì khác. Sự lựa chọn của bạn là một lớp tiện ích bao gồm các bit chức năng không liên quan khác nhau hoặc một lớp về cơ bản chỉ có một điều này.

Nếu bạn chỉ có một bit như thế này, thì lớp tĩnh của bạn là lớp cụ thể của bạn. Vì vậy, hoặc bạn có một hàm tạo thực hiện tất cả công việc hoặc một hàm duy nhất thực hiện tất cả công việc. Ưu điểm của việc thực hiện mọi thứ trong hàm tạo là nó chỉ xảy ra một lần, nó cho phép bạn sử dụng các trường, thuộc tính và phương thức riêng mà không lo chúng bị tái sử dụng hoặc xâu chuỗi. Nếu bạn có một hàm tạo / phương thức, bạn có thể bị cám dỗ để cho các tham số được truyền cho một phương thức duy nhất, nhưng nếu bạn sử dụng các trường riêng hoặc các dự đoán giới thiệu các vấn đề luồng tiềm năng.

Ngay cả với một lớp tiện ích, hầu hết mọi người sẽ không nghĩ rằng có các lớp tĩnh lồng nhau (và điều đó có thể không thể tùy thuộc vào ngôn ngữ).

Về cơ bản, đây là một cách tương đối dễ hiểu để cô lập hành vi với phần còn lại của hệ thống, trong phạm vi được ngôn ngữ cho phép, trong khi vẫn cho phép bạn tận dụng càng nhiều ngôn ngữ càng tốt.

Thành thật mà nói tôi sẽ trả lời nhiều như nhà thầu của bạn đã làm, đó là một điều chỉnh nhỏ để biến nó thành hai cuộc gọi, không có gì nhiều để đề xuất một cuộc gọi khác. Những gì dis / advatanges có, có lẽ là giả thuyết hơn thực tế, tại sao cố gắng biện minh cho quyết định khi nó không quan trọng và có lẽ nó không được quyết định nhiều như chỉ là hành động mặc định?


1

Có các mẫu phổ biến trong các ngôn ngữ nơi các hàm và các lớp giống nhau nhiều hơn, như Python, trong đó một mẫu sử dụng một đối tượng về cơ bản là hàm với quá nhiều tác dụng phụ hoặc có nhiều đối tượng được đặt tên trả về.

Trong trường hợp này, phần lớn, nếu không phải tất cả các công việc có thể được thực hiện trong hàm tạo, vì bản thân đối tượng chỉ là một trình bao bọc xung quanh một bó công việc duy nhất và không có lý do chính đáng nào để nhét nó vào một hàm riêng biệt. Cái gì đó như

var parser = XMLParser()
var x = parser.parse(string)
string a = x.LookupTag(s)

thực sự không tốt hơn

 var x = ParsedXML(string)
 string a = x.LookupTag(s)

Thay vì trực tiếp có các tác dụng phụ hoàn toàn, bạn có thể gọi đối tượng để thực thi hiệu ứng phụ trên cue, giúp bạn nhìn rõ hơn. Nếu tôi có tác dụng phụ xấu đối với một đối tượng, tôi có thể thực hiện tất cả công việc của mình và sau đó vượt qua đối tượng, tôi sẽ ảnh hưởng xấu và gây thiệt hại cho nó. Xác định đối tượng và cách ly cuộc gọi theo cách này rõ ràng hơn là chuyển nhiều đối tượng như vậy vào một chức năng cùng một lúc.

x.UpdateView(v)

Bạn có thể thực hiện nhiều giá trị trả về thông qua các bộ truy cập trên đối tượng. Tất cả công việc đã hoàn thành, nhưng tôi muốn tất cả mọi thứ trong ngữ cảnh và tôi thực sự không muốn chuyển nhiều tài liệu tham khảo vào chức năng của mình.

var x = new ComputeStatistics(inputFile)
int max = x.MaxOptions;
int mean = x.AverageOption;
int sd = x.StandardDeviation;
int k = x.Kurtosis;
...

Vì vậy, với tư cách là một lập trình viên Python / C # chung, điều này dường như không có gì lạ đối với tôi.


Tôi cần làm rõ rằng ví dụ đã cho vẫn còn sai lệch. Trong ví dụ không có người truy cập và không có giá trị trả về, đây có thể là dấu tích. Có lẽ bản gốc được cung cấp trả về gỡ lỗi hoặc một cái gì đó.
Jon Jay Obermark

1

Một trường hợp xuất hiện trong đó trình xây dựng / hàm hủy thực hiện tất cả công việc:

Khóa. Bạn thường không bao giờ tương tác với một khóa trong suốt cuộc đời của nó. Sử dụng kiến ​​trúc của C # là tốt để xử lý các trường hợp như vậy mà không đề cập rõ ràng đến hàm hủy. Không phải tất cả các khóa được thực hiện theo cách này, mặc dù.

Tôi cũng đã viết những gì lên tới một đoạn mã chỉ dành cho nhà xây dựng để vá lỗi thư viện thời gian chạy. (Trên thực tế việc sửa mã sẽ gây ra các vấn đề khác.) Không có hàm hủy vì không cần hoàn tác bản vá.


-1

Tôi đồng ý với AndyBursh. Có vẻ như một số vấn đề thiếu kiến ​​thức.

Tuy nhiên, điều quan trọng là phải đề cập đến các khung như NHibernate yêu cầu bạn chỉ cần mã trong hàm tạo (khi tạo các lớp bản đồ). Tuy nhiên đây không phải là giới hạn của khung, nó chỉ là thứ bạn cần. Khi nói đến sự phản chiếu, hàm tạo là phương thức duy nhất sẽ luôn tồn tại (mặc dù nó có thể là riêng tư) và điều này có thể hữu ích nếu bạn phải gọi một phương thức của lớp một cách linh hoạt.


-4

"Tôi đã được dạy từ lâu rằng các đối tượng khởi tạo trong một vòng lặp thường là một ý tưởng tồi"

Vâng, có thể bạn đang nhớ lại lý do tại sao chúng tôi cần StringBuilder.

Có hai trường Java.

Trình xây dựng được quảng bá bởi cái đầu tiên , dạy chúng ta sử dụng lại (vì chia sẻ = nhận dạng để hiệu quả). Tuy nhiên, vào đầu năm 2000 tôi đã bắt đầu đọc rằng việc tạo các đối tượng trong Java rất rẻ (trái ngược với C ++) và GC hiệu quả đến mức việc sử dụng lại là vô ích và điều duy nhất quan trọng là năng suất của lập trình viên. Để có năng suất, anh ta phải viết mã có thể quản lý, có nghĩa là mô đun hóa (hay còn gọi là thu hẹp phạm vi). Vì thế,

Thật tệ

byte[] array = new byte[kilos or megas]
for_loop:
  use(array)

điều này là tốt

for_loop:
  byte[] array = new byte[kilos or megas]
  use(array)

Tôi đã hỏi câu hỏi này khi forum.java.sun tồn tại và mọi người đồng ý rằng họ muốn khai báo mảng càng hẹp càng tốt.

Lập trình viên java hiện đại không bao giờ ngần ngại khai báo một lớp mới hoặc tạo một đối tượng. Ông được khuyến khích để làm như vậy. Java đưa ra tất cả lý do để làm như vậy, với ý tưởng rằng "mọi thứ đều là đối tượng" và sáng tạo giá rẻ.

Hơn nữa, phong cách lập trình doanh nghiệp hiện đại là, khi bạn cần thực hiện một hành động, bạn tạo một lớp đặc biệt (hoặc thậm chí tốt hơn, một khung công tác) sẽ thực hiện hành động đơn giản đó. IDE Java tốt, giúp đỡ ở đây. Họ tự động tạo ra hàng tấn crap, như hơi thở.

Vì vậy, tôi nghĩ rằng các đối tượng của bạn thiếu mẫu Builder hoặc Factory. Nó không phải là tốt để tạo ra các trường hợp trực tiếp, bởi nhà xây dựng. Một lớp nhà máy đặc biệt cho mọi đối tượng của bạn được khuyên.

Bây giờ, khi lập trình chức năng bắt đầu hoạt động, việc tạo các đối tượng thậm chí còn đơn giản hơn. Bạn sẽ tạo ra các vật thể ở mỗi bước như hơi thở, mà thậm chí không nhận thấy điều này. Vì vậy, tôi hy vọng mã của bạn sẽ trở nên "hiệu quả" hơn nữa trong kỷ nguyên mới

"không làm gì trong hàm tạo của bạn. Nó chỉ dành cho khởi tạo"

Cá nhân, tôi thấy không có lý do trong hướng dẫn. Tôi coi đó chỉ là một phương pháp khác. Bao thanh toán mã là cần thiết chỉ khi bạn có thể chia sẻ nó.


3
lời giải thích không có cấu trúc tốt và khó theo dõi. Bạn chỉ cần đi khắp nơi với khẳng định có thể tranh cãi mà không có liên kết đến bối cảnh.
New Alexandria

Tuyên bố thực sự có thể tranh cãi là "Các nhà xây dựng nên khởi tạo các trường của một đối tượng và thực hiện bất kỳ khởi tạo nào khác cần thiết để làm cho đối tượng sẵn sàng sử dụng". Nói với người đóng góp phổ biến nhất.
Val
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.