Các kỹ thuật lập trình bị lạm dụng hoặc lạm dụng [đóng]


38

Có bất kỳ kỹ thuật nào trong lập trình mà bạn thấy bị lạm dụng (IE sử dụng quá mức so với những gì họ nên làm) hoặc lạm dụng, hoặc sử dụng một chút cho mọi thứ, trong khi không phải là một giải pháp thực sự tốt cho nhiều vấn đề mà mọi người cố gắng giải quyết với nó

Nó có thể là các biểu thức chính quy, một số kiểu mẫu thiết kế hoặc có thể là một thuật toán hoặc một cái gì đó hoàn toàn khác. Có thể bạn nghĩ rằng mọi người lạm dụng nhiều di sản, vv


33
Tôi đồng ý rằng IE được sử dụng quá mức so với mức cần thiết, nhưng chủ yếu là bởi những người không lập trình. . .
Eric Wilson

7
@FarmBoy - Tôi nghĩ ý anh ấy là IE: "Tức là" viết tắt của "nghĩa là", được viết hoàn toàn bằng tiếng Latin là 'id est'.
Raphael

Đã sửa lỗi ngay bây giờ :)
Anto

4
Bất kỳ kỹ thuật nào cũng có thể (và thường bị lạm dụng), nó chỉ cần được trình bày như viên đạn bạc tiếp theo và bạn sẽ tìm thấy ai đó coi mọi vấn đề là một cái đinh (để trộn lẫn các ẩn dụ).
ChrisF

8
@Rapheal - Tôi đã nói đùa, tất nhiên. Cảm ơn sự giáo dục.
Eric Wilson

Câu trả lời:


73

Nhận xét trong mã

Tôi chỉ mong các Giáo sư Đại học sẽ hiểu rằng họ không cần phải dạy sinh viên của mình viết 10 dòng bình luận nói rằng đoạn mã sau đây là một vòng lặp, lặp từ 1 đến số x. Tôi có thể thấy điều đó trong mã!

Dạy chúng viết mã tự viết tài liệu trước sau đó nhận xét thích hợp về những gì không thể tự viết đầy đủ thứ hai. Thế giới phần mềm sẽ là một nơi tốt hơn.


26
Mã tự viết tài liệu không. Các giáo sư cũng làm điều này để dạy sinh viên khái niệm hóa vấn đề và cách tiếp cận nó. Ngoài ra, tôi chưa bao giờ thấy ai phàn nàn về quá nhiều tài liệu. Hãy cẩn thận là tài liệu là chính xác.
Woot4Moo

24
@ Woot4Moo: nếu bạn đọc Clean Code, Fowler nói rõ rằng tài liệu lỗi thời còn tệ hơn không có tài liệu và tất cả các bình luận đều có xu hướng trở nên cũ kỹ và di chuyển ra khỏi mã mà họ tài liệu. Toàn bộ cuốn sách là tất cả về cách viết mã tự viết.
Scott Whitlock

12
Dạy họ thay thế các bình luận bằng mã sẽ là một khởi đầu tốt ...
Shog9

15
+1. Tôi thực sự đã thấy những điều sau đây trong mã thế giới thực: "loopVar ++; // tăng loopVar". AAAAAAAAAAAAARRRRRGH!
Bàn Bobby

7
@Bill: Tôi đồng ý rằng bạn không cần phải ghi lại các cấu trúc logic và điều khiển chung, ngay cả khi chúng tương đối phức tạp. Về cơ bản, bất cứ điều gì mà một nhà phát triển giỏi biết ngôn ngữ sẽ có thể giải quyết bằng cách phân tích mã không cần phải bình luận. ví dụ. Một tập hợp các vòng lặp lồng nhau với một số ngắt bên trong chúng, v.v. "Nếu một lập trình viên mới bắt đầu tại công ty vào ngày mai và xem mã, liệu nó có ý nghĩa gì nếu không có gợi ý nhận xét?"
Bàn Bobby

57

Các mẫu thiết kế singleton.

Chắc chắn, đó là một mẫu hữu ích nhưng mỗi khi một lập trình viên mới biết về mẫu này, anh ta bắt đầu cố gắng áp dụng nó cho mỗi lớp mà anh ta tạo ra.


Tôi sử dụng lý do được thiết kế kém này cho một khung mỗi ngày. codeigniter.com/user_guide/lologists/email.html Họ nghĩ rằng OOP là các hàm tiền tố với $this->. PHP là một ngôn ngữ mục nát, vì vậy tôi không thể mong đợi các khung công tác là tuyệt vời.
Keyo

7
Tôi nghĩ rằng bất kỳ lập trình viên nào thực hiện một singleton và không ăn năn sẽ bị thiêu trong một địa ngục rực lửa vì tội lỗi mà anh ta (hoặc cô ta) đã phạm phải.

