Mẫu thiết kế bộ điều hợp bằng Python

Giới thiệu

Sản phẩm Mẫu thiết kế bộ điều hợp là một phổ biến Mẫu thiết kế cấu trúc được sử dụng trong kỹ thuật phần mềm. Hướng dẫn này xem xét cách chúng ta có thể triển khai Mẫu thiết kế bộ điều hợp bằng Python.

Mẫu thiết kế là các giải pháp giống như khuôn mẫu - thực tế là các công thức để giải quyết các vấn đề lặp lại, phổ biến trong phát triển phần mềm. Mẫu Bộ điều hợp dựa trên khái niệm về bộ điều hợp trong thế giới thực! Ví dụ: bộ sạc của máy tính xách tay có thể có đầu cắm 3 chân, nhưng ổ cắm trên tường có thể chỉ là ổ cắm 2 chân. Để cắm bộ sạc 3 chân vào ổ cắm này, chúng tôi cần một bộ chuyển đổi, chấp nhận phích cắm 3 chân và thích nghi giao diện thành 2-pin ổ cắm.

Bộ sạc 2 chân và bộ sạc 3 chân có cùng một chức năng cơ bản (dẫn điện từ ổ cắm vào máy tính xách tay), nhưng có một hình thức khácvà một người có thể dễ dàng thích ứng vào cái khác. Bất cứ khi nào bạn có các thành phần phần mềm có cùng chức năng cơ bản nhưng các dạng khác nhau, bạn có thể áp dụng Mẫu thiết kế bộ điều hợp.

Mẫu Bộ điều hợp tuân theo nguyên tắc chính xác này. Nó cho phép hai giao diện không tương thích hoạt động cùng nhau mà không cần sửa đổi bên trong của mỗi thành phần. Điều này đạt được bằng cách điều chỉnh giao diện này sang giao diện khác, bên ngoài.

Hãy xem xét một số thuật ngữ cơ bản trước khi đi sâu hơn vào thế giới của các Mẫu bộ điều hợp:

  • Giao diện khách hàng: Một giao diện chỉ định các chức năng mà máy khách nên thực hiện.
  • Khách hàng: Một lớp thực hiện giao diện máy khách.
  • Người thích nghi / Dịch vụ: Lớp không tương thích cần cộng tác với giao diện máy khách.
  • bộ chuyển đổi: Lớp giúp cho sự hợp tác giữa dịch vụ và máy khách có thể thực hiện được.

Các loại mô hình bộ điều hợp khác nhau

Mẫu thiết kế bộ điều hợp có thể được thực hiện theo hai cách khác nhau:

Bộ điều hợp đối tượng

Với phương thức này, lớp bộ điều hợp thực hiện các phương thức từ giao diện máy khách. Do đó, đối tượng khách hàng và đối tượng bộ điều hợp tương thích với nhau. Đối tượng dịch vụ tạo thành một has-a mối quan hệ với đối tượng bộ điều hợp tức là đối tượng dịch vụ thuộc đối tượng bộ điều hợp.

Chúng tôi biết rằng lớp dịch vụ không tương thích với máy khách. Lớp bộ điều hợp bao bọc xung quanh đối tượng dịch vụ bằng cách khởi tạo chính nó với đối tượng đó. Bây giờ, đối tượng dịch vụ có thể được truy cập thông qua đối tượng bộ điều hợp, cho phép máy khách tương tác với nó.

Chúng tôi có thể triển khai bộ điều hợp đối tượng trong tất cả các ngôn ngữ lập trình hiện đại.

Bộ điều hợp lớp

Với phương pháp này, bộ điều hợp có is-a mối quan hệ với lớp dịch vụ. Trong trường hợp này, bộ điều hợp triển khai các phương thức được khách hàng yêu cầu, nhưng nó kế thừa từ nhiều bộ điều hợp, cho phép nó gọi trực tiếp các chức năng không tương thích của chúng. Hạn chế lớn nhất của biến thể này là chúng ta chỉ có thể sử dụng nó trong các ngôn ngữ lập trình hỗ trợ đa kế thừa các lớp.

Triển khai Mẫu thiết kế bộ điều hợp bằng Python

Trong phần dưới đây, chúng tôi sẽ triển khai mẫu thiết kế Bộ điều hợp bằng Python, cụ thể bằng cách sử dụng biến thể bộ điều hợp đối tượng. Phần này được chia thành hai phần. Đầu tiên, chúng tôi sẽ tạo môi trường nơi Mẫu điều hợp sẽ được sử dụng. Điều quan trọng là phải thấy rõ cách mà mẫu này có thể giải quyết một số vấn đề phần mềm. Phần thứ hai sẽ sử dụng bộ điều hợp để giải quyết vấn đề.

Vấn đề không tương thích giữa các lớp

Hãy xem xét vấn đề tương thích khi máy khách và lớp dịch vụ triển khai các chức năng khác nhau. Tạo một lớp khách hàng bằng các phương pháp sau và lưu nó trong một thư mục dưới dạng car.py:

import random

class Car:
    def __init__(self):
        self.generator = random.Random()

    def accelerate(self):
        random_num = self.generator.randint(50, 100)
        speed = random_num
        print(f"The speed of the car is {speed} mph")

    def apply_brakes(self):
        random_num = self.generator.randint(20, 40)
        speed = random_num
        print(f"The speed of the car is {speed} mph after applying the brakes")

    def assign_driver(self, driver_name):
        print(f"{driver_name} is driving the car")

Ở đây, chúng tôi đã tạo ra một Car lớp với ba phương thức accelerate(), apply_brakes()assign_driver(). Chúng tôi đã nhập random và sử dụng nó để tạo ra các con số thiết lập tốc độ của ô tô sau khi tăng tốc và áp dụng phanh. Các assign_driver() phương pháp hiển thị tên người lái xe ô tô.

Tiếp theo, chúng ta phải tạo một lớp dịch vụ hoặc lớp thích ứng muốn cộng tác với lớp khách hàng Car. Tạo một lớp Xe máy như thế này và lưu nó trong thư mục của bạn dưới dạng motorcycle.py:

import random

class Motorcycle:
    def __init__(self):
        self.generator = random.Random()

    def rev_throttle(self):
        random_num = self.generator.randint(50, 100)
        speed = random_num
        print(f"The speed of the motorcycle is {speed} mph")

    def pull_brake_lever(self):
        random_num = self.generator.randint(20, 40)
        speed = random_num
        print(
            f"The speed of the motorcycle is {speed} mph after applying the brakes")

    def assign_rider(self, rider_name):
        print(f"{rider_name} is riding the motorcycle")  

Một hạng dịch vụ, Motorcycle được tạo ở trên với ba phương pháp rev_throttle(), pull_brake_lever()assign_rider(). Lưu ý sự khác biệt giữa các phương thức của lớp dịch vụ và máy khách mặc dù chức năng của chúng tương tự nhau. Các accelerator() phương pháp tăng tốc độ của ô tô trong khi rev_throttle() phương pháp làm tăng tốc độ của xe máy. Tương tự như vậy, apply_brakes()pull_brake_lever() áp dụng phanh cho các loại xe tương ứng. cuối cùng assign_driver()assign_rider() phương pháp chỉ định người điều khiển phương tiện.

Tiếp theo, hãy tạo một lớp để truy cập các phương thức khác nhau này. Đầu tiên, hãy thêm một __init.py__ trong cùng một thư mục bạn đã tạo car.pymotorcycle.py:

touch __init__.py

Bây giờ hãy thêm mã sau vào một tệp mới drive.py:

from car import Car
from motorcycle import Motorcycle
import traceback

if __name__ == '__main__':
    car = Car()
    bike = Motorcycle()

    print("The Motorcyclen")
    bike.assign_rider("Subodh")
    bike.rev_throttle()
    bike.pull_brake_lever()
    print("n")

    print("The Carn")
    car.assign_driver("Sushant")
    car.accelerate()
    car.apply_brakes()
    print("n")

    print("Attempting to call client methods with the service objectn")

    try:
        bike.assign_driver("Robert")
        bike.accelerate()
        bike.apply_brakes()
    except AttributeError:
        print("Oops! bike object cannot access car methods")
        traceback.print_exc()

Tập lệnh này tạo ra các đối tượng khách hàng và dịch vụ của chúng tôi. Đầu tiên chúng tôi nhập CarMotorcycle và tạo các đối tượng với chúng. Sau đó, chúng tôi gọi các phương thức từ bike vật (Motorcycle lớp). Sau đó, chúng tôi gọi các phương thức của car vật (Car lớp). Khi được thực thi, tất cả mã được đề cập cho đến nay sẽ hoạt động.

Tuy nhiên, một ngoại lệ được đưa ra khi chúng tôi cố gắng gọi các phương thức của Car lớp học với bike sự vật. Khi chúng tôi chạy tập lệnh này:

The Motorcycle

Subodh is riding the motorcycle
The speed of the motorcycle is 91 mph
The speed of the motorcycle is 37 mph after applying the brakes


The Car

Sushant is driving the car
The speed of the car is 59 mph
The speed of the car is 33 mph after applying the brakes


Attempting to call client methods with the service object

Oops! bike object cannot access car methods
Traceback (most recent call last):
  File "drive.py", line 24, in 
    bike.assign_driver("Robert")
AttributeError: 'Motorcycle' object has no attribute 'assign_driver'

Trong trường hợp này, chúng tôi có thể sửa đổi Motorcycle lớp học hoặc drive.py script để sử dụng các phương pháp phù hợp. Tuy nhiên, trong nhiều trường hợp, chúng tôi có thể không có quyền truy cập vào mã nguồn của máy khách hoặc lớp dịch vụ. Ngoài ra, đây là một ví dụ đơn giản. Với các khách hàng và dịch vụ lớn hơn, việc cấu trúc lại một trong hai có thể không khả thi trong trường hợp chúng tôi phá vỡ khả năng tương thích với các hệ thống khác.

