Có bất kỳ mẫu thiết kế nào không cần thiết trong các ngôn ngữ động như Python không?


98

Tôi đã bắt đầu đọc cuốn sách mẫu thiết kế của GoF. Một số mẫu có vẻ rất giống nhau chỉ với sự khác biệt về khái niệm nhỏ.

Bạn có nghĩ rằng trong số nhiều mẫu không cần thiết trong một ngôn ngữ động như Python (ví dụ: vì chúng được thay thế bằng một tính năng động) không?


1
Một loại câu hỏi thú vị, vì nó ngụ ý rằng sự lựa chọn ngôn ngữ có thể thay thế hiệu quả cho các cấu trúc mã.
joshin4colours

3
Không phải là một câu trả lời, nhưng có liên quan - Tôi nghĩ rằng các mẫu thiết kế của GoF có liên quan đến một số nguyên tắc chung có thể được chắt lọc ra khỏi chúng như đối với các mẫu cụ thể. Tôi không có nghĩa là ý tưởng về một mẫu (mặc dù điều đó chắc chắn có ý nghĩa), nhưng nhiều quyền hơn là sử dụng các lớp theo những cách nhất định vi phạm các nguyên tắc OOP ngây thơ. Ví dụ, có rất nhiều mẫu trong đó "hình dạng" rõ ràng không "tự vẽ" hoặc ít nhất ủy thác một số khía cạnh của công việc cho một số đối tượng khác. Tôi nghĩ rằng bài học rất quan trọng trong bất kỳ ngôn ngữ nào hỗ trợ OOP.
Steve314

Câu hỏi rất thú vị. Tôi ước tôi có thể +5 thay vì +1.
MathAttack

1
Nhìn thoáng qua các mẫu thiết kế Các tính năng ngôn ngữ bị thiếu và các mẫu thiết kế bị thiếu các tính năng ngôn ngữ tại c2. Nó thậm chí không phải là một vấn đề 'ngôn ngữ động'. Ví dụ đơn giản nhất là mẫu lặp đó là tầm thường trong python, perl (và thậm chí Java - không động).

Câu trả lời:


92

Peter Norvig chứng minh rằng 16 trong số 23 mẫu thiết kế được tìm thấy trong sách GOF là vô hình hoặc đơn giản hơn trong các ngôn ngữ động (ông tập trung vào Lisp và Dylan).

Vì bạn đã đề cập đến Python, có một bài thuyết trình hay của Alex Martelli về chủ đề này. Cũng liên quan đến Python, có một bài đăng blog rất hay thể hiện sáu mẫu thiết kế trong Python thành ngữ .

Tôi cũng giữ một kho lưu trữ github với các triển khai (của người khác) về các mẫu thiết kế phổ biến nhất trong Python .


Tuyệt quá! Đó sẽ là một câu trả lời :) Tôi ước mọi người đã nắm bắt được câu hỏi đó một cách rõ ràng.
Gerenuk

2
Theo Norvig, 2 trong số 16 (Trình thông dịch và Trình lặp) là "vô hình hoặc đơn giản hơn" do macro (mà Python không có).
mjs

1
Tôi không rõ ràng rằng tất cả các mẫu này không cần vì lisp là động mà là do các tính năng khác như là một ngôn ngữ chức năng mạnh mẽ
jk.

@mjs Iterators là một tính năng dựng sẵn của Python.
sakisk

1
Câu trả lời tuyệt vời này thậm chí có thể được cải thiện một chút bằng cách thay đổi chú thích liên kết có phần vô nghĩa chứng minh , trình bàykho lưu trữ - chúng tốt hơn nhiều ở đây , nhưng, bạn biết đấy ... :-)
Wolf

59

Không có mẫu thiết kế là cần thiết. Bằng bất kỳ ngôn ngữ nào.

Tôi có xu hướng bắt gặp rất nhiều mã được viết bởi những người đọc các mẫu thiết kế và sau đó nghĩ rằng họ nên sử dụng chúng ở mọi nơi. Kết quả là mã thực tế bị chôn vùi dưới hàng tấn giao diện, trình bao bọc và các lớp và khá khó đọc. Đó là một cách tiếp cận sai cho các mẫu thiết kế.