2
Tôi đã thực hiện một singleton một lần trong sự nghiệp chuyên nghiệp của mình (trong bối cảnh đa nhiệm) và tôi đã phải ăn năn tội lỗi của mình bằng cách viết lại nó.
Spoike

3
Singletons có thể hữu ích cho một số thứ, nhưng hầu như luôn được sử dụng khi không nên sử dụng. Điều đó không có nghĩa là không nên sử dụng singletons - chỉ vì thứ gì đó bị lạm dụng không có nghĩa là nó không thể được sử dụng một cách chính xác.
cấu hình

2
@Rapahel: Đó chính xác là lý do tại sao tôi không tin nghiên cứu các mẫu thiết kế là một điều tốt.
cấu hình

53

Điều xấu xa nhất để bảo vệ lập trình câm. đặt mọi thứ vào một cái bẫy thử và không làm gì với cái bẫy

        try
        {
            int total = 1;
            int avg = 0;
            var answer = total/avg;
        }
        catch (Exception)
        {

        }

Tôi rùng mình khi thấy một cái bẫy thử không làm gì cả và được thiết kế để xử lý logic ngu ngốc. Nói chung, các sản phẩm khai thác thử được sử dụng quá mức, tuy nhiên trong một số trường hợp rất hữu ích.


4
Điều thú vị - Tôi vừa mới chỉnh sửa một tập tin thực hiện điều đó hàng trăm lần và với lý do chính đáng. Đó là một tệp thử nghiệm đơn vị, thử nghiệm rằng các phương pháp khác nhau đưa ra một ngoại lệ khi dự kiến. Khối thử chứa một cuộc gọi và báo cáo "dự kiến ​​không xảy ra". Ngoại lệ được mong đợi và chính xác, vì vậy không có hành động khắc phục. Rõ ràng các bài kiểm tra đơn vị là một trường hợp đặc biệt, nhưng tôi đã có trường hợp tương tự trong mã thực. Cờ đỏ, có, nhưng không phải là một quy tắc tuyệt đối.
Steve314

5
@Steve trường hợp bạn mô tả là một điều kiện cạnh hiếm. Một cách khác tôi có thể nghĩ đến là đăng nhập mã - nếu bản thân việc đăng nhập thất bại, sẽ không có điểm nào cố gắng đăng nhập ngoại lệ hoặc làm gián đoạn ứng dụng.
dbkk

1
@dbkk - đã đồng ý với điều kiện cạnh và tôi nói thêm rằng khi bạn thực sự cần phải có một ngoại lệ nhưng không cần một hành động khắc phục, thêm một nhận xét trong khối bắt để giải thích điều đó là cần thiết nếu chỉ để làm dịu người bảo trì. Nó không quá hiếm trong các bài kiểm tra đơn vị, vì vậy tôi sẽ bỏ điều nhận xét trong trường hợp đó.
Steve314

5
tiếp tục lỗi tiếp theo
jk.

2
@ jk01 - một ngoại lệ không (nhất thiết) là một lỗi. Cho dù bất kỳ điều kiện là một lỗi hay không phụ thuộc vào bối cảnh. Ví dụ: "không tìm thấy tệp" không phải là lỗi nếu bạn không cần tệp. Có lẽ đó chỉ là một tệp cài đặt tùy chọn có thể có hoặc không có và bạn chỉ có thể để mặc định của mình nếu tệp không có ở đó (vì vậy không cần thực hiện hành động khắc phục nào sau khi bắt).
Steve314

47

Dựa vào StackOverflow để giải quyết vấn đề của bạn thay vì tìm ra nó một cách khó khăn.

Các lập trình viên mới tìm thấy sự giàu có của kiến ​​thức về SO (quá thường xuyên) đăng trước khi suy nghĩ và thử mọi thứ.

Trong thời của tôi, chúng tôi phải viết mã từ sách, không có internet, không có SO. Bây giờ có được ra bãi cỏ của tôi.


28
Tôi phải thừa nhận, tôi nao núng trước sự táo bạo của một số câu hỏi về SO. Hoặc bởi vì họ được hỏi nhiều lần mỗi ngày và rõ ràng họ không tìm kiếm gì cả; hoặc tệ hơn nữa, họ coi cộng đồng là một dịch vụ gia công miễn phí.
Orble

2
@dbkk: stackoverflow.com/questions/4665778/ trên -> bình luận đầu tiên "bạn đã bao giờ thử cái này chưa?"
Matthieu M.

