Mẫu thiết kế Python

Tổng quat

Phát triển phần mềm hiện đại cần giải quyết các yêu cầu kinh doanh phức tạp. Nó cũng cần tính đến các yếu tố như khả năng mở rộng và khả năng bảo trì trong tương lai. Một thiết kế tốt của một hệ thống phần mềm là rất quan trọng để đạt được những mục tiêu này. Các mẫu thiết kế đóng một vai trò quan trọng trong các hệ thống như vậy.

Để hiểu mẫu thiết kế, hãy xem xét ví dụ dưới đây:

  • Mọi thiết kế của ô tô đều tuân theo một mô hình thiết kế cơ bản, bốn bánh xe, vô lăng, hệ thống truyền động cốt lõi như chân ga-ly hợp ngắt, v.v.

Vì vậy, tất cả những thứ được chế tạo / sản xuất lặp đi lặp lại, chắc chắn sẽ tuân theo một khuôn mẫu trong thiết kế của nó .. ô tô, xe đạp, bánh pizza, máy atm, bất cứ thứ gì… thậm chí cả giường sofa của bạn.

Các thiết kế gần như đã trở thành cách tiêu chuẩn để mã hóa một số logic / cơ chế / kỹ thuật trong phần mềm, do đó được gọi là hoặc được nghiên cứu với cái tên, Mẫu thiết kế phần mềm.

Tại sao Mẫu thiết kế lại quan trọng?

Lợi ích của việc sử dụng Mẫu thiết kế là -

  • Giúp bạn giải quyết các vấn đề thiết kế thông thường thông qua một cách tiếp cận đã được chứng minh.

  • Không có sự mơ hồ trong sự hiểu biết vì chúng được ghi chép đầy đủ.

  • Giảm thời gian phát triển tổng thể.

  • Giúp bạn xử lý các tiện ích mở rộng và sửa đổi trong tương lai dễ dàng hơn so với cách khác.

  • Có thể giảm các lỗi trong hệ thống vì chúng là giải pháp đã được chứng minh cho các vấn đề chung.

Phân loại các mẫu thiết kế

Các mẫu thiết kế của GoF (Gang of Four) được phân thành ba loại cụ thể là sáng tạo, cấu trúc và hành vi.

Các mẫu sáng tạo

Các mẫu thiết kế sáng tạo tách biệt logic tạo đối tượng khỏi phần còn lại của hệ thống. Thay vì bạn tạo các đối tượng, các mẫu sáng tạo sẽ tạo ra chúng cho bạn. Các mẫu sáng tạo bao gồm Abstract Factory, Builder, Factory Method, Prototype và Singleton.

Các mẫu tạo cấu trúc không thường được sử dụng trong Python vì tính chất động của ngôn ngữ. Ngoài ra, bản thân ngôn ngữ cung cấp cho chúng ta tất cả sự linh hoạt cần thiết để tạo ra một phong cách thanh lịch vừa đủ, chúng ta hiếm khi cần phải triển khai bất cứ thứ gì trên đầu, như singleton hoặc Factory.

Ngoài ra, những mẫu này cung cấp một cách để tạo đối tượng trong khi ẩn logic tạo, thay vì khởi tạo đối tượng trực tiếp bằng toán tử mới.

Các mẫu cấu trúc

Đôi khi thay vì bắt đầu từ đầu, bạn cần xây dựng các cấu trúc lớn hơn bằng cách sử dụng một tập hợp các lớp hiện có. Đó là nơi các mẫu lớp cấu trúc sử dụng tính kế thừa để xây dựng một cấu trúc mới. Các mẫu đối tượng cấu trúc sử dụng thành phần / tổng hợp để có được một chức năng mới. Adapter, Bridge, Composite, Decorator, Façade, Flyweight và Proxy là các Mẫu cấu trúc. Họ đưa ra những cách tốt nhất để tổ chức hệ thống phân cấp lớp.

Mẫu hành vi

Các mẫu hành vi cung cấp những cách tốt nhất để xử lý giao tiếp giữa các đối tượng. Các mẫu thuộc các danh mục này là: Khách truy cập, Chuỗi trách nhiệm, Lệnh, Người phiên dịch, Người lặp lại, Người hòa giải, Ghi nhớ, Người quan sát, Trạng thái, Chiến lược và phương pháp Mẫu là Mẫu hành vi.

Bởi vì chúng đại diện cho hành vi của một hệ thống, chúng thường được sử dụng để mô tả chức năng của hệ thống phần mềm.

Các mẫu thiết kế thường được sử dụng

Singleton

Nó là một trong những mẫu thiết kế gây tranh cãi và nổi tiếng nhất. Nó được sử dụng trong các ngôn ngữ hướng đối tượng quá mức và là một phần quan trọng của lập trình hướng đối tượng truyền thống.

Mẫu Singleton được sử dụng cho,

  • Khi ghi nhật ký cần được thực hiện. Bản ghi nhật ký được chia sẻ bởi tất cả các thành phần của hệ thống.

  • Các tệp cấu hình đang sử dụng điều này vì bộ nhớ cache của thông tin cần được duy trì và chia sẻ bởi tất cả các thành phần khác nhau trong hệ thống.

  • Quản lý kết nối đến cơ sở dữ liệu.

Đây là sơ đồ UML,

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 Singleton.

Khi __new__ được gọi, nó thường xây dựng một thể hiện mới của lớp đó. Khi chúng tôi ghi đè nó, trước tiên chúng tôi kiểm tra xem cá thể singleton của chúng tôi đã được tạo hay chưa. Nếu không, chúng tôi tạo nó bằng cách sử dụng super call. Do đó, bất cứ khi nào chúng ta gọi hàm tạo trên Logger, chúng ta luôn nhận được cùng một thể hiện chính xác.

>>>
>>> obj1 = Logger()
>>> obj2 = Logger()
>>> obj1 == obj2
True
>>>
>>> obj1
<__main__.Logger object at 0x03224090>
>>> obj2
<__main__.Logger object at 0x03224090>