Hướng dẫn how do i learn python design patterns? - làm cách nào để tìm hiểu các mẫu thiết kế python?

Hãy để nói một lần nữa: Python là ngôn ngữ lập trình cấp cao với việc gõ động và ràng buộc động. Tôi sẽ mô tả nó như một ngôn ngữ năng động cấp cao, mạnh mẽ. Nhiều nhà phát triển đang yêu Python vì cú pháp rõ ràng, các mô -đun và gói có cấu trúc tốt, và cho sự linh hoạt và phạm vi của các tính năng hiện đại.

Trong Python, không có gì bắt buộc bạn phải viết các lớp và khởi tạo các đối tượng từ chúng. Nếu bạn không cần các cấu trúc phức tạp trong dự án của mình, bạn chỉ có thể viết các chức năng. Thậm chí tốt hơn, bạn có thể viết một tập lệnh phẳng để thực hiện một số tác vụ đơn giản và nhanh chóng mà không cần cấu trúc mã.

Đồng thời Python là ngôn ngữ hướng đối tượng 100 phần trăm. Làm thế nào mà điều đó? Chà, chỉ cần đặt, mọi thứ trong Python là một đối tượng. Các hàm là đối tượng, đối tượng hạng nhất (bất kể điều đó có nghĩa là gì). Thực tế này về các chức năng là đối tượng là quan trọng, vì vậy hãy nhớ nó.

Vì vậy, bạn có thể viết các tập lệnh đơn giản bằng Python, hoặc chỉ cần mở thiết bị đầu cuối Python và thực hiện các câu lệnh ngay tại đó (điều đó rất hữu ích!). Nhưng đồng thời, bạn có thể tạo các khung, ứng dụng, thư viện phức tạp, v.v. Bạn có thể làm rất nhiều trong Python. Tất nhiên có một số hạn chế, nhưng đó không phải là chủ đề của bài viết này.

Tuy nhiên, vì Python rất mạnh mẽ và linh hoạt, chúng tôi cần một số quy tắc (hoặc mẫu) khi lập trình trong đó. Vì vậy, hãy xem các mẫu là gì và chúng liên quan đến Python như thế nào. Chúng tôi cũng sẽ tiến hành thực hiện một vài mẫu thiết kế Python thiết yếu.

Tại sao Python tốt cho các mẫu?

Bất kỳ ngôn ngữ lập trình là tốt cho các mẫu. Trong thực tế, các mẫu nên được xem xét trong bối cảnh của bất kỳ ngôn ngữ lập trình nhất định. Cả hai mẫu, cú pháp ngôn ngữ và thiên nhiên đều áp đặt các hạn chế đối với lập trình của chúng tôi. Những hạn chế đến từ cú pháp ngôn ngữ và bản chất ngôn ngữ (động, chức năng, định hướng đối tượng và tương tự) có thể khác nhau, vì những lý do đằng sau sự tồn tại của chúng. Những hạn chế đến từ các mẫu là có một lý do, chúng có mục đích. Đó là mục tiêu cơ bản của các mẫu; Để cho chúng tôi biết làm thế nào để làm điều gì đó và làm thế nào để không làm điều đó. Chúng tôi sẽ nói về các mẫu, và đặc biệt là các mẫu thiết kế Python, sau này.

Hướng dẫn how do i learn python design patterns? - làm cách nào để tìm hiểu các mẫu thiết kế python?

Python là một ngôn ngữ năng động và linh hoạt. Các mẫu thiết kế Python là một cách tuyệt vời để khai thác tiềm năng rộng lớn của nó.

Triết lý của Python sườn được xây dựng trên đỉnh của ý tưởng về những thực tiễn tốt nhất được suy nghĩ tốt. Python là một ngôn ngữ năng động (tôi đã nói điều đó chưa?) Và như vậy, đã thực hiện hoặc giúp nó dễ dàng thực hiện, một số mẫu thiết kế phổ biến với một vài dòng mã. Một số mẫu thiết kế được tích hợp vào Python, vì vậy chúng tôi sử dụng chúng ngay cả khi không biết. Các mẫu khác là không cần thiết do bản chất của ngôn ngữ.