5
Tôi bắt đầu học từ sách nhưng một khi tôi có một nền tảng, tôi đã học được hầu hết mọi thứ khác từ các cuộc thảo luận trên diễn đàn trực tuyến. Không phải bằng cách hỏi, mà chủ yếu (và lúc đầu, độc quyền) bằng cách đọc. Phương pháp này đã dạy cho tôi một số ngôn ngữ lập trình chuyên sâu (với rất nhiều ngóc ngách) và tôi nghĩ đó không phải là một phương pháp tồi.
Konrad Rudolph

1
@Konrad Rudolph: Phương pháp đó tốt và khôn ngoan, đọc câu hỏi, tìm kiếm tốt. Câu hỏi được thực hiện tốt nhất khi người hỏi có một khung để hiểu câu trả lời. Mọi người thường đặt câu hỏi mà họ không (chưa) có khả năng hiểu.
Orble

3
vấn đề là SO khuyến khích điều này bằng cách đưa ra nhiều đại diện để hỏi / trả lời câu hỏi rất dễ có thể trả lời bằng tìm kiếm google đơn giản. câu hỏi rất khó mọi người trả lời chỉ vì họ thực sự muốn.
IAd CHƯƠNG

36

OOP hiển nhiên. Nó rất có giá trị, nhưng khi sử dụng sai, nó có thể che khuất mã rõ ràng một cách dễ dàng (một số ví dụ về lập trình S4 trong R), và có thể cung cấp một chi phí rất lớn không cần thiết và có thể khiến bạn mất thời gian lớn về hiệu suất.

Một điều nữa là (ví dụ Perl) OOP thường viết ra điều tương tự theo cách khác: result = $object ->function(pars)thay vì result = function(object, pars)Điều này đôi khi có ý nghĩa, nhưng khi trộn lẫn với lập trình thủ tục, nó có thể khiến việc đọc mã khá khó hiểu. Và ngoài ra, bạn chỉ giới thiệu thêm chi phí mà không cải thiện thiết kế. Nó cũng nói về những gì được nói về mẫu singleton: Nên được sử dụng, nhưng không phải trên tất cả mọi thứ.

Bản thân tôi sử dụng OOP, nhưng trong lĩnh vực của tôi (tính toán khoa học) là một vấn đề lớn và OOP thường bị lạm dụng ở đó vì tất cả các sinh viên đều có Java ngày nay. Thật tuyệt vời khi xử lý các vấn đề lớn hơn, để khái niệm hóa và vân vân. Nhưng nếu bạn làm việc với các chuỗi DNA trong BioPerl, sử dụng các đối tượng mọi lúc và làm việc nhất quán với getters và setters có thể tăng thời gian tính toán lên gấp 10 lần. Khi mã của bạn đang chạy một vài ngày thay vì một vài giờ, sự khác biệt đó thực sự quan trọng.


6
@Craige: Bản thân tôi sử dụng OOP, nhưng trong lĩnh vực của tôi (tính toán khoa học) là một vấn đề lớn và OOP thường bị lạm dụng ở đó vì tất cả các sinh viên hiện nay đều có Java. Thật tuyệt vời khi xử lý các vấn đề lớn hơn, để khái niệm hóa và vân vân. Nhưng nếu bạn làm việc với các chuỗi DNA trong BioPerl, sử dụng các đối tượng mọi lúc và làm việc nhất quán với getters và setters có thể tăng thời gian tính toán lên gấp 10 lần. Khi mã của bạn đang chạy một vài ngày thay vì một vài giờ, sự khác biệt đó thực sự quan trọng.
Joris Meys