Thay vào đó, chúng tôi có thể sử dụng bộ điều hợp để thu hẹp khoảng cách tương thích giữa mã khách hàng và đối tượng dịch vụ của chúng tôi.

Sử dụng bộ điều hợp để giải quyết vấn đề không tương thích

Trong một tệp mới, motorcycle_adapter.py, thêm lớp sau:

class MotorcycleAdapter:

    def __init__(self, motorcycle):
        self.motorcycle = motorcycle

    def accelerate(self):
        self.motorcycle.rev_throttle()

    def apply_brakes(self):
        self.motorcycle.pull_brake_lever()

    def assign_driver(self, name):
        self.motorcycle.assign_rider(name)

Chúng tôi đã tạo ra một MotorcycleAdapter lớp, tự khởi tạo với một đối tượng dịch vụ (motorcycle). Bộ điều hợp triển khai các phương thức khách là accelerate(), apply_brakes()assign_driver(). Bên trong cơ thể của accelerate() phương pháp, chúng tôi đã sử dụng motorcycle phiên bản của đối tượng dịch vụ để gọi rev_throttle() phương thức dịch vụ. Tương tự như vậy, các phương pháp khác sử dụng các phương pháp tương ứng của Motorcycle lớp học.

Bây giờ, hãy cập nhật drive.py vì vậy chúng tôi có thể sử dụng bộ điều hợp trong try/except khối:

from car import Car
from motorcycle import Motorcycle
from motorcycle_adapter import MotorcycleAdapter 
import traceback

if __name__ == '__main__':
    car = Car()
    bike = Motorcycle()
    bike_adapter = MotorcycleAdapter(bike) 

    ...

    try:
        print("Attempting to call client methods with the service object using an adaptern")
        bike_adapter.assign_driver("Robert")
        bike_adapter.accelerate()
        bike_adapter.apply_brakes()
    except AttributeError:
        print("Oops! bike object cannot access car methods")
        traceback.print_exc()

Ở đây,bike_adapter là một đối tượng của MotorcycleAdapter lớp. Chúng tôi đã cung cấp bike phản đối MotorcycleAdapter phương thức khởi tạo của lớp '. Việc thực thi tập lệnh này cho chúng ta kết quả sau:

Xem hướng dẫn thực hành, thực tế của chúng tôi để học Git, với các phương pháp hay nhất, các tiêu chuẩn được ngành công nghiệp chấp nhận và bảng lừa đảo đi kèm. Dừng lệnh Googling Git và thực sự học nó!

The Motorcycle

Subodh is riding the motorcycle
The speed of the motorcycle is 88 mph
The speed of the motorcycle is 35 mph after applying the brakes


The Car

Sushant is driving the car
The speed of the car is 91 mph
The speed of the car is 24 mph after applying the brakes


Attempting to call client methods with the service object

Attempting to call client methods with the service object using an adapter

Robert is riding the motorcyle
The speed of the motorcycle is 67 mph
The speed of the motorcycle is 25 mph after applying the brakes

Mà không cần phải điều chỉnh cơ bản Motorcycle lớp học, chúng ta có thể làm cho nó hoạt động như một Car sử dụng bộ chuyển đổi!

Ưu và nhược điểm của mẫu thiết kế bộ điều hợp

Ưu điểm của các mẫu bộ điều hợp là:

  • Chúng ta có thể đạt được sự kết hợp thấp giữa lớp bộ điều hợp và lớp khách hàng.
  • Chúng ta có thể sử dụng lại lớp bộ điều hợp để kết hợp nhiều lớp dịch vụ trong ứng dụng.
  • Chúng tôi có thể tăng tính linh hoạt của chương trình bằng cách giới thiệu nhiều bộ điều hợp mà không can thiệp vào mã máy khách

Nhược điểm của Mẫu Bộ điều hợp là:

  • Độ phức tạp của chương trình tăng lên khi bổ sung lớp bộ điều hợp và lớp dịch vụ.
  • Có sự gia tăng chi phí trong chương trình khi các yêu cầu được chuyển tiếp từ lớp này sang lớp khác.
  • Mẫu bộ điều hợp (bộ điều hợp lớp) sử dụng nhiều bản kế thừa, mà tất cả các ngôn ngữ lập trình có thể không hỗ trợ.

Kết luận

Trong bài viết này, chúng ta đã tìm hiểu về mẫu thiết kế bộ điều hợp, các loại của nó và các vấn đề mà chúng giải quyết. Chúng tôi đã triển khai Mẫu bộ điều hợp bằng Python để chúng tôi có thể tương tác với Motorcycle đối tượng, giống như một Car đối tượng bằng cách sử dụng một bộ điều hợp để giao diện của mỗi lớp không thay đổi.

Dấu thời gian:

Thêm từ xếp chồng lên nhau