Ví dụ, nhà máy là một mẫu thiết kế Python cấu trúc nhằm tạo ra các đối tượng mới, che giấu logic khởi tạo từ người dùng. Nhưng việc tạo ra các đối tượng trong Python là năng động theo thiết kế, vì vậy các bổ sung như nhà máy là không cần thiết. Tất nhiên, bạn có thể tự do thực hiện nó nếu bạn muốn. Có thể có những trường hợp nó sẽ thực sự hữu ích, nhưng chúng là một ngoại lệ, không phải là tiêu chuẩn.

Có gì tốt về triết lý Python? Hãy bắt đầu với điều này (khám phá nó trong thiết bị đầu cuối Python):

> >> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Đây có thể không phải là mô hình theo nghĩa truyền thống, nhưng đây là những quy tắc xác định cách tiếp cận của Pythonic, đối với lập trình theo cách thanh lịch và hữu ích nhất.

Chúng tôi cũng có hướng dẫn mã PEP-8 giúp cấu trúc mã của chúng tôi. Tất nhiên, đó là một điều bắt buộc đối với tôi, với một số ngoại lệ thích hợp. Nhân tiện, những ngoại lệ này được khuyến khích bởi chính PEP-8:

Nhưng quan trọng nhất: biết khi nào nên không nhất quán - đôi khi hướng dẫn phong cách chỉ không áp dụng. Khi nghi ngờ, hãy sử dụng phán đoán tốt nhất của bạn. Nhìn vào các ví dụ khác và quyết định những gì trông tốt nhất. Và đừng ngần ngại hỏi!

Kết hợp PEP-8 với Zen of Python (cũng là PEP-PEP-20) và bạn sẽ có một nền tảng hoàn hảo để tạo mã có thể đọc được và có thể duy trì. Thêm các mẫu thiết kế và bạn đã sẵn sàng để tạo ra mọi loại hệ thống phần mềm với tính nhất quán và khả năng phát triển.

Mô hình thiết kế Python

Một mẫu thiết kế là gì?

Mọi thứ bắt đầu với nhóm bốn (GOF). Thực hiện tìm kiếm trực tuyến nhanh nếu bạn không quen thuộc với GOF.

Mô hình thiết kế là một cách phổ biến để giải quyết các vấn đề nổi tiếng. Hai nguyên tắc chính nằm trong các cơ sở của các mẫu thiết kế được xác định bởi GOF:

  • Chương trình cho một giao diện không phải là một triển khai.
  • Ủng hộ thành phần đối tượng trên kế thừa.

Hãy cùng xem xét kỹ hơn về hai nguyên tắc này từ quan điểm của các lập trình viên Python.

Chương trình cho một giao diện không phải là một triển khai

Hãy nghĩ về việc đánh máy vịt. Trong Python, chúng tôi không muốn xác định các giao diện và các lớp chương trình theo các giao diện này, phải không? Nhưng, hãy lắng nghe tôi! Điều này không có nghĩa là chúng tôi không nghĩ về các giao diện, trên thực tế với việc đánh máy vịt, chúng tôi làm điều đó mọi lúc.

Hãy để nói một số từ về cách tiếp cận gõ vịt khét tiếng để xem nó phù hợp như thế nào trong mô hình này: chương trình với một giao diện.

Hướng dẫn how do i learn python design patterns? - làm cách nào để tìm hiểu các mẫu thiết kế python?

Nếu nó trông giống như một con vịt và những kẻ lừa đảo như một con vịt, thì đó là một con vịt!