1
@Craige: Phương pháp xâu chuỗi (như Foo.DoX().DoY().DoZ()) là tốt, nhưng, nhưng chắc chắn đó không phải là cách duy nhất để nói về điều gì đó. Thành phần chức năng (như doZ . doY . doX $ foolà một sự thay thế hoàn toàn hợp lệ.
Anon.

1
@Joris: một điều mà tôi đã băn khoăn trong một thời gian dài (bản thân tôi là một nhà sinh lý học): nếu hiệu suất quan trọng đến vậy, tại sao lại sử dụng Perl ở nơi đầu tiên thay vì C ++? Nếu bạn lo lắng về việc loại bỏ yếu tố 10 khỏi thời gian chạy (mối quan tâm hợp lệ!) Thì việc chuyển sang C ++ mang lại cho bạn sự hài lòng ngay lập tức. Tất nhiên, ngôn ngữ này rất hấp dẫn nhưng sau đó, Perl cũng vậy và có những thư viện tin sinh học tốt cho C ++.
Konrad Rudolph

1
@Konrad: Nó phụ thuộc. BioPerl được cho là hầu hết các gói dành cho các nhà sinh học từ tất cả các ngôn ngữ (tôi nghĩ rằng Python đang bắt kịp). Thêm vào đó, rất nhiều công việc đã được thực hiện trong Perl và việc điều chỉnh một kịch bản dễ dàng hơn là viết lại mọi thứ trong C ++. Cuối cùng, nó không phục vụ để viết một ứng dụng hoàn chỉnh khi một kịch bản sẽ làm. Đoán đó là lý do tại sao Perl vẫn còn nhiều như vậy. Và thành thật mà nói, tôi không phiền, tôi thích ngôn ngữ này. Nó vẫn là tốt nhất tôi biết cho công việc chuỗi và tập tin. Các tính toán rõ ràng được thực hiện bằng các ngôn ngữ khác và được liên kết lại (điều này khá dễ dàng).
Joris Meys

1
@Konrad: nó phụ thuộc vào cách người ta làm điều đó. Có thể thực hiện tất cả trong Perl, nhưng Perl có thể dễ dàng liên kết với các công cụ khác, đặc biệt là trên Linux. Tôi thường xuyên sử dụng Perl như một tập lệnh bash nâng cao với thao tác chuỗi mạnh mẽ và dễ dàng xây dựng các bộ dữ liệu để đưa vào các ứng dụng khác.
Joris Meys

27

Đã dành vài năm trong ASP.NET Webforms, tôi phải nói một cách dứt khoát:

Giao diện người dùng thông minh

Mặc dù hoàn toàn có thể tạo các ứng dụng phân lớp, có thể kiểm tra trong các biểu mẫu web, Visual Studio giúp các nhà phát triển quá dễ dàng chỉ cần một cú nhấp chuột để tạo các liên kết chặt chẽ với nguồn dữ liệu của họ, với logic ứng dụng nằm rải rác trong tất cả mã UI.

Steve Sanderson giải thích cách chống mô hình này tốt hơn nhiều so với tôi có thể trong cuốn sách Pro ASP.NET MVC của mình:

Để xây dựng ứng dụng Giao diện người dùng thông minh, trước tiên, nhà phát triển xây dựng giao diện người dùng, thường bằng cách kéo một loạt các tiện ích UI vào khung vẽ, sau đó điền mã xử lý sự kiện cho mỗi lần nhấp nút có thể hoặc sự kiện UI khác. Tất cả logic ứng dụng nằm trong các trình xử lý sự kiện này: logic để chấp nhận và xác thực đầu vào của người dùng, để thực hiện truy cập và lưu trữ dữ liệu và cung cấp phản hồi bằng cách cập nhật giao diện người dùng. Toàn bộ ứng dụng bao gồm các trình xử lý sự kiện này. Về cơ bản, đây là những gì có xu hướng xuất hiện theo mặc định khi bạn đặt một người mới trước Visual Studio. Trong thiết kế này, không có bất kỳ mối quan tâm nào. Mọi thứ được hợp nhất với nhau, chỉ được sắp xếp theo các sự kiện UI khác nhau có thể xảy ra. Khi logic hoặc quy tắc kinh doanh cần được áp dụng trong nhiều trình xử lý, mã thường được sao chép và dán, hoặc các phân đoạn được chọn ngẫu nhiên nhất định được đưa vào các lớp tiện ích tĩnh. Vì nhiều lý do rõ ràng, loại mẫu thiết kế này thường được gọi là mẫu chống.


1
GUI ít nhất là một số loại mã đặc tả phải tuân thủ. Tôi không nghĩ rằng các lập trình viên mà anh ta mô tả sẽ làm tốt hơn nếu được trình bày với một tệp văn bản trống thay thế.

4
@qpr, tôi không biết về điều đó. Nếu họ có một tệp văn bản trống, họ có thể không thể làm bất cứ điều gì (có thể chỉ là một phần thưởng).
Ken Henderson

Một trong nhiều lợi ích của việc sử dụng WPF là việc triển khai MVVM sẽ phá vỡ mô hình chống này thành smithereens.
Robert Rossney

2
Một ngàn lần này. Tôi thậm chí còn thấy các nhà phát triển .NET có kinh nghiệm dựa vào "mẫu" này bởi vì nó dễ hơn là hiểu hoặc quan tâm đến Tách biệt các mối quan tâm. Ngay cả khi họ không sử dụng trình hướng dẫn kéo và thả, "mẫu" phổ biến nhất trong phát triển .NET WebForms là thực hiện mọi thứ trong các sự kiện đằng sau mã và sao chép / dán mã khi cần.
Wayne Molina

23

Thỉnh thoảng tôi thấy điều này và nó thường xuất phát từ việc không hiểu đầy đủ các biểu thức boolean.

if (someCondition == true)

16
Nó có lợi thế là làm cho mã rõ ràng hơn
Pemdas

7
Tôi nghĩ rằng nhìn vào câu hỏi này là theo thứ tự: programmers.stackexchange.com/questions/12807/...
gablin

5
Tôi không làm điều đó nhưng, nghiêm túc, vượt qua nó. Có một địa ngục tồi tệ hơn nhiều ngoài kia. :)
MetalMikester