Các mẫu thiết kế tồn tại để bạn có một tiết mục thành ngữ hữu ích khi bạn gặp phải một vấn đề. Nhưng bạn không bao giờ nên áp dụng bất kỳ mô hình nào trước khi bạn xác định vấn đề. Giữ cho nó đơn giản Ngốc luôn phải là nguyên tắc quản trị cao cấp.

Nó cũng giúp nghĩ về các mẫu thiết kế như là một khái niệm để suy nghĩ về vấn đề thay vì mã soạn sẵn cụ thể để viết. Và phần lớn các bản tóm tắt như cách giải quyết cho Java thiếu các hàm miễn phí và các đối tượng hàm tiêu chuẩn mà bạn sử dụng trong hầu hết các ngôn ngữ khác có chúng (như Python, C #, C ++, v.v.).

Tôi có thể nói rằng tôi có một mẫu khách truy cập, nhưng trong bất kỳ ngôn ngữ nào có các hàm hạng nhất, nó sẽ chỉ là một hàm lấy một hàm. Thay vì lớp nhà máy tôi thường chỉ có một chức năng nhà máy. Tôi có thể nói rằng tôi có một giao diện, nhưng sau đó chỉ là một vài phương thức được đánh dấu bằng các bình luận, bởi vì sẽ không có bất kỳ triển khai nào khác (tất nhiên trong python một giao diện luôn chỉ là các bình luận, bởi vì nó được gõ vào). Tôi vẫn nói về mã như sử dụng mẫu, bởi vì đó là một cách hữu ích để suy nghĩ về nó, nhưng không thực sự gõ tất cả các thứ cho đến khi tôi thực sự cần nó.

Vì vậy, tìm hiểu tất cả các mô hình như các khái niệm . Và quên đi việc thực hiện cụ thể. Việc triển khai khác nhau và nên thay đổi trong thế giới thực, thậm chí chỉ trong Java.


28
Tuyên bố mở đầu của bạn là quá đơn giản đến cùng cực. Đúng là các mẫu có chi phí của chúng, vì vậy không nên sử dụng một cách mù quáng, chỉ vì lợi ích của nó. Nhưng ở đúng nơi, họ có thể là một trợ giúp tuyệt vời. Và vâng, chúng là ngôn ngữ cụ thể - một số mẫu không cần thiết trong một số ngôn ngữ vì bản thân ngôn ngữ hỗ trợ cách tiếp cận tốt hơn. Nhưng đó vẫn còn khá xa so với yêu cầu mở đầu của bạn.
Péter Török

2
Btw visitor không hoàn toàn được thay thế bởi các hàm bậc cao hơn - đó là một giải pháp để thực hiện gửi hai lần trong một ngôn ngữ không thực sự hỗ trợ nó (chẳng hạn như C # và C ++). (Và nó thực sự nên được sử dụng rất ít - Tôi coi đó là một trong những mô hình phức tạp và tốn kém nhất mà sử dụng là IMHO khó khăn như vậy để biện minh rằng bản thân tôi chưa bao giờ sử dụng nó cho đến nay.)
Péter Török

14
Vâng, bạn không bao giờ cần một mô hình. Những gì bạn cần là để giải quyết một vấn đề . Nếu bạn không biết bất kỳ mẫu nào cho nó, bạn vẫn có thể giải quyết nó, nó sẽ cần nhiều suy nghĩ hơn và bạn có thể đưa ra một giải pháp phù hợp với một số mẫu hoặc một mẫu không. Biết các mẫu chỉ làm cho nó dễ dàng hơn.
Jan Hudec

3
@Gerenuk: Vâng, nhưng vấn đề là, các mẫu không dành riêng cho ngôn ngữ, chúng dành cho đầu của bạn. Bạn thường thấy rằng một số mô hình được nhận ra dễ dàng hơn nhiều và sử dụng các công cụ khác nhau trong python, nhưng cùng một khái niệm thường tồn tại.
Jan Hudec

4
@ PéterTörök: Khách truy cập không bị thay thế bởi bất cứ điều gì. Vấn đề là cùng một khái niệm có thể được thực hiện bằng các công cụ khác nhau trong các trường hợp khác nhau, nhưng tôi vẫn coi đó là cùng một mẫu.
Jan Hudec

13

Mô hình nhà máy trừu tượng là không cần thiết trong ngôn ngữ gõ vịt như Python, vì nó thực sự được tích hợp vào ngôn ngữ.


10
tốt, bạn vẫn cần các nhà máy khác nhau. Bạn không cần định nghĩa giao diện.
Stefano Borini

1
Nếu bạn có một lớp học, bạn đã có một nhà máy. Các lớp là các đối tượng lớp đầu tiên và có thể được truyền khắp nơi và được gọi đơn giản để tạo một đối tượng (không giống như Java). Bạn không cần phải tạo ra bất cứ điều gì khác. Nếu bạn muốn một cái gì đó không phải là hàm tạo mặc định, chỉ cần tạo một lambda / có thể gọi được của một số loại bao bọc hàm tạo theo một cách nào đó.
spookylukey

13

Người duy nhất nghĩ đến là mẫu Singleton.

Vì Python không bắt bạn phải sử dụng các lớp cho mọi thứ , nên bạn chỉ có thể sử dụng cấu trúc dữ liệu toàn cầu thay thế. Cấu trúc dữ liệu toàn cầu đó có thể được quản lý bởi một thể hiện, nhưng bạn không phải kiểm soát việc khởi tạo của lớp đó, bạn chỉ cần tạo cá thể khi nhập và để nó ở đó.

Hầu hết, Singletons trong python được thay thế bằng một mô-đun. Các mô-đun trong trăn là bản chất của chúng Singletons; trình thông dịch python tạo ra chúng một lần và một lần duy nhất.

Tất cả các mẫu khác trong Design Patters tôi đã sử dụng Python lúc này hay lúc khác và bạn sẽ tìm thấy các ví dụ về chúng trong thư viện chuẩn Python và trong chính Python.


2
Không phải đó thực sự là một mô hình chống lại những ngày này sao?
Den

16
Singleton là một antipotype . Trong tất cả các ngôn ngữ. Nó được tạo ra để giải quyết một số vấn đề không liên quan và không phù hợp với cả hai (lưu ý rằng ngay cả Java cũng có các thành viên tĩnh, tồn tại một lần trên mỗi lớp, vì vậy bạn không cần một ví dụ cho điều đó).
Jan Hudec

1
Và trong Python chúng tôi không bao giờ bận tâm với nó vì không bao giờ có vấn đề cần giải quyết.
Martijn Pieters

1
"Python không bắt bạn phải sử dụng các đối tượng cho mọi thứ" Không đúng. Nó không đáng ghét như trong Java, nhưng, trong Python, mọi thứ đều là một đối tượng. Ngay cả mô-đun là một đối tượng.
vartec

3
@Darthfett: Tôi nhận thức rõ về cách thức lenhoạt động; Guido đã đưa ra một lựa chọn rõ ràng ở đây . Quan điểm của tôi là chỉ ra rằng Python không phải là ngôn ngữ OOP thuần túy; nó là một ngôn ngữ thực dụng. Tôi thích nó theo cách đó.
Martijn Pieters

8

Các mẫu thiết kế dành cho lập trình viên, không dành cho ngôn ngữ. Các lập trình viên có xu hướng sử dụng các mẫu giúp họ hiểu được vấn đề trong tay. Không có mẫu thiết kế nào thực sự cần thiết, nhưng nó có thể được sử dụng để giúp đơn giản hóa những gì bạn đang cố gắng làm.

Python và gõ vịt đặc biệt, cung cấp một kết thúc xung quanh rất nhiều kiểu và cách thức phổ biến, và rất nhiều hạn chế được đưa ra bởi một số mẫu (quyền riêng tư, bất biến, v.v.) chỉ tuân theo mức độ mà người lập trình đồng ý không phá vỡ chúng . Tuy nhiên, họ vẫn làm việc miễn là lập trình viên chơi cùng. Một cánh cửa vẫn là một cánh cửa, ngay cả khi nó được đóng khung bởi những bức tường tưởng tượng.

Python được coi là một ngôn ngữ "đa mô hình"; bạn có thể sử dụng bất cứ mẫu nào bạn muốn Đây là cố ý. Nó cung cấp cho các hệ thống phân cấp lớp phức tạp, ví dụ, mặc dù chúng hoàn toàn không cần thiết và hơi giả tạo. Nhưng đối với một số người, sự trừu tượng đặc biệt là hữu ích. Không phải vì vấn đề đòi hỏi nó, mà vì lập trình viên làm. Vì vậy, có bạn đi.


Điều đó chắc chắn thú vị. Vì vậy, những mẫu đặc biệt nào có nghĩa là người ta có thể quên đi, bởi vì có những cách tốt hơn trong Python?
Gerenuk

4

Cuốn sách "Các mẫu thiết kế" ban đầu được ghi lại và đặt tên cho một số thành ngữ phổ biến hữu ích trong các ngôn ngữ bắt buộc, hướng đối tượng như C ++ và Smalltalk. Nhưng Smalltalk là một ngôn ngữ được gõ động, do đó, đây không phải là vấn đề năng động.

Tuy nhiên, câu trả lời cho câu hỏi của bạn vẫn là "có": một số trong các mẫu thiết kế này sẽ không liên quan đến các ngôn ngữ được gõ động hiện đại. Tổng quát hơn, sẽ có các mẫu thiết kế khác nhau trong các ngôn ngữ khác nhau, đặc biệt là trong các loại ngôn ngữ khác nhau .

Để nhắc lại: "mẫu thiết kế" chỉ đơn giản là một tên cho thành ngữ lập trình: một giải pháp phổ biến cho một vấn đề thường gặp. Các ngôn ngữ khác nhau đòi hỏi các thành ngữ khác nhau, bởi vì vấn đề đối với một ngôn ngữ có thể là tầm thường đối với ngôn ngữ khác. Theo nghĩa này, các mẫu thiết kế có xu hướng chỉ ra những điểm yếu trong ngôn ngữ mà chúng áp dụng.

Vì vậy, bạn có thể tìm kiếm các tính năng khác làm cho các ngôn ngữ động hiện đại (hoặc các ngôn ngữ cổ như Lisp) trở nên mạnh mẽ hơn, khiến một số mẫu thiết kế cổ điển này không liên quan.


1

Mẫu thiết kế là cách để giải quyết các vấn đề cụ thể. Nếu một vấn đề không được đáp ứng, mô hình giải quyết nó không có tác dụng.

Mọi người đang cố gắng điều chỉnh các mẫu thiết kế ở mọi nơi như thể đó là cách tốt nhất để có các mẫu thiết kế trong dự án của bạn. Đó là cách khác. Bạn gặp phải một vấn đề có thể được giải quyết với một mô hình nhà máy? Mát mẻ. Thích nghi với nó. Đừng tìm mã của bạn và cố gắng tìm đúng nơi để triển khai một singleton (hoặc nhà máy, hoặc mặt tiền, hoặc bất cứ điều gì ...).

Có lẽ Python có các mẫu thiết kế riêng không dành cho người Java và .NET (do bản chất của các ngôn ngữ này)?


1

Tôi muốn nói rằng các mẫu luôn phụ thuộc vào ngôn ngữ. Hầu hết các mẫu python trông giống như các mẫu được xác định trong GoF, đó là do OOP của Python, được nói là OOP không giống OOP (không có hai ngôn ngữ xác định các đối tượng và thao tác của chúng giống nhau 100%).

Vì vậy, không có nghi ngờ gì một số mẫu sẽ không được áp dụng "như hiện tại", một số mẫu có thể không có ý nghĩa và có một số mẫu có thể chỉ có ý nghĩa đối với Python.

Để lấy lại chính xác câu hỏi của bạn: Các mẫu chỉ cần thiết nếu bạn cần chúng. Bạn không cần phải sử dụng chúng nếu không có nhu cầu sử dụng chúng (như Jan Hudec đã nói).

Hơn nữa, có nhiều mẫu hơn so với các mẫu được đề cập trong GoF. Xem trong wikipedia các mẫu khác

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.