Chúng tôi không làm phiền với bản chất của đối tượng, chúng tôi không phải quan tâm đến đối tượng là gì; Chúng tôi chỉ muốn biết nếu nó có thể làm những gì chúng tôi cần (chúng tôi chỉ quan tâm đến giao diện của đối tượng).

Đối tượng có thể quack? Vì vậy, hãy để nó quack!

try:
    bird.quack()
except AttributeError:
    self.lol()

Chúng tôi đã xác định một giao diện cho vịt của chúng tôi? Không! Chúng ta đã lập trình với giao diện thay vì triển khai? Đúng! Và, tôi thấy điều này rất tốt.

Như Alex Martelli chỉ ra trong bài thuyết trình nổi tiếng của mình về các mô hình thiết kế trong Python, thì dạy những con vịt để gõ mất một lúc, nhưng giúp bạn tiết kiệm rất nhiều công việc sau đó!

Ủng hộ thành phần đối tượng hơn sự kế thừa

Bây giờ, đó là những gì tôi gọi là nguyên tắc Pythonic! Tôi đã tạo ra ít lớp/lớp con hơn so với việc gói một lớp (hoặc thường xuyên hơn, một số lớp) trong một lớp khác.

Thay vì làm điều này:

class User(DbObject):
    pass

Chúng ta có thể làm điều gì đó như thế này:

class User:
    _persist_methods = ['get', 'save', 'delete']

    def __init__(self, persister):
        self._persister = persister

    def __getattr__(self, attribute):
        if attribute in self._persist_methods:
            return getattr(self._persister, attribute)

Những lợi thế là rõ ràng. Chúng ta có thể hạn chế những phương pháp của lớp được bao bọc để phơi bày. Chúng ta có thể tiêm ví dụ Persister trong thời gian chạy! Ví dụ, hôm nay, nó là một cơ sở dữ liệu quan hệ, nhưng ngày mai nó có thể là bất cứ điều gì, với giao diện chúng ta cần (một lần nữa những con vịt phiền phức).

Thành phần là thanh lịch và tự nhiên đối với Python.

Mẫu hành vi

Các mẫu hành vi liên quan đến giao tiếp giữa các đối tượng, cách các đối tượng tương tác và thực hiện một nhiệm vụ nhất định. Theo các nguyên tắc của GOF, có tổng cộng 11 mẫu hành vi trong Python: Chuỗi trách nhiệm, chỉ huy, thông dịch viên, người lặp, hòa giải viên, Memento, Quan sát viên, Nhà nước, Chiến lược, Mẫu, Khách truy cập.

Tôi thấy các mẫu này rất hữu ích, nhưng điều này không có nghĩa là các nhóm mẫu khác thì không.

Người lặp lại

Tererators được tích hợp vào Python. Đây là một trong những đặc điểm mạnh mẽ nhất của ngôn ngữ. Nhiều năm trước, tôi đã đọc ở đâu đó rằng các trình lặp lại làm cho Python trở nên tuyệt vời, và tôi nghĩ rằng đây vẫn là trường hợp. Tìm hiểu đủ về các trình lặp và máy phát Python và bạn sẽ biết mọi thứ bạn cần về mẫu Python đặc biệt này.

Chuỗi trách nhiệm

Mẫu này cho chúng ta một cách để xử lý một yêu cầu bằng các phương pháp khác nhau, mỗi phương pháp giải quyết một phần cụ thể của yêu cầu. Bạn biết đấy, một trong những nguyên tắc tốt nhất cho mã tốt là nguyên tắc trách nhiệm duy nhất.

Mỗi đoạn mã phải làm một, và chỉ một, điều.

Nguyên tắc này được tích hợp sâu trong mô hình thiết kế này.

Ví dụ: nếu chúng ta muốn lọc một số nội dung, chúng ta có thể triển khai các bộ lọc khác nhau, mỗi bộ lọc thực hiện một loại lọc chính xác và được xác định rõ ràng. Các bộ lọc này có thể được sử dụng để lọc các từ xúc phạm, quảng cáo, nội dung video không phù hợp, v.v.