4
Nếu bạn đặt tên cho các biến của mình đúng cách, ví dụ boolbắt đầu bằng ishoặc has, bạn không cần phải làm cho mã của mình rõ ràng hơn = true.
Không ai là

3
@DisgruntledGoat vì hoàn toàn không nên sử dụng
Corey

19

Thực hiện lại chức năng cốt lõi (hoặc được cung cấp theo cách khác), vì sự thiếu hiểu biết về sự tồn tại của nó hoặc do nhu cầu nhận thức về các tùy chỉnh.


2
Học tập là một ngoại lệ. Khi nghiên cứu bất cứ điều gì, thường có lợi khi "phát minh lại bánh xe".
Tối đa

Chắc chắn - Tôi nên đã chỉ định rằng nó chỉ liên quan khi tạo phần mềm sản xuất.
l0b0

1
Điều này đặc biệt xấu khi thực hiện bất cứ điều gì liên quan đến bảo mật. Phần mềm bảo mật tốt ngăn chặn các cuộc tấn công mà hầu hết mọi người thậm chí không bao giờ nghĩ tới.
David Thornley

Tôi thấy cách này quá phổ biến. Chúng ta cần X, hãy viết riêng của chúng tôi! Nhưng còn gói nguồn mở Y thì sao? Không, chúng tôi cần phần mềm tùy chỉnh cho các bí mật thương mại siêu bí mật giống như mọi người khác trong ngành của chúng tôi, chúng tôi không thể sử dụng phần mềm rác thông thường!
Wayne Molina

18

Di sản.

Đừng thi hành là một nơi không có ý nghĩa.


6
Vấn đề là trực giác là một trò chơi trực tuyến rất thường có ý nghĩa (đặc biệt là vì mọi mối quan hệ thực hiện / hợp đồng có thể được biểu hiện một cách thông thường là một cách khó khăn). Nó đòi hỏi một sự hiểu biết vững chắc về OOP để nhận ra rằng trên thực tế đây là một sai lầm, và việc kế thừa và thực hiện giao diện là khác nhau về cơ bản.
Konrad Rudolph

@Konrad - Hoàn toàn đồng ý. Tôi cố gắng khuyến khích mọi người bắt đầu với thành phần , chuyển sang giao diện và xem xét kế thừa sau cùng. (Như một quy tắc của ngón tay cái, tất nhiên). Nhưng có lẽ đó là nền tảng VB của tôi đang nói chuyện ... ;-)
Mike Woodhouse

1
Điều này phần lớn là một câu hỏi thiết kế ngôn ngữ, mặc dù. Lý do tại sao bạn nên "thích sáng tác hơn (triển khai) kế thừa" trong các ngôn ngữ như Java hoặc C #, là vì tính kế thừa triển khai hút trong các ngôn ngữ đó. Một số người chỉ trích Xây dựng phần mềm hướng đối tượng của Bertrand Meyer vì lạm dụng thừa kế, nhưng khi bạn thực sự nhìn vào Eiffel (ngôn ngữ được sử dụng trong cuốn sách), bạn nhận ra rằng nó được thiết kế để kế thừa thực hiện và do đó thực sự sử dụng kế thừa thành phần. Trong trường hợp đó , ít nhất.
Jörg W Mittag

14

Tùy chỉnh phần mềm sẵn có.

Mặc dù tôi có thể thừa nhận điều này có thể hữu ích, tôi tự hỏi bao nhiêu tiền được chi cho việc hoàn thành những việc nhỏ để kiếm lợi nhuận đáng ngờ. Đây là nơi một công ty có thể chi hàng trăm nghìn nếu không phải hàng triệu đô la cho giấy phép cho một số phần mềm sau đó được tùy chỉnh vì nó có thể cấu hình, có thể chỉnh sửa và linh hoạt đến mức nó thực sự không làm được gì nhiều theo mặc định. Cuối cùng, nó là một ứng dụng tùy chỉnh vì tất cả các mã mới được thêm vào những gì ban đầu được mua.


Đây không phải là nhiều khả năng là một trường hợp với một ứng dụng tùy chỉnh?
JeffO

13

Sử dụng trình biên dịch như một trình sửa lỗi.

Bỏ qua các cảnh báo trình biên dịch hoặc tắt chúng hoàn toàn.

Biến toàn cầu.


18
Có gì sai với "sử dụng trình biên dịch làm trình gỡ lỗi"? Có một trình biên dịch có thể chỉ ra các lỗi trong mã của bạn trước khi chúng trở thành một vấn đề trong thời gian chạy là một lợi thế to lớn.
Mason Wheeler

3
Tôi dựa vào trình biên dịch bắt lỗi cú pháp của tôi và các lỗi khớp kiểu không chính xác. Đối với các lỗi hành vi, tôi dựa vào các trường hợp thử nghiệm.
gablin

5
Vấn đề là khi bạn bắt đầu phụ thuộc vào trình biên dịch để đảm bảo tính chính xác của chương trình. Điều này đã được biên dịch? Không, hãy để tôi munge phần nhỏ này và xem nếu nó đã sửa nó. Nó đã biên dịch? Không, hãy để tôi thêm một * ở đây và ở đó và xem nếu biên dịch. ... Ect. Rõ ràng, nó hữu ích cho việc sửa lỗi chính tả
Pemdas

2
Bạn nói rằng như thể lập trình viên đang chọc ngoáy một cách mù quáng trong bóng tối cố gắng làm một cái gì đó - bất cứ điều gì - để có được mã để bằng cách nào đó biên dịch. Đó không phải là cách nó hoạt động IME; trình biên dịch cung cấp cho bạn một thông báo lỗi hữu ích và chỉ cho bạn biết vị trí lỗi và thông thường nếu có gì đó không biên dịch mã mới mà bạn tự viết, vì vậy bạn có một ý tưởng khá hay là sai và cách khắc phục khi nó được chỉ ra ngoài. (Mặc dù nếu bạn tung ngẫu nhiên * xung quanh, bạn có thể đang làm việc trong C ++, trong đó lỗi trình biên dịch được biết là cực kỳ không có ích, vì vậy những gì tôi nói có thể không áp dụng.)
Mason Wheeler

3
Dựa vào trình biên dịch hoạt động rất tốt, được cung cấp một hệ thống loại đủ mạnh và cơ sở mã được gõ tốt. Thông thường, hệ thống loại có thể mô hình hóa các ràng buộc quan trọng mà nếu không bạn phải viết các bài kiểm tra (ví dụ: trong các hệ thống được gõ yếu). Được sử dụng một cách thận trọng, trình biên dịch (và đặc biệt là trình kiểm tra loại của nó) là một tài sản tuyệt vời để kiểm tra và gỡ lỗi, và không có sai khi dựa vào nó. Cụ thể, thật sai khi nói rằng trình biên dịch chỉ có thể hiển thị lỗi cú pháp.
Konrad Rudolph

11

Tất cả các mẫu thiết kế.

Chúng giống như muối hoặc đường. Một số trong số chúng trên thực phẩm của bạn làm cho nó tuyệt vời, rất nhiều trong số chúng, làm cho thực phẩm của bạn hút.

Đừng hiểu lầm tôi. Mẫu thiết kế là những kỹ thuật tuyệt vời. Tôi đã sử dụng chúng rất nhiều. Nhưng đôi khi, tôi tìm thấy các lập trình viên, (một số trong số họ là ông chủ cũ của tôi), người đã có những "bạn phải sử dụng một mẫu thiết kế", ngay cả khi không phù hợp với vấn đề !!!

Một ví dụ là "Mẫu khách truy cập", người được định hướng nhiều hơn cho "Bộ sưu tập Lineal / Sequential". Tôi đã phải làm việc với một cấu trúc dữ liệu cây, một lần. Để "truy cập" từng mục, tôi mã hóa một phương thức mẫu không thiết kế và một ông chủ cũ khăng khăng sử dụng hoặc điều chỉnh "Mẫu khách truy cập". Sau đó, tôi duyệt mạng, cho ý kiến ​​thứ hai. Vâng, các lập trình viên khác có cùng một tình huống, và cùng một giải pháp. Và gọi nó là "Mẫu khách truy cập cây / phân cấp"., Như một mẫu thiết kế MỚI

Tôi hy vọng nó được thêm vào như một mẫu mới cho các mẫu hiện có, trong phiên bản mới của cuốn sách "Mẫu thiết kế".


3
Tôi không bao giờ sử dụng các mẫu thiết kế, mặc dù đôi khi chúng xuất hiện tự nhiên trong mã của tôi.
cấu hình

Làm thế nào để nói đi? Bạn bắt đầu sử dụng các mẫu mà không biết bạn đang sử dụng chúng, sau đó bạn tìm hiểu về chúng và sử dụng chúng ở mọi nơi, sau đó chúng trở thành bản chất thứ hai để bạn bắt đầu sử dụng chúng mà không biết bạn đang sử dụng chúng?
Wayne Molina

2
@configurator Khi tôi đọc về các mẫu thiết kế; Tôi cũng phát hiện ra rằng tôi và các nhà phát triển khác đã sử dụng một số trong số họ ;-)
umlcat

9

Sử dụng ngoại lệ như kiểm soát dòng chảy. Sắp xếp tương tự như câu trả lời này , nhưng khác nhau.