class ContentFilter(object):
    def __init__(self, filters=None):
        self._filters = list()
        if filters is not None:
            self._filters += filters

    def filter(self, content):
        for filter in self._filters:
            content = filter(content)
        return content

filter = ContentFilter([
                offensive_filter,
                ads_filter,
                porno_video_filter])
filtered_content = filter.filter(content)

Yêu cầu

Đây là một trong những mẫu thiết kế Python đầu tiên mà tôi đã triển khai như một lập trình viên. Điều đó nhắc nhở tôi: Các mẫu không được phát minh, chúng được phát hiện. Chúng tồn tại, chúng ta chỉ cần tìm và đưa chúng vào sử dụng. Tôi đã phát hiện ra điều này cho một dự án tuyệt vời mà chúng tôi đã thực hiện nhiều năm trước: một biên tập viên WYSIWYM XML có mục đích đặc biệt. Sau khi sử dụng mẫu này một cách chuyên sâu trong mã, tôi đọc thêm về nó trên một số trang web.

Mẫu lệnh rất tiện dụng trong các tình huống khi, vì một số lý do, chúng ta cần bắt đầu bằng cách chuẩn bị những gì sẽ được thực hiện và sau đó thực hiện nó khi cần thiết. Ưu điểm là việc đóng gói các hành động theo cách như vậy cho phép các nhà phát triển Python thêm các chức năng bổ sung liên quan đến các hành động được thực hiện, chẳng hạn như hoàn tác/làm lại hoặc giữ lịch sử hành động và tương tự.

Hãy để xem một ví dụ đơn giản và thường xuyên được sử dụng trông như thế nào:

class RenameFileCommand(object):
    def __init__(self, from_name, to_name):
        self._from = from_name
        self._to = to_name

    def execute(self):
        os.rename(self._from, self._to)

    def undo(self):
        os.rename(self._to, self._from)

class History(object):
    def __init__(self):
        self._commands = list()

    def execute(self, command):
        self._commands.append(command)
        command.execute()

    def undo(self):
        self._commands.pop().undo()

history = History()
history.execute(RenameFileCommand('docs/cv.doc', 'docs/cv-en.doc'))
history.execute(RenameFileCommand('docs/cv1.doc', 'docs/cv-bg.doc'))
history.undo()
history.undo()

Mô hình sáng tạo

Hãy bắt đầu bằng cách chỉ ra rằng các mẫu sáng tạo không được sử dụng phổ biến trong Python. Tại sao? Bởi vì bản chất năng động của ngôn ngữ.

Ai đó khôn ngoan hơn tôi từng nói rằng nhà máy được xây dựng thành Python. Điều đó có nghĩa là chính ngôn ngữ cung cấp cho chúng ta tất cả sự linh hoạt mà chúng ta cần để tạo các đối tượng theo cách đủ thanh lịch; Chúng tôi hiếm khi cần phải thực hiện bất cứ điều gì trên đầu, như Singleton hoặc Factory.

Trong một hướng dẫn về mô hình thiết kế Python, tôi đã tìm thấy một mô tả về các mẫu thiết kế sáng tạo đã nêu các mẫu thiết kế này cung cấp một cách để tạo các đối tượng trong khi ẩn logic sáng tạo, thay vì các đối tượng tức thời sử dụng toán tử mới.new operator.”

Điều đó tổng hợp khá nhiều vấn đề: Chúng tôi không có một nhà điều hành mới trong Python!new operator in Python!

Tuy nhiên, hãy để Lôi xem cách chúng ta có thể thực hiện một số ít, nếu chúng ta cảm thấy chúng ta có thể đạt được lợi thế bằng cách sử dụng các mẫu như vậy.

Singleton