Nuốt ngoại lệ là hình thức xấu vì nó giới thiệu các lỗi bí ẩn, khó tìm trong mã. Mặt khác, sử dụng các ngoại lệ như kiểm soát luồng, là xấu vì nó làm cho mã kém hiệu quả hơn nhiều so với khả năng và về mặt khái niệm là cẩu thả.

Xử lý ngoại lệ chỉ nên được sử dụng để xử lý các tình huống thực sự đặc biệt (duh), không lường trước được, không phải là những thứ như người dùng nhập vào một ký tự chữ cái trong đó một số được mong đợi. Kiểu lạm dụng ngoại lệ này cực kỳ phổ biến đối với các lập trình viên xấu trong thế giới Java.


Các ngoại lệ tạo mã không hiệu quả phụ thuộc vào ngôn ngữ của bạn - tạo khung ngăn xếp, v.v. Trong Squeak, ngăn xếp của bạn được thống nhất hoàn toàn, do đó không có sự khác biệt giữa việc sử dụng ngoại lệ hay không. (Nói cách khác, trường hợp ngoại lệ là một phần của thư viện, không phải là ngôn ngữ.) Tuy nhiên, nó được gây nhầm lẫn làm việc với dòng điều khiển ngoại lệ kiểm soát: lshift.net/blog/2011/01/04/try-again-with-exceptions show một ngoại lệ sử dụng vòng lặp mà tôi tìm thấy gần đây.
Frank Shearar

Về đoạn cuối, một lần nữa, nó phụ thuộc vào ngôn ngữ của bạn. Các ngoại lệ ("điều kiện") trong Common Lisp là sự thay thế nghiêm ngặt các ý tưởng ngoại lệ của hầu hết các ngôn ngữ. Xem ví dụ tại đây: gigamonkeys.com/book/ đá Như với mọi thứ, bạn có thể đi quá xa!
Frank Shearar

Khả năng đọc và bảo trì vượt xa hiệu suất. Các trường hợp tôi sẽ sử dụng ngoại lệ để thành công (theo ý tôi là "kiểm soát dòng chảy") là rất hiếm, nhưng chúng có thể cung cấp mã sạch hơn trong ví dụ tìm kiếm đệ quy phức tạp. Nhìn rộng ra, tôi đồng ý. Ví dụ: tôi có các thùng chứa với các phương thức lặp trả về sai khi đi ra khỏi phạm vi (phổ biến ở cuối vòng lặp), nhưng ném một ngoại lệ nếu iterator là "null" (một dấu hiệu có thể xảy ra của một loại không nhất quán nội bộ)
Steve314

7

Tôi sẽ đi với sự không linh hoạt thông qua việc ẩn dữ liệu quá mức.

Chúng ta đều biết rằng sự trừu tượng và che giấu việc thực hiện là tốt, nhưng nhiều hơn không phải lúc nào cũng tốt hơn. Quá liều, bạn có thể nhận được một kết quả không linh hoạt mà không thể đối phó với những thay đổi trong yêu cầu. Để xử lý thay đổi, bạn không chỉ phải sửa đổi lớp cần xử lý thay đổi đó mà còn phải tạo một cách để thông tin không bao giờ cần có trước đây có thể truy cập được mặc dù có các lớp ẩn dữ liệu.

Vấn đề là, như với tất cả các vấn đề tìm kiếm sự cân bằng cho mọi bối cảnh, nó cần có kinh nghiệm.



6

Trạng thái đột biến và vòng lặp. Bạn gần như không bao giờ cần chúng, và bạn hầu như luôn nhận được mã tốt hơn mà không có chúng.

Ví dụ: cái này được lấy trực tiếp từ luồng StackOverflow:

// ECMAScript
var thing, things_by_type = {};
for (var i = 0; i < things.length; i++) {
    thing = things[i];
    if(things_by_type[thing.type]) {
        things_by_type[thing.type].push(thing);
    } else {
        things_by_type[thing.type] = [thing];
    }
}

# Ruby
things_by_type = {}
things.each do |thing|
  (things_by_type[thing.type] ||= []) << thing
end

Cả hai đều làm điều tương tự. Nhưng tôi không có ý tưởng những gì họ đang làm. May mắn thay, câu hỏi thực sự giải thích những gì họ đang làm, vì vậy tôi đã có thể viết lại chúng như sau:

// ECMAScript
things.reduce(function (acc, thing) {
    (acc[thing.type] || (acc[thing.type] = [])).push(thing);
    return acc;
}, {});

# Ruby
things.group_by(&:type)

// Scala
things groupBy(_.type)

// C#
from thing in things group thing by thing.Type // or
things.GroupBy(thing => thing.Type);

Không có vòng lặp, và không có trạng thái đột biến. Vâng, không có, không có vòng lặp rõ ràng và không có bộ đếm vòng lặp.

Mã đã trở nên ngắn hơn nhiều, đơn giản hơn nhiều, giống như mô tả về những gì mã phải làm (đặc biệt là trong trường hợp Ruby, nó nói trực tiếp "nhóm các thứ theo loại") và ít bị lỗi hơn. Không có nguy cơ chạy hết mảng, lỗi hàng rào hoặc lỗi do lỗi với các chỉ số vòng lặp và điều kiện kết thúc, bởi vì không có chỉ số vòng lặp và điều kiện kết thúc.


Tôi tin rằng trong dòng thứ hai của ECMAScript "cố định" của bạn nên đọc (acc[thing.type] || (acc[thing.type] = [])), trái ngược với `= [điều] điều đó , unless you want to add trong danh sách hai lần ... Hay tôi đang thiếu thứ gì đó?
Austin Hyde

@Austin Hyde: Bạn nói đúng.
Jörg W Mittag

1
Ví dụ bản thảo đó là không thể hiểu được đối với nhiều lập trình viên. Nó dựa vào quá nhiều thủ thuật cú pháp. Vòng lặp có lợi thế rõ ràng cho các nhà phát triển cơ sở.
Joeri Sebrechts

6

Chế giễu. Nó đưa ra quá nhiều yêu cầu giả tạo để tách mã quá mức vào mã của bạn, dẫn đến mã ravioli bị áp đảo và buộc thiết kế kiểu OO xuống cổ họng của bạn khi một thiết kế chức năng hoặc thủ tục hơn có thể là một giải pháp đơn giản hơn cho vấn đề của bạn.


Đồng ý trong lý thuyết; giả là hữu ích nhưng bạn không cần phải có chúng.
Wayne Molina

Sự xâm lấn của chế nhạo phụ thuộc vào ngôn ngữ bạn sử dụng. Trong C #, nó có thể rất xâm lấn và thêm các bè của các giao diện không cần thiết.
Frank Hileman

3

Các lập trình viên Delphi trên toàn thế giới đã phát hiện ra trong hai năm qua về việc sử dụng các mảng ký tự để lưu trữ byte do chuyển đổi Unicode toàn bộ sẽ tệ đến mức nào.

Và, "sớm thôi" chúng ta sẽ biết mức độ tệ của việc lưu trữ số nguyên trong danh sách khi chúng ta muốn thực hiện thay đổi thành 64 bit.


2
Tôi nghĩ rằng một phần lớn các vấn đề Unicode sẽ không bao giờ xuất hiện nếu Borland đã tuyên bố một loại DataString về cơ bản giống như AnsiString nhưng đặc biệt là để sử dụng với các đốm màu, và sau đó đảm bảo mọi người biết về nó.
Mason Wheeler

2

Tính chất. Tôi biết điều này đang gây tranh cãi, nhưng tôi cảm thấy rằng các thuộc tính được sử dụng quá mức trong .net.

Sự khác biệt giữa hai dòng này là gì?

public string Property { get; set; }

public string Field;

Đối với nhà phát triển, sự khác biệt là: hoàn toàn không có gì. Biểu mẫu được biên dịch hơi khác một chút, vì vậy nếu bạn đang viết thư viện thư viện đó sẽ được nâng cấp trong các chương trình bạn không thể tự biên dịch lại các chương trình (ví dụ: nếu bạn đang viết giao diện cho các plugin nên hoạt động trên các phiên bản phần mềm của bạn), sau đó bạn không nên sử dụng các trường công khai vì bạn không thể thay thế chúng bằng các thuộc tính. Trong mọi trường hợp khác, hoàn toàn không có sự khác biệt giữa việc sử dụng trường hoặc thuộc tính tự động mà không cần sửa đổi.


1
Đã đồng ý; nếu bạn biết 100% bạn sẽ không bao giờ cần phải làm gì với việc nhận / đặt "tài sản" thì không có lý do gì để có một tài sản. Tuy nhiên, nếu có cơ hội bạn sẽ cần phải làm gì đó (ví dụ: ghi lại giá trị đã được thay đổi) thì bạn nên sử dụng một thuộc tính. Cá nhân tôi không thấy một sự khác biệt đủ lớn để không sử dụng tài sản, chỉ trong trường hợp bạn làm cần phải sửa đổi nó sau này (Tôi biết, tôi biết YAGNInhưng tôi cảm thấy sai lệch trong trường hợp này không chi phí bất cứ điều gì)
Wayne Molina

2
@Wayne: Làm thế nào ;để thay đổi thành { get { ... } set { ... } }bất kỳ công việc nào hơn là thay đổi { get; set; }thành { get { ... } set { ... } }?
cấu hình

Bây giờ tôi nghĩ về nó, đó là một điểm công bằng.
Wayne Molina
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.