Mẫu Singleton được sử dụng khi chúng tôi muốn đảm bảo rằng chỉ có một phiên bản của một lớp nhất định tồn tại trong thời gian chạy. Chúng ta có thực sự cần mô hình này trong Python không? Dựa trên kinh nghiệm của tôi, nó dễ dàng hơn để tạo một thể hiện một cách có chủ ý và sau đó sử dụng nó thay vì thực hiện mẫu singleton.

Nhưng nếu bạn muốn thực hiện nó, đây là một tin tốt: trong Python, chúng ta có thể thay đổi quá trình khởi tạo (cùng với hầu hết mọi thứ khác). Nhớ phương pháp

try:
    bird.quack()
except AttributeError:
    self.lol()
6 mà tôi đã đề cập trước đó? Ở đây chúng tôi đi:

class Logger(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_logger'):
            cls._logger = super(Logger, cls
                    ).__new__(cls, *args, **kwargs)
        return cls._logger

Trong ví dụ này, Logger là một người độc thân.

Đây là những lựa chọn thay thế cho việc sử dụng singleton trong Python:

  • Sử dụng một mô -đun.
  • Tạo một thể hiện ở đâu đó ở cấp cao nhất của ứng dụng của bạn, có lẽ trong tệp cấu hình.
  • Chuyển thể hiện cho mọi đối tượng cần nó. Đó là một tiêm phụ thuộc và nó là một cơ chế mạnh mẽ và dễ thành thạo.

Tiêm phụ thuộc

Tôi không có ý định thảo luận về việc liệu tiêm phụ thuộc có phải là một mô hình thiết kế hay không, nhưng tôi sẽ nói rằng nó là một cơ chế rất tốt để thực hiện các khớp nối lỏng lẻo, và nó giúp ứng dụng của chúng tôi có thể duy trì và mở rộng. Kết hợp nó với gõ vịt và lực sẽ ở bên bạn. Luôn luôn.

Tôi đã liệt kê nó trong phần mẫu sáng tạo của bài đăng này vì nó liên quan đến câu hỏi khi nào (hoặc thậm chí tốt hơn: ở đâu) đối tượng được tạo. Nó được tạo ra bên ngoài. Tốt hơn để nói rằng các đối tượng hoàn toàn không được tạo ra tại nơi chúng ta sử dụng chúng, vì vậy sự phụ thuộc không được tạo ra khi nó được tiêu thụ. Mã người tiêu dùng nhận được đối tượng được tạo bên ngoài và sử dụng nó. Để tham khảo thêm, xin vui lòng đọc câu trả lời được nâng cấp nhất cho câu hỏi Stackoverflow này.

Đó là một lời giải thích tốt đẹp về tiêm phụ thuộc và cho chúng ta một ý tưởng tốt về tiềm năng của kỹ thuật cụ thể này. Về cơ bản, câu trả lời giải thích vấn đề với ví dụ sau: don don nhận được những thứ để uống từ tủ lạnh, thay vào đó hãy nói một nhu cầu. Nói với bố mẹ rằng bạn cần một cái gì đó để uống với bữa trưa.

Python cung cấp cho chúng ta tất cả những gì chúng ta cần để thực hiện một cách dễ dàng. Hãy suy nghĩ về việc triển khai có thể của nó trong các ngôn ngữ khác như Java và C#, và bạn sẽ nhanh chóng nhận ra vẻ đẹp của Python.

Hãy cùng suy nghĩ về một ví dụ đơn giản về tiêm phụ thuộc:

class Command:

    def __init__(self, authenticate=None, authorize=None):
        self.authenticate = authenticate or self._not_authenticated
        self.authorize = authorize or self._not_autorized

    def execute(self, user, action):
        self.authenticate(user)
        self.authorize(user, action)
        return action()

if in_sudo_mode:
    command = Command(always_authenticated, always_authorized)
else:
    command = Command(config.authenticate, config.authorize)
command.execute(current_user, delete_user_action)

Chúng tôi tiêm các phương thức Authenticator và Authorizer trong lớp lệnh. Tất cả các nhu cầu của lớp lệnh là thực hiện chúng thành công mà không bận tâm đến các chi tiết thực hiện. Bằng cách này, chúng tôi có thể sử dụng lớp lệnh với bất kỳ cơ chế xác thực và ủy quyền nào chúng tôi quyết định sử dụng trong thời gian chạy.

Chúng tôi đã chỉ ra cách tiêm các phụ thuộc thông qua hàm tạo, nhưng chúng tôi có thể dễ dàng tiêm chúng bằng cách đặt trực tiếp các thuộc tính đối tượng, mở khóa nhiều tiềm năng hơn:

command = Command()

if in_sudo_mode:
    command.authenticate = always_authenticated
    command.authorize = always_authorized
else:
    command.authenticate = config.authenticate
    command.authorize = config.authorize
command.execute(current_user, delete_user_action)

Có nhiều hơn nữa để tìm hiểu về tiêm phụ thuộc; Những người tò mò sẽ tìm kiếm IOC, ví dụ.

Nhưng trước khi bạn làm điều đó, hãy đọc một câu trả lời Stackoverflow khác, câu trả lời được nâng lên nhiều nhất cho câu hỏi này.

Một lần nữa, chúng tôi chỉ chứng minh cách thực hiện mô hình thiết kế tuyệt vời này trong Python chỉ là vấn đề sử dụng các chức năng tích hợp của ngôn ngữ.

Chúng ta đừng quên tất cả những gì có nghĩa là: Kỹ thuật tiêm phụ thuộc cho phép thử nghiệm đơn vị rất linh hoạt và dễ dàng. Hãy tưởng tượng một kiến ​​trúc nơi bạn có thể thay đổi lưu trữ dữ liệu khi đang bay. Chế biến một cơ sở dữ liệu trở thành một nhiệm vụ tầm thường, phải không? Để biết thêm thông tin, bạn có thể xem phần giới thiệu của Toptal về việc chế giễu trong Python.

Bạn cũng có thể muốn nghiên cứu các mẫu thiết kế nguyên mẫu, xây dựng và nhà máy.

Mô hình cấu trúc

Mặt tiền

Đây rất có thể là mô hình thiết kế Python nổi tiếng nhất.

Hãy tưởng tượng bạn có một hệ thống với một số lượng đáng kể các đối tượng. Mỗi đối tượng đều cung cấp một bộ phương thức API phong phú. Bạn có thể làm rất nhiều thứ với hệ thống này, nhưng làm thế nào về việc đơn giản hóa giao diện? Tại sao không thêm một đối tượng giao diện để lộ một tập hợp con được suy nghĩ kỹ lưỡng của tất cả các phương thức API? Một mặt tiền!

Hướng dẫn how do i learn python design patterns? - làm cách nào để tìm hiểu các mẫu thiết kế python?

Mặt tiền là một mô hình thiết kế Python thanh lịch. Đó là một cách hoàn hảo để hợp lý hóa giao diện.

Mẫu thiết kế mặt tiền Python Ví dụ:

class Car(object):

    def __init__(self):
        self._tyres = [Tyre('front_left'),
                             Tyre('front_right'),
                             Tyre('rear_left'),
                             Tyre('rear_right'), ]
        self._tank = Tank(70)

    def tyres_pressure(self):
        return [tyre.pressure for tyre in self._tyres]

    def fuel_level(self):
        return self._tank.level

Không có gì ngạc nhiên, không có thủ thuật, lớp

try:
    bird.quack()
except AttributeError:
    self.lol()
7 là một mặt tiền, và tất cả.

Bộ chuyển đổi

Nếu mặt tiền được sử dụng để đơn giản hóa giao diện, tất cả đều là về việc thay đổi giao diện. Giống như sử dụng một con bò khi hệ thống đang mong đợi một con vịt.

Hãy nói rằng bạn có một phương pháp làm việc để ghi nhật ký thông tin đến một điểm đến nhất định. Phương thức của bạn hy vọng đích sẽ có phương thức

try:
    bird.quack()
except AttributeError:
    self.lol()
8 (ví dụ như mọi đối tượng tệp đều có).

try:
    bird.quack()
except AttributeError:
    self.lol()
0

Tôi muốn nói rằng đó là một phương pháp được viết tốt với tiêm phụ thuộc, cho phép mở rộng rất nhiều. Thay vào đó, bạn muốn đăng nhập vào một số ổ cắm UDP vào một tệp, bạn biết cách mở ổ cắm UDP này nhưng vấn đề duy nhất là đối tượng

try:
    bird.quack()
except AttributeError:
    self.lol()
9 không có phương thức
try:
    bird.quack()
except AttributeError:
    self.lol()
8. Bạn cần một bộ chuyển đổi!Adapter!

try:
    bird.quack()
except AttributeError:
    self.lol()
1

Nhưng tại sao tôi thấy bộ chuyển đổi rất quan trọng? Chà, khi nó kết hợp hiệu quả với việc tiêm phụ thuộc, nó mang lại cho chúng ta sự linh hoạt rất lớn. Tại sao thay đổi mã được thử nghiệm tốt của chúng tôi để hỗ trợ các giao diện mới khi chúng tôi chỉ có thể triển khai một bộ chuyển đổi sẽ dịch giao diện mới sang bộ chuyển đổi nổi tiếng?

Bạn cũng nên kiểm tra và Master Bridge và các mẫu thiết kế proxy, do sự giống nhau của chúng với bộ điều hợp. Hãy nghĩ rằng họ dễ dàng thực hiện trong Python và suy nghĩ về những cách khác nhau mà bạn có thể sử dụng chúng trong dự án của mình.

Người trang trí

Ôi chúng ta may mắn làm sao! Các nhà trang trí thực sự tốt đẹp, và chúng tôi đã tích hợp chúng vào ngôn ngữ. Điều tôi thích nhất trong Python là việc sử dụng nó dạy chúng ta sử dụng các thực tiễn tốt nhất. Nó không phải là chúng tôi không thể có ý thức về các thực tiễn tốt nhất (và đặc biệt là các mẫu thiết kế), nhưng với Python, tôi cảm thấy như tôi đã theo dõi các thực tiễn tốt nhất, bất kể. Cá nhân, tôi thấy các thực tiễn tốt nhất của Python là bản chất trực quan và thứ hai, và đây là điều được đánh giá cao bởi các nhà phát triển người mới và ưu tú.

Mô hình trang trí là về việc giới thiệu chức năng bổ sung và đặc biệt, làm điều đó mà không cần sử dụng kế thừa.

Vì vậy, hãy để kiểm tra cách chúng tôi trang trí một phương pháp mà không cần sử dụng chức năng Python tích hợp. Đây là một ví dụ đơn giản.

try:
    bird.quack()
except AttributeError:
    self.lol()
2

Điều không tốt ở đây là chức năng

class User(DbObject):
    pass
1 làm nhiều hơn là thực hiện một cái gì đó. Chúng tôi không tuân theo nguyên tắc trách nhiệm duy nhất cho thư.

Thật tốt khi chỉ cần viết chỉ sau:

try:
    bird.quack()
except AttributeError:
    self.lol()
3

Chúng tôi có thể thực hiện bất kỳ chức năng ủy quyền và xác thực ở một nơi khác, trong một người trang trí, như vậy:

try:
    bird.quack()
except AttributeError:
    self.lol()
4

Bây giờ phương pháp

class User(DbObject):
    pass
2 là:

  • Đơn giản để đọc
  • Chỉ có một điều (ít nhất là khi xem mã)
  • Được trang trí với xác thực
  • Được trang trí với sự cho phép

Chúng tôi viết tương tự bằng cách sử dụng cú pháp trang trí tích hợp Python,:

try:
    bird.quack()
except AttributeError:
    self.lol()
5

Điều quan trọng cần lưu ý là bạn không giới hạn trong các chức năng là người trang trí. Một người trang trí có thể liên quan đến toàn bộ các lớp học. Yêu cầu duy nhất là họ phải là các thiết bị gọi. Nhưng chúng tôi không có vấn đề gì với điều đó; Chúng ta chỉ cần xác định phương pháp

class User(DbObject):
    pass
3.

Bạn cũng có thể muốn xem xét kỹ hơn về mô -đun Functools Python. Có nhiều thứ để khám phá ở đó!

Sự kết luận

Tôi đã chỉ ra cách sử dụng các mẫu thiết kế Python, nhưng tôi cũng đã chỉ ra cách lập trình trong Python cũng dễ dàng đi.

Simple Simple là tốt hơn phức tạp, có nhớ điều đó không? Có thể bạn đã nhận thấy rằng không có mẫu thiết kế nào được mô tả đầy đủ và chính thức. Không có triển khai toàn diện phức tạp đã được hiển thị. Bạn cần phải cảm nhận và thực hiện chúng theo cách phù hợp nhất với phong cách và nhu cầu của bạn. Python là một ngôn ngữ tuyệt vời và nó cung cấp cho bạn tất cả sức mạnh bạn cần để tạo ra mã linh hoạt và có thể tái sử dụng.

Tuy nhiên, nó cung cấp cho bạn nhiều hơn thế. Nó cung cấp cho bạn sự tự do của người Viking để viết mã thực sự xấu. Hãy làm điều đó! Don Tiết lặp lại bản thân (khô) và không bao giờ viết các dòng mã dài hơn 80 ký tự. Và don không quên sử dụng các mẫu thiết kế nếu có; Nó là một trong những cách tốt nhất để học hỏi từ người khác và đạt được từ sự giàu có kinh nghiệm của họ miễn phí.

Python có mẫu thiết kế không?

Python có mẫu thiết kế không?Vâng, Python có mô hình thiết kế.Trong thực tế, các mẫu thiết kế chỉ đơn giản là cách để giải quyết vấn đề;Họ độc lập với bất kỳ ngôn ngữ lập trình.Bạn có thể triển khai hầu hết các mẫu thiết kế trong một loạt các ngôn ngữ lập trình.Yes, Python has design patterns. In fact, design patterns are simply ways to solve problems; they are independent of any programming language. You can implement most design patterns in a wide range of programming languages.

Ngôn ngữ nào là tốt nhất cho các mẫu thiết kế?

Đối với các mẫu thiết kế học tập, bạn có thể muốn Java hoặc C#.Những ngôn ngữ đó có xu hướng được sử dụng bởi những người coi các mẫu thiết kế là cách viết thành ngữ để viết ngôn ngữ.tức là mọi người cân nhắc sử dụng nhiều mẫu thiết kế trong Java hoặc C# để trở thành cách viết chính xác của người Viking C# hoặc Java.Java or C#. Those languages tend to be used by people that consider design patterns as idiomatic ways of writing the language. i.e. people consider using many design patterns in Java or C# to be the “correct” way of writing C# or Java.

Các mẫu có quan trọng trong Python không?

Các mẫu thiết kế là phần thiết yếu nhất của kỹ thuật phần mềm, vì chúng cung cấp giải pháp lặp lại chung cho một vấn đề thường xảy ra trong thiết kế phần mềm.Họ thường đại diện cho một số thực tiễn tốt nhất được áp dụng bởi các nhà phát triển phần mềm hướng đối tượng có kinh nghiệm., as they provide the general repeatable solution to a commonly occurring problem in software design. They usually represent some of the best practices adopted by experienced object-oriented software developers.