Các mẫu thiết kế Python - Hướng dẫn nhanh

Các mẫu thiết kế được sử dụng để đại diện cho mẫu được các nhà phát triển sử dụng để tạo phần mềm hoặc ứng dụng web. Các mẫu này được lựa chọn dựa trên phân tích yêu cầu. Các mẫu mô tả giải pháp cho vấn đề, khi nào và ở đâu áp dụng giải pháp và hậu quả của việc thực hiện.

Cấu trúc của một mẫu thiết kế

Tài liệu về mẫu thiết kế được duy trì theo cách tập trung nhiều hơn vào công nghệ được sử dụng và theo những cách nào. Sơ đồ sau đây giải thích cấu trúc cơ bản của tài liệu mẫu thiết kế.

Tên mẫu

Nó mô tả mô hình một cách ngắn gọn và hiệu quả.

Ý định / Động cơ

Nó mô tả những gì mẫu làm.

Khả năng áp dụng

Nó mô tả danh sách các tình huống có thể áp dụng mẫu.

Những người tham gia và hậu quả

Những người tham gia bao gồm các lớp và đối tượng tham gia vào mẫu thiết kế với một danh sách các hệ quả tồn tại với mẫu.

Tại sao lại là Python?

Python là một ngôn ngữ kịch bản mã nguồn mở. Nó có các thư viện hỗ trợ nhiều mẫu thiết kế. Cú pháp của python rất dễ hiểu và sử dụng từ khóa tiếng Anh.

Python cung cấp hỗ trợ cho danh sách các mẫu thiết kế được đề cập bên dưới. Các mẫu thiết kế này sẽ được sử dụng trong suốt hướng dẫn này -

  • Mẫu bộ điều khiển chế độ xem mô hình
  • Mô hình singleton
  • Mẫu nhà máy
  • Mô hình trình xây dựng
  • Mẫu nguyên mẫu
  • Mẫu mặt tiền
  • Mẫu lệnh
  • Mẫu bộ điều hợp
  • Mẫu nguyên mẫu
  • Mẫu trang trí
  • Mẫu proxy
  • Mô hình chuỗi trách nhiệm
  • Mẫu người quan sát
  • Mẫu trạng thái
  • Mô hình chiến lược
  • Mẫu Mẫu
  • Mẫu Flyweight
  • Mô hình nhà máy trừu tượng
  • Mẫu hướng đối tượng

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

Sau đây là những lợi ích khác nhau của mẫu thiết kế:

  • Các mẫu cung cấp cho nhà phát triển lựa chọn các giải pháp đã thử và đã thử nghiệm cho các vấn đề được chỉ định.

  • Tất cả các mẫu thiết kế là ngôn ngữ trung lập.

  • Các mẫu giúp đạt được giao tiếp và duy trì tốt tài liệu.

  • Nó bao gồm một hồ sơ về thành tích để giảm bất kỳ rủi ro kỹ thuật nào đối với dự án.

  • Các mẫu thiết kế rất linh hoạt để sử dụng và dễ hiểu.

Python là một ngôn ngữ kịch bản mã nguồn mở, là ngôn ngữ cấp cao, được thông dịch, tương tác và hướng đối tượng. Nó được thiết kế để dễ đọc. Cú pháp của ngôn ngữ Python dễ hiểu và sử dụng các từ khóa tiếng Anh thường xuyên.

Các tính năng của ngôn ngữ Python

Trong phần này, chúng ta sẽ tìm hiểu về các tính năng khác nhau của ngôn ngữ Python.

Đã thông dịch

Python được xử lý trong thời gian chạy bằng trình thông dịch. Không cần phải biên dịch chương trình trước khi thực thi. Nó tương tự như PERL và PHP.

Hướng đối tượng

Python tuân theo kiểu thiết kế và phong cách hướng đối tượng. Nó bao gồm định nghĩa lớp với các tính năng khác nhau như đóng gói, đa hình và nhiều tính năng khác.

Xách tay

Mã Python được viết trong hệ điều hành Windows và có thể được sử dụng trong hệ điều hành Mac. Mã có thể được sử dụng lại và di động theo yêu cầu.

Dễ mã

Cú pháp Python dễ hiểu và dễ viết mã. Bất kỳ nhà phát triển nào cũng có thể hiểu cú pháp của Python trong vòng vài giờ. Python có thể được mô tả là “thân thiện với lập trình viên”

Có thể mở rộng

Nếu cần, người dùng cũng có thể viết một số mã Python bằng ngôn ngữ C. Cũng có thể đặt mã python trong mã nguồn bằng các ngôn ngữ khác nhau như C ++. Điều này làm cho Python trở thành một ngôn ngữ có thể mở rộng.

Điểm quan trọng

Hãy xem xét các điểm quan trọng sau liên quan đến ngôn ngữ lập trình Python:

  • Nó bao gồm các phương pháp lập trình chức năng và cấu trúc cũng như các phương pháp lập trình hướng đối tượng.

  • Nó có thể được sử dụng như ngôn ngữ kịch bản hoặc ngôn ngữ lập trình.

  • Nó bao gồm thu gom rác tự động.

  • Nó bao gồm các kiểu dữ liệu động cấp cao và hỗ trợ nhiều kiểu kiểm tra động khác nhau.

  • Python bao gồm một tính năng tích hợp với C, C ++ và các ngôn ngữ như Java.

Làm cách nào để tải xuống ngôn ngữ python trong hệ thống của bạn?

Để tải xuống ngôn ngữ Python trong hệ thống của bạn, hãy nhấp vào liên kết này -

https://www.python.org/downloads/

Nó bao gồm các gói cho các hệ điều hành khác nhau như các bản phân phối Windows, MacOS và Linux.

Các công cụ quan trọng trong Python

Trong phần này, chúng ta sẽ tìm hiểu sơ lược về một vài công cụ quan trọng trong Python.

Chuỗi Python

Khai báo cơ bản của chuỗi như sau:

str = 'Hello World!'

Danh sách Python

Danh sách python có thể được khai báo dưới dạng kiểu dữ liệu phức hợp được phân tách bằng dấu phẩy và được đặt trong dấu ngoặc vuông ([]).

list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']

Python Tuples

Tuple là kiểu dữ liệu động của Python, bao gồm số lượng giá trị được phân tách bằng dấu phẩy. Các bộ giá trị được đặt trong dấu ngoặc đơn.

tinytuple = (123, 'john')

Từ điển Python

Từ điển Python là một loại bảng băm. Khóa từ điển có thể là hầu hết mọi kiểu dữ liệu của Python. Các kiểu dữ liệu thường là số hoặc chuỗi.

tinydict = {'name': 'omkar','code':6734, 'dept': 'sales'}

Điều gì tạo nên một mẫu thiết kế trong Python?

Python giúp tạo ra một mẫu thiết kế bằng cách sử dụng các tham số sau:

  • Tên mẫu
  • Intent
  • Aliases
  • Motivation
  • Problem
  • Solution
  • Structure
  • Participants
  • Constraints
  • Mã mẫu

Model View Controller là mẫu thiết kế được sử dụng phổ biến nhất. Các nhà phát triển thấy dễ dàng thực hiện mẫu thiết kế này.

Sau đây là kiến ​​trúc cơ bản của Model View Controller:

Bây giờ chúng ta hãy xem cấu trúc hoạt động như thế nào.

Mô hình

Nó bao gồm logic ứng dụng thuần túy, tương tác với cơ sở dữ liệu. Nó bao gồm tất cả thông tin để trình bày dữ liệu cho người dùng cuối.

Lượt xem

Chế độ xem đại diện cho các tệp HTML, tương tác với người dùng cuối. Nó đại diện cho dữ liệu của mô hình cho người dùng.

Bộ điều khiển

Nó hoạt động như một trung gian giữa khung nhìn và mô hình. Nó lắng nghe các sự kiện được kích hoạt bởi chế độ xem và mô hình truy vấn cho giống nhau.

Mã Python

Chúng ta hãy xem xét một đối tượng cơ bản được gọi là “Người” và tạo một mẫu thiết kế MVC.

Model.py

import json

class Person(object):
   def __init__(self, first_name = None, last_name = None):
      self.first_name = first_name
      self.last_name = last_name
   #returns Person name, ex: John Doe
   def name(self):
      return ("%s %s" % (self.first_name,self.last_name))
		
   @classmethod
   #returns all people inside db.txt as list of Person objects
   def getAll(self):
      database = open('db.txt', 'r')
      result = []
      json_list = json.loads(database.read())
      for item in json_list:
         item = json.loads(item)
         person = Person(item['first_name'], item['last_name'])
         result.append(person)
      return result

Nó gọi một phương thức, phương thức này tìm nạp tất cả các bản ghi của bảng Person trong cơ sở dữ liệu. Các bản ghi được trình bày ở định dạng JSON.

Lượt xem

Nó hiển thị tất cả các bản ghi được tìm nạp trong mô hình. Chế độ xem không bao giờ tương tác với mô hình; controller thực hiện công việc này (giao tiếp với model và view).

from model import Person
def showAllView(list):
   print 'In our db we have %i users. Here they are:' % len(list)
   for item in list:
      print item.name()
def startView():
   print 'MVC - the simplest example'
   print 'Do you want to see everyone in my db?[y/n]'
def endView():
   print 'Goodbye!'

Bộ điều khiển

Bộ điều khiển tương tác với mô hình thông qua getAll() phương thức tìm nạp tất cả các bản ghi được hiển thị cho người dùng cuối.

from model import Person
import view

def showAll():
   #gets list of all Person objects
   people_in_db = Person.getAll()
   #calls view
   return view.showAllView(people_in_db)

def start():
   view.startView()
   input = raw_input()
   if input == 'y':
      return showAll()
   else:
      return view.endView()

if __name__ == "__main__":
   #running controller function
   start()

Mẫu này hạn chế việc khởi tạo một lớp cho một đối tượng. Nó là một kiểu sáng tạo và chỉ liên quan đến một lớp để tạo các phương thức và các đối tượng được chỉ định.

Nó cung cấp một điểm truy cập toàn cầu cho cá thể được tạo.

Làm thế nào để triển khai một lớp singleton?

Chương trình sau đây trình bày việc triển khai lớp singleton nơi nó in các thể hiện được tạo nhiều lần.

class Singleton:
   __instance = None
   @staticmethod 
   def getInstance():
      """ Static access method. """
      if Singleton.__instance == None:
         Singleton()
      return Singleton.__instance
   def __init__(self):
      """ Virtually private constructor. """
      if Singleton.__instance != None:
         raise Exception("This class is a singleton!")
      else:
         Singleton.__instance = self
s = Singleton()
print s

s = Singleton.getInstance()
print s

s = Singleton.getInstance()
print s

Đầu ra

Chương trình trên tạo ra kết quả sau:

Số lượng cá thể được tạo là như nhau và không có sự khác biệt về các đối tượng được liệt kê trong đầu ra.

Mô hình nhà máy thuộc danh mục mô hình sáng tạo. Nó cung cấp một trong những cách tốt nhất để tạo một đối tượng. Trong mô hình gốc, các đối tượng được tạo ra mà không để lộ logic cho máy khách và tham chiếu đến đối tượng mới được tạo bằng giao diện chung.

Các mẫu nhà máy được triển khai bằng Python bằng phương pháp nhà máy. Khi người dùng gọi một phương thức mà chúng ta truyền vào một chuỗi và giá trị trả về dưới dạng một đối tượng mới được thực hiện thông qua phương thức gốc. Loại đối tượng được sử dụng trong phương thức factory được xác định bằng chuỗi được chuyển qua phương thức.

Trong ví dụ dưới đây, mọi phương thức đều bao gồm đối tượng dưới dạng tham số, được thực hiện thông qua phương thức gốc.

Làm thế nào để thực hiện một mô hình nhà máy?

Bây giờ chúng ta hãy xem làm thế nào để thực hiện một mô hình nhà máy.

class Button(object):
   html = ""
   def get_html(self):
      return self.html

class Image(Button):
   html = "<img></img>"

class Input(Button):
   html = "<input></input>"

class Flash(Button):
   html = "<obj></obj>"

class ButtonFactory():
   def create_button(self, typ):
      targetclass = typ.capitalize()
      return globals()[targetclass]()

button_obj = ButtonFactory()
button = ['image', 'input', 'flash']
for b in button:
   print button_obj.create_button(b).get_html()

Lớp nút giúp tạo các thẻ html và trang html được liên kết. Máy khách sẽ không có quyền truy cập vào logic của mã và đầu ra đại diện cho việc tạo trang html.

Đầu ra

Giải trình

Mã python bao gồm logic của các thẻ html, giá trị đã chỉ định. Người dùng cuối có thể xem tệp HTML được tạo bởi mã Python.

Builder Pattern là một mẫu thiết kế độc đáo giúp xây dựng đối tượng phức tạp bằng cách sử dụng các đối tượng đơn giản và sử dụng phương pháp tiếp cận thuật toán. Mẫu thiết kế này thuộc danh mục mẫu sáng tạo. Trong mẫu thiết kế này, một lớp người xây dựng sẽ xây dựng đối tượng cuối cùng trong thủ tục từng bước. Trình xây dựng này độc lập với các đối tượng khác.

Ưu điểm của Builder Pattern

  • Nó cung cấp sự phân tách rõ ràng và một lớp duy nhất giữa việc xây dựng và biểu diễn của một đối tượng cụ thể được tạo bởi lớp.

  • Nó cung cấp khả năng kiểm soát tốt hơn quá trình xây dựng của mẫu được tạo.

  • Nó đưa ra một kịch bản hoàn hảo để thay đổi biểu diễn bên trong của các đối tượng.

Làm thế nào để triển khai mẫu trình tạo?

Trong phần này, chúng ta sẽ tìm hiểu cách triển khai mẫu trình tạo.

class Director:
   __builder = None
   
   def setBuilder(self, builder):
      self.__builder = builder
   
   def getCar(self):
      car = Car()
      
      # First goes the body
      body = self.__builder.getBody()
      car.setBody(body)
      
      # Then engine
      engine = self.__builder.getEngine()
      car.setEngine(engine)
      
      # And four wheels
      i = 0
      while i < 4:
         wheel = self.__builder.getWheel()
			car.attachWheel(wheel)
         i += 1
      return car

# The whole product
class Car:
   def __init__(self):
      self.__wheels = list()
      self.__engine = None
      self.__body = None

   def setBody(self, body):
      self.__body = body

   def attachWheel(self, wheel):
      self.__wheels.append(wheel)

   def setEngine(self, engine):
      self.__engine = engine

   def specification(self):
      print "body: %s" % self.__body.shape
      print "engine horsepower: %d" % self.__engine.horsepower
      print "tire size: %d\'" % self.__wheels[0].size

class Builder:
      def getWheel(self): pass
      def getEngine(self): pass
      def getBody(self): pass

class JeepBuilder(Builder):
   
   def getWheel(self):
      wheel = Wheel()
      wheel.size = 22
      return wheel
   
   def getEngine(self):
      engine = Engine()
      engine.horsepower = 400
      return engine
   
   def getBody(self):
      body = Body()
      body.shape = "SUV"
      return body

# Car parts
class Wheel:
   size = None

class Engine:
   horsepower = None

class Body:
   shape = None

def main():
   jeepBuilder = JeepBuilder() # initializing the class
   
   director = Director()
   
   # Build Jeep
   print "Jeep"
   director.setBuilder(jeepBuilder)
   jeep = director.getCar()
   jeep.specification()
   print ""

if __name__ == "__main__":
   main()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Mẫu thiết kế nguyên mẫu giúp che giấu sự phức tạp của các thể hiện được tạo bởi lớp. Khái niệm về đối tượng hiện có sẽ khác với khái niệm của đối tượng mới, được tạo ra từ đầu.

Đối tượng mới được sao chép có thể có một số thay đổi trong các thuộc tính nếu được yêu cầu. Cách tiếp cận này tiết kiệm thời gian và nguồn lực dành cho việc phát triển sản phẩm.

Làm thế nào để thực hiện một mẫu nguyên mẫu?

Bây giờ chúng ta hãy xem cách triển khai một mẫu nguyên mẫu.

import copy

class Prototype:

   _type = None
   _value = None

   def clone(self):
      pass

   def getType(self):
      return self._type

   def getValue(self):
      return self._value

class Type1(Prototype):

   def __init__(self, number):
      self._type = "Type1"
      self._value = number

   def clone(self):
      return copy.copy(self)

class Type2(Prototype):

   """ Concrete prototype. """

   def __init__(self, number):
      self._type = "Type2"
      self._value = number

   def clone(self):
      return copy.copy(self)

class ObjectFactory:

   """ Manages prototypes.
   Static factory, that encapsulates prototype
   initialization and then allows instatiation
   of the classes from these prototypes.
   """

   __type1Value1 = None
   __type1Value2 = None
   __type2Value1 = None
   __type2Value2 = None

   @staticmethod
   def initialize():
      ObjectFactory.__type1Value1 = Type1(1)
      ObjectFactory.__type1Value2 = Type1(2)
      ObjectFactory.__type2Value1 = Type2(1)
      ObjectFactory.__type2Value2 = Type2(2)

   @staticmethod
   def getType1Value1():
      return ObjectFactory.__type1Value1.clone()

   @staticmethod
   def getType1Value2():
      return ObjectFactory.__type1Value2.clone()

   @staticmethod
   def getType2Value1():
      return ObjectFactory.__type2Value1.clone()

   @staticmethod
   def getType2Value2():
      return ObjectFactory.__type2Value2.clone()

def main():
   ObjectFactory.initialize()
   
   instance = ObjectFactory.getType1Value1()
   print "%s: %s" % (instance.getType(), instance.getValue())
   
   instance = ObjectFactory.getType1Value2()
   print "%s: %s" % (instance.getType(), instance.getValue())
   
   instance = ObjectFactory.getType2Value1()
   print "%s: %s" % (instance.getType(), instance.getValue())
   
   instance = ObjectFactory.getType2Value2()
   print "%s: %s" % (instance.getType(), instance.getValue())

if __name__ == "__main__":
   main()

Đầu ra

Chương trình trên sẽ tạo ra kết quả sau:

Đầu ra giúp tạo các đối tượng mới với các đối tượng hiện có và nó được hiển thị rõ ràng trong đầu ra được đề cập ở trên.

Mẫu thiết kế mặt tiền cung cấp một giao diện thống nhất cho một tập hợp các giao diện trong một hệ thống con. Nó định nghĩa một giao diện cấp cao hơn mà bất kỳ hệ thống con nào cũng có thể sử dụng.

Một lớp mặt tiền biết hệ thống con nào chịu trách nhiệm cho một yêu cầu.

Làm thế nào để thiết kế một mẫu mặt tiền?

Bây giờ chúng ta hãy xem cách thiết kế một mẫu mặt tiền.

class _IgnitionSystem(object):
   
   @staticmethod
   def produce_spark():
      return True

class _Engine(object):

   def __init__(self):
      self.revs_per_minute = 0

   def turnon(self):
      self.revs_per_minute = 2000
   
   def turnoff(self):
      self.revs_per_minute = 0

class _FuelTank(object):
   
   def __init__(self, level=30):
      self._level = level
   
   @property
   def level(self):
      return self._level
   
   @level.setter
	def level(self, level):
      self._level = level

class _DashBoardLight(object):

   def __init__(self, is_on=False):
      self._is_on = is_on

   def __str__(self):
      return self.__class__.__name__

   @property
   def is_on(self):
      return self._is_on
   
   @is_on.setter
   def is_on(self, status):
      self._is_on = status
   
   def status_check(self):
      if self._is_on:
         print("{}: ON".format(str(self)))
      else:
         print("{}: OFF".format(str(self)))

class _HandBrakeLight(_DashBoardLight):
   pass

class _FogLampLight(_DashBoardLight):
   pass

class _Dashboard(object):
   
   def __init__(self):
      self.lights = {"handbreak": _HandBrakeLight(), "fog": _FogLampLight()}
   
   def show(self):
	   for light in self.lights.values():
      light.status_check()

# Facade
class Car(object):
   
   def __init__(self):
      self.ignition_system = _IgnitionSystem()
      self.engine = _Engine()
      self.fuel_tank = _FuelTank()
      self.dashboard = _Dashboard()
   
   @property
   def km_per_litre(self):
      return 17.0
   
   def consume_fuel(self, km):
      litres = min(self.fuel_tank.level, km / self.km_per_litre)
      self.fuel_tank.level -= litres
   
   def start(self):
      print("\nStarting...")
      self.dashboard.show()
      if self.ignition_system.produce_spark():
         self.engine.turnon()
      else:
         print("Can't start. Faulty ignition system")
   
   def has_enough_fuel(self, km, km_per_litre):
      litres_needed = km / km_per_litre
      if self.fuel_tank.level > litres_needed:
         return True
      else:
         return False
	   
      def drive(self, km = 100):
         print("\n")
         if self.engine.revs_per_minute > 0:
            while self.has_enough_fuel(km, self.km_per_litre):
               self.consume_fuel(km)
               print("Drove {}km".format(km))
               print("{:.2f}l of fuel still left".format(self.fuel_tank.level))
         else:
            print("Can't drive. The Engine is turned off!")
         
         def park(self):
            print("\nParking...")
            self.dashboard.lights["handbreak"].is_on = True
            self.dashboard.show()
            self.engine.turnoff()
         
         def switch_fog_lights(self, status):
            print("\nSwitching {} fog lights...".format(status))
            boolean = True if status == "ON" else False
            self.dashboard.lights["fog"].is_on = boolean
            self.dashboard.show()
         
         def fill_up_tank(self):
            print("\nFuel tank filled up!")
            self.fuel_tank.level = 100
				
# the main function is the Client
def main():
   car = Car()
   car.start()
   car.drive()
   car.switch_fog_lights("ON")
   car.switch_fog_lights("OFF")
	car.park()
   car.fill_up_tank()
   car.drive()
   car.start()
   car.drive()

if __name__ == "__main__":
   main()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

Chương trình này được thiết kế với một kịch bản. Đó là khởi động động cơ của ô tô hoặc bất kỳ phương tiện lái xe nào. Nếu bạn quan sát mã, nó bao gồm các chức năng liên quan để lái xe, đỗ xe và tiêu thụ nhiên liệu.

Command Pattern bổ sung một mức độ trừu tượng giữa các hành động và bao gồm một đối tượng, gọi các hành động này.

Trong mẫu thiết kế này, khách hàng tạo một đối tượng lệnh bao gồm một danh sách các lệnh sẽ được thực thi. Đối tượng lệnh được tạo thực hiện một giao diện cụ thể.

Sau đây là kiến ​​trúc cơ bản của mẫu lệnh:

Làm thế nào để thực hiện mẫu lệnh?

Bây giờ chúng ta sẽ xem cách thực hiện mẫu thiết kế.

def demo(a,b,c):
   print 'a:',a
   print 'b:',b
   print 'c:',c

class Command:
   def __init__(self, cmd, *args):
      self._cmd=cmd
      self._args=args

   def __call__(self, *args):
      return apply(self._cmd, self._args+args)
cmd = Command(dir,__builtins__)
print cmd()

cmd = Command(demo,1,2)
cmd(3)

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

Đầu ra thực hiện tất cả các lệnh và từ khóa được liệt kê bằng ngôn ngữ Python. Nó in ra các giá trị cần thiết của các biến.

Mẫu bộ điều hợp hoạt động như một cầu nối giữa hai giao diện không tương thích. Loại mẫu thiết kế này thuộc mẫu cấu trúc vì mẫu này kết hợp khả năng của hai giao diện độc lập.

Mẫu này liên quan đến một lớp duy nhất, có trách nhiệm tham gia các chức năng của các giao diện độc lập hoặc không tương thích. Một ví dụ thực tế có thể là trường hợp của đầu đọc thẻ, hoạt động như một bộ chuyển đổi giữa thẻ nhớ và máy tính xách tay. Bạn cắm thẻ nhớ vào đầu đọc thẻ và đầu đọc thẻ vào laptop để thẻ nhớ đọc qua laptop.

Mẫu thiết kế bộ điều hợp giúp làm việc các lớp với nhau. Nó chuyển đổi giao diện của một lớp thành một giao diện khác dựa trên yêu cầu. Mẫu bao gồm một đặc tả là một dạng đa hình có tên một tên và nhiều dạng. Giả sử một lớp hình dạng có thể sử dụng theo các yêu cầu được thu thập.

Có hai loại mẫu bộ điều hợp -

Mẫu bộ điều hợp đối tượng

Mẫu thiết kế này dựa vào việc triển khai đối tượng. Do đó, nó được gọi là Object Adapter Pattern.

Mẫu bộ điều hợp lớp

Đây là một cách thay thế để triển khai mẫu thiết kế bộ điều hợp. Mẫu có thể được thực hiện bằng cách sử dụng nhiều kế thừa.

Làm thế nào để triển khai mẫu bộ điều hợp?

Bây giờ chúng ta hãy xem cách triển khai mẫu bộ điều hợp.

class EuropeanSocketInterface:
   def voltage(self): pass

   def live(self): pass
   def neutral(self): pass
   def earth(self): pass

# Adaptee
class Socket(EuropeanSocketInterface):
   def voltage(self):
      return 230

	def live(self):
      return 1
   
   def neutral(self):
      return -1
   
   def earth(self):
      return 0

# Target interface
class USASocketInterface:
   def voltage(self): pass
   def live(self): pass
   def neutral(self): pass

# The Adapter
class Adapter(USASocketInterface):
   __socket = None
   def __init__(self, socket):
      self.__socket = socket
   
   def voltage(self):
      return 110
   
   def live(self):
      return self.__socket.live()
   
   def neutral(self):
      return self.__socket.neutral()

# Client
class ElectricKettle:
   __power = None
   
   def __init__(self, power):
	   self.__power = power
   
   def boil(self):
      if self.__power.voltage() > 110:
         print "Kettle on fire!"
      else:
         if self.__power.live() == 1 and \
            self.__power.neutral() == -1:
            print "Coffee time!"
         else:
            print "No power."

def main():
   # Plug in
   socket = Socket()
   adapter = Adapter(socket)
   kettle = ElectricKettle(adapter)
	
   # Make coffee
   kettle.boil()
	
   return 0
	
if __name__ == "__main__":
   main()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

Mã bao gồm giao diện bộ điều hợp với các thông số và thuộc tính khác nhau. Nó bao gồm Adaptee cùng với giao diện Target thực hiện tất cả các thuộc tính và hiển thị đầu ra dưới dạng hiển thị.

Mẫu trang trí cho phép người dùng thêm chức năng mới vào một đối tượng hiện có mà không làm thay đổi cấu trúc của nó. Loại mẫu thiết kế này nằm dưới mẫu cấu trúc vì mẫu này hoạt động như một lớp bao bọc cho lớp hiện có.

Mẫu này tạo ra một lớp decorator, lớp này bao bọc lớp ban đầu và cung cấp chức năng bổ sung giữ nguyên chữ ký của các phương thức lớp.

Động cơ của một mẫu trang trí là gắn các trách nhiệm bổ sung của một đối tượng một cách động.

Cách triển khai mẫu thiết kế trang trí

Đoạn mã được đề cập bên dưới là một minh chứng đơn giản về cách triển khai mẫu thiết kế decorator trong Python. Hình minh họa liên quan đến việc trình diễn một quán cà phê dưới dạng lớp học. Lớp cà phê được tạo ra là một trừu tượng, có nghĩa là nó không thể được tạo ra ngay lập tức.

import six
from abc import ABCMeta

@six.add_metaclass(ABCMeta)
class Abstract_Coffee(object):

   def get_cost(self):
      pass

   def get_ingredients(self):
      pass
   
   def get_tax(self):
      return 0.1*self.get_cost()

class Concrete_Coffee(Abstract_Coffee):
   
   def get_cost(self):
      return 1.00
   
   def get_ingredients(self):
      return 'coffee'

@six.add_metaclass(ABCMeta)
class Abstract_Coffee_Decorator(Abstract_Coffee):
   
   def __init__(self,decorated_coffee):
      self.decorated_coffee = decorated_coffee
   
   def get_cost(self):
      return self.decorated_coffee.get_cost()
   
   def get_ingredients(self):
      return self.decorated_coffee.get_ingredients()

class Sugar(Abstract_Coffee_Decorator):
   
   def __init__(self,decorated_coffee):
      Abstract_Coffee_Decorator.__init__(self,decorated_coffee)
   
   def get_cost(self):
      return self.decorated_coffee.get_cost()
   
   def get_ingredients(self):
	   return self.decorated_coffee.get_ingredients() + ', sugar'

class Milk(Abstract_Coffee_Decorator):
   
   def __init__(self,decorated_coffee):
      Abstract_Coffee_Decorator.__init__(self,decorated_coffee)
   
   def get_cost(self):
      return self.decorated_coffee.get_cost() + 0.25
   
   def get_ingredients(self):
      return self.decorated_coffee.get_ingredients() + ', milk'

class Vanilla(Abstract_Coffee_Decorator):
   
   def __init__(self,decorated_coffee):
      Abstract_Coffee_Decorator.__init__(self,decorated_coffee)
   
   def get_cost(self):
      return self.decorated_coffee.get_cost() + 0.75
   
   def get_ingredients(self):
      return self.decorated_coffee.get_ingredients() + ', vanilla'

Việc triển khai lớp trừu tượng của quán cà phê được thực hiện với một tệp riêng biệt như được đề cập bên dưới:

import coffeeshop

myCoffee = coffeeshop.Concrete_Coffee()
print('Ingredients: '+myCoffee.get_ingredients()+
   '; Cost: '+str(myCoffee.get_cost())+'; sales tax = '+str(myCoffee.get_tax()))

myCoffee = coffeeshop.Milk(myCoffee)
print('Ingredients: '+myCoffee.get_ingredients()+
   '; Cost: '+str(myCoffee.get_cost())+'; sales tax = '+str(myCoffee.get_tax()))

myCoffee = coffeeshop.Vanilla(myCoffee)
print('Ingredients: '+myCoffee.get_ingredients()+
   '; Cost: '+str(myCoffee.get_cost())+'; sales tax = '+str(myCoffee.get_tax()))

myCoffee = coffeeshop.Sugar(myCoffee)
print('Ingredients: '+myCoffee.get_ingredients()+
   '; Cost: '+str(myCoffee.get_cost())+'; sales tax = '+str(myCoffee.get_tax()))

Đầu ra

Chương trình trên tạo ra kết quả sau:

Mẫu thiết kế proxy bao gồm một đối tượng mới, được gọi là “Proxy” thay cho một đối tượng hiện có được gọi là “Đối tượng thực”. Đối tượng proxy được tạo ra bởi chủ thể thực phải nằm trên cùng một giao diện theo cách mà khách hàng không được biết rằng proxy được sử dụng thay cho đối tượng thực. Các yêu cầu do máy khách tạo ra cho proxy được chuyển qua chủ thể thực.

Biểu diễn UML của mẫu proxy như sau:

Làm thế nào để triển khai mẫu proxy?

Bây giờ chúng ta hãy xem cách triển khai mẫu proxy.

class Image:
   def __init__( self, filename ):
      self._filename = filename
   
   def load_image_from_disk( self ):
      print("loading " + self._filename )
   
   def display_image( self ):
      print("display " + self._filename)

class Proxy:
   def __init__( self, subject ):
      self._subject = subject
      self._proxystate = None

class ProxyImage( Proxy ):
   def display_image( self ):
      if self._proxystate == None:
         self._subject.load_image_from_disk()
         self._proxystate = 1
      print("display " + self._subject._filename )

proxy_image1 = ProxyImage ( Image("HiRes_10Mb_Photo1") )
proxy_image2 = ProxyImage ( Image("HiRes_10Mb_Photo2") )

proxy_image1.display_image() # loading necessary
proxy_image1.display_image() # loading unnecessary
proxy_image2.display_image() # loading necessary
proxy_image2.display_image() # loading unnecessary
proxy_image1.display_image() # loading unnecessary

Đầu ra

Chương trình trên tạo ra kết quả sau:

Thiết kế mẫu proxy giúp tái tạo các hình ảnh mà chúng tôi đã tạo. Hàm display_image () giúp kiểm tra xem các giá trị có được in trong dấu nhắc lệnh hay không.

Mẫu chuỗi trách nhiệm được sử dụng để đạt được sự liên kết lỏng lẻo trong phần mềm nơi một yêu cầu cụ thể từ khách hàng được chuyển qua một chuỗi các đối tượng có trong đó. Nó giúp xây dựng một chuỗi các đối tượng. Yêu cầu đi vào từ một đầu và chuyển từ đối tượng này sang đối tượng khác.

Mẫu này cho phép một đối tượng gửi một lệnh mà không cần biết đối tượng nào sẽ xử lý yêu cầu.

Làm thế nào để thực hiện mô hình chuỗi trách nhiệm?

Bây giờ chúng ta sẽ xem cách thực hiện mô hình chuỗi trách nhiệm.

class ReportFormat(object):
   PDF = 0
   TEXT = 1
class Report(object):
   def __init__(self, format_):
      self.title = 'Monthly report'
      self.text = ['Things are going', 'really, really well.']
      self.format_ = format_

class Handler(object):
   def __init__(self):
      self.nextHandler = None

   def handle(self, request):
      self.nextHandler.handle(request)

class PDFHandler(Handler):

   def handle(self, request):
      if request.format_ == ReportFormat.PDF:
         self.output_report(request.title, request.text)
      else:
         super(PDFHandler, self).handle(request)
	
   def output_report(self, title, text):
      print '<html>'
      print ' <head>'
      print ' <title>%s</title>' % title
      print ' </head>'
      print ' <body>'
      for line in text:
         print ' <p>%s

' % line print ' </body>' print '</html>' class TextHandler(Handler): def handle(self, request): if request.format_ == ReportFormat.TEXT: self.output_report(request.title, request.text) else: super(TextHandler, self).handle(request) def output_report(self, title, text): print 5*'*' + title + 5*'*' for line in text: print line class ErrorHandler(Handler): def handle(self, request): print "Invalid request" if __name__ == '__main__': report = Report(ReportFormat.TEXT) pdf_handler = PDFHandler() text_handler = TextHandler() pdf_handler.nextHandler = text_handler text_handler.nextHandler = ErrorHandler() pdf_handler.handle(report)

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

Đoạn mã trên tạo một báo cáo cho các nhiệm vụ hàng tháng, nơi nó gửi lệnh qua từng chức năng. Cần hai trình xử lý - cho PDF và cho văn bản. Nó in ra kết quả sau khi đối tượng được yêu cầu thực hiện từng chức năng.

Trong mô hình này, các đối tượng được biểu thị như những người quan sát chờ một sự kiện kích hoạt. Một người quan sát gắn vào chủ thể một khi sự kiện được chỉ định xảy ra. Khi sự kiện xảy ra, chủ thể nói với những người quan sát rằng nó đã xảy ra.

Biểu đồ UML sau đại diện cho mẫu người quan sát:

Làm thế nào để thực hiện mô hình quan sát viên?

Bây giờ chúng ta hãy xem cách triển khai mô hình quan sát viên.

import threading
import time
import pdb

class Downloader(threading.Thread):
   
   def run(self):
      print 'downloading'
      for i in range(1,5):
         self.i = i
         time.sleep(2)
			print 'unfunf'
         return 'hello world'

class Worker(threading.Thread):
   def run(self):
      for i in range(1,5):
         print 'worker running: %i (%i)' % (i, t.i)
         time.sleep(1)
         t.join()

         print 'done'

t = Downloader()
t.start()

time.sleep(1)

t1 = Worker()
t1.start()

t2 = Worker()
t2.start()

t3 = Worker()
t3.start()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

Đoạn mã trên giải thích quy trình tải xuống một kết quả cụ thể. Theo logic của mẫu người quan sát, mọi đối tượng được coi là người quan sát. Nó in đầu ra khi sự kiện được kích hoạt.

Nó cung cấp một mô-đun cho các máy trạng thái, được thực hiện bằng cách sử dụng các lớp con, bắt nguồn từ một lớp máy trạng thái được chỉ định. Các phương thức là trạng thái độc lập và gây ra các chuyển đổi được khai báo bằng cách sử dụng trình trang trí.

Làm thế nào để thực hiện mô hình trạng thái?

Cách triển khai cơ bản của mẫu trạng thái được hiển thị bên dưới:

class ComputerState(object):

   name = "state"
   allowed = []

   def switch(self, state):
      """ Switch to new state """
      if state.name in self.allowed:
         print 'Current:',self,' => switched to new state',state.name
         self.__class__ = state
      else:
         print 'Current:',self,' => switching to',state.name,'not possible.'

   def __str__(self):
      return self.name

class Off(ComputerState):
   name = "off"
   allowed = ['on']

class On(ComputerState):
   """ State of being powered on and working """
   name = "on"
   allowed = ['off','suspend','hibernate']

class Suspend(ComputerState):
   """ State of being in suspended mode after switched on """
   name = "suspend"
   allowed = ['on']

class Hibernate(ComputerState):
   """ State of being in hibernation after powered on """
   name = "hibernate"
   allowed = ['on']

class Computer(object):
   """ A class representing a computer """
   
   def __init__(self, model='HP'):
      self.model = model
      # State of the computer - default is off.
      self.state = Off()
   
   def change(self, state):
      """ Change state """
      self.state.switch(state)

if __name__ == "__main__":
   comp = Computer()
   comp.change(On)
   comp.change(Off)
   comp.change(On)
   comp.change(Suspend)
   comp.change(Hibernate)
   comp.change(On)
   comp.change(Off)

Đầu ra

Chương trình trên tạo ra kết quả sau:

Mô hình chiến lược là một loại mô hình hành vi. Mục tiêu chính của mô hình chiến lược là cho phép khách hàng chọn từ các thuật toán hoặc thủ tục khác nhau để hoàn thành nhiệm vụ được chỉ định. Các thuật toán khác nhau có thể được hoán đổi trong và ngoài mà không có bất kỳ sự phức tạp nào cho tác vụ được đề cập.

Mẫu này có thể được sử dụng để cải thiện tính linh hoạt khi các tài nguyên bên ngoài được truy cập.

Làm thế nào để thực hiện mô hình chiến lược?

Chương trình hiển thị bên dưới giúp thực hiện mô hình chiến lược.

import types

class StrategyExample:
   def __init__(self, func = None):
      self.name = 'Strategy Example 0'
      if func is not None:
         self.execute = types.MethodType(func, self)

   def execute(self):
      print(self.name)

def execute_replacement1(self): 
   print(self.name + 'from execute 1')

def execute_replacement2(self):
   print(self.name + 'from execute 2')

if __name__ == '__main__':
   strat0 = StrategyExample()
   strat1 = StrategyExample(execute_replacement1)
   strat1.name = 'Strategy Example 1'
   strat2 = StrategyExample(execute_replacement2)
   strat2.name = 'Strategy Example 2'
   strat0.execute()
   strat1.execute()
   strat2.execute()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

Nó cung cấp một danh sách các chiến lược từ các hàm để thực thi đầu ra. Trọng tâm chính của mẫu hành vi này là hành vi.

Một mẫu khuôn mẫu xác định một thuật toán cơ bản trong một lớp cơ sở bằng cách sử dụng thao tác trừu tượng trong đó các lớp con ghi đè hành vi cụ thể. Mẫu mẫu giữ phác thảo của thuật toán trong một phương pháp riêng biệt. Phương pháp này được gọi là phương pháp khuôn mẫu.

Sau đây là các tính năng khác nhau của mẫu mẫu:

  • Nó xác định khung của thuật toán trong một hoạt động

  • Nó bao gồm các lớp con, xác định lại các bước nhất định của một thuật toán.

class MakeMeal:

   def prepare(self): pass
   def cook(self): pass
   def eat(self): pass

   def go(self):
      self.prepare()
      self.cook()
      self.eat()

class MakePizza(MakeMeal):
   def prepare(self):
      print "Prepare Pizza"
   
   def cook(self):
      print "Cook Pizza"
   
   def eat(self):
      print "Eat Pizza"

class MakeTea(MakeMeal):
   def prepare(self):
      print "Prepare Tea"
	
   def cook(self):
      print "Cook Tea"
   
   def eat(self):
      print "Eat Tea"

makePizza = MakePizza()
makePizza.go()

print 25*"+"

makeTea = MakeTea()
makeTea.go()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

Mã này tạo ra một mẫu để chuẩn bị bữa ăn. Ở đây, mỗi tham số đại diện cho thuộc tính để tạo một phần của bữa ăn như trà, bánh pizza, v.v.

Đầu ra thể hiện sự trực quan hóa của các thuộc tính.

Mẫu flyweight thuộc danh mục mẫu thiết kế kết cấu. Nó cung cấp một cách để giảm số lượng đối tượng. Nó bao gồm các tính năng khác nhau giúp cải thiện cấu trúc ứng dụng. Tính năng quan trọng nhất của các đối tượng trọng lượng bay là bất biến. Điều này có nghĩa là chúng không thể được sửa đổi sau khi xây dựng. Mẫu sử dụng HashMap để lưu trữ các đối tượng tham chiếu.

Làm thế nào để thực hiện mô hình hạng ruồi?

Chương trình sau đây giúp thực hiện mô hình hạng ruồi:

class ComplexGenetics(object):
   def __init__(self):
      pass
   
   def genes(self, gene_code):
      return "ComplexPatter[%s]TooHugeinSize" % (gene_code)
class Families(object):
   family = {}
   
   def __new__(cls, name, family_id):
      try:
         id = cls.family[family_id]
      except KeyError:
         id = object.__new__(cls)
         cls.family[family_id] = id
      return id
   
   def set_genetic_info(self, genetic_info):
      cg = ComplexGenetics()
      self.genetic_info = cg.genes(genetic_info)
   
   def get_genetic_info(self):
      return (self.genetic_info)

def test():
   data = (('a', 1, 'ATAG'), ('a', 2, 'AAGT'), ('b', 1, 'ATAG'))
   family_objects = []
   for i in data:
      obj = Families(i[0], i[1])
      obj.set_genetic_info(i[2])
      family_objects.append(obj)
   
   for i in family_objects:
      print "id = " + str(id(i))
      print i.get_genetic_info()
   print "similar id's says that they are same objects "

if __name__ == '__main__':
   test()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Mô hình nhà máy trừu tượng còn được gọi là nhà máy của các nhà máy. Mẫu thiết kế này thuộc danh mục mẫu thiết kế sáng tạo. Nó cung cấp một trong những cách tốt nhất để tạo một đối tượng.

Nó bao gồm một giao diện, có nhiệm vụ tạo các đối tượng liên quan đến Factory.

Làm thế nào để thực hiện mô hình nhà máy trừu tượng?

Chương trình sau đây giúp thực hiện mô hình nhà máy trừu tượng.

class Window:
   __toolkit = ""
   __purpose = ""

   def __init__(self, toolkit, purpose):
      self.__toolkit = toolkit
      self.__purpose = purpose
   
   def getToolkit(self):
      return self.__toolkit
   
   def getType(self):
      return self.__purpose

class GtkToolboxWindow(Window):
   def __init__(self):
      Window.__init__(self, "Gtk", "ToolboxWindow")

class GtkLayersWindow(Window):
   def __init__(self):
      Window.__init__(self, "Gtk", "LayersWindow")

class GtkMainWindow(Window):
   def __init__(self):
      Window.__init__(self, "Gtk", "MainWindow")

class QtToolboxWindow(Window):
   def __init__(self):
      Window.__init__(self, "Qt", "ToolboxWindow")

class QtLayersWindow(Window):
   def __init__(self):
      Window.__init__(self, "Qt", "LayersWindow")

class QtMainWindow(Window):
   def __init__(self):
      Window.__init__(self, "Qt", "MainWindow")

# Abstract factory class
class UIFactory:
   def getToolboxWindow(self): pass
   def getLayersWindow(self): pass
   def getMainWindow(self): pass

class GtkUIFactory(UIFactory):
   def getToolboxWindow(self):
      return GtkToolboxWindow()
   def getLayersWindow(self):
      return GtkLayersWindow()
   def getMainWindow(self):
      return GtkMainWindow()

class QtUIFactory(UIFactory):
   def getToolboxWindow(self):
      return QtToolboxWindow()
   def getLayersWindow(self):
      return QtLayersWindow()
   def getMainWindow(self):
      return QtMainWindow()

if __name__ == "__main__":
   gnome = True
   kde = not gnome
   
   if gnome:
      ui = GtkUIFactory()
   elif kde:
      ui = QtUIFactory()
   
   toolbox = ui.getToolboxWindow()
   layers = ui.getLayersWindow()
   main = ui.getMainWindow()
   
   print "%s:%s" % (toolbox.getToolkit(), toolbox.getType())
   print "%s:%s" % (layers.getToolkit(), layers.getType())
   print "%s:%s" % (main.getToolkit(), main.getType())

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

Trong chương trình trên, nhà máy trừu tượng tạo các đối tượng cho mỗi cửa sổ. Nó gọi cho mỗi phương thức, thực thi đầu ra như mong đợi.

Mẫu hướng đối tượng là mẫu được sử dụng phổ biến nhất. Mẫu này có thể được tìm thấy trong hầu hết mọi ngôn ngữ lập trình.

Làm thế nào để triển khai mô hình hướng đối tượng?

Bây giờ chúng ta hãy xem cách triển khai mẫu hướng đối tượng.

class Parrot:
   # class attribute
   species = "bird"
	
   # instance attribute
   def __init__(self, name, age):
      self.name = name
      self.age = age
		
# instantiate the Parrot class
blu = Parrot("Blu", 10)
woo = Parrot("Woo", 15)

# access the class attributes
print("Blu is a {}".format(blu.__class__.species))
print("Woo is also a {}".format(woo.__class__.species))

# access the instance attributes
print("{} is {} years old".format( blu.name, blu.age))
print("{} is {} years old".format( woo.name, woo.age))

Đầu ra

Chương trình trên tạo ra kết quả sau

Giải trình

Mã bao gồm thuộc tính lớp và thuộc tính cá thể, được in theo yêu cầu của đầu ra. Có nhiều tính năng khác nhau tạo thành một phần của mẫu hướng đối tượng. Các tính năng được giải thích trong chương tiếp theo.

Trong chương này, chúng ta sẽ tập trung vào các mẫu sử dụng khái niệm hướng đối tượng và việc triển khai nó trong Python. Khi chúng ta thiết kế chương trình của mình xung quanh các khối lệnh, thao tác dữ liệu xung quanh các hàm, nó được gọi là lập trình hướng thủ tục. Trong lập trình hướng đối tượng, có hai thể hiện chính được gọi là lớp và đối tượng.

Làm thế nào để triển khai các lớp và các biến đối tượng?

Việc triển khai các lớp và các biến đối tượng như sau:

class Robot:
   population = 0
   
   def __init__(self, name):
      self.name = name
      print("(Initializing {})".format(self.name))
      Robot.population += 1
   
   def die(self):
      print("{} is being destroyed!".format(self.name))
      Robot.population -= 1
      if Robot.population == 0:
         print("{} was the last one.".format(self.name))
      else:
         print("There are still {:d} robots working.".format(
            Robot.population))
   
   def say_hi(self):
      print("Greetings, my masters call me {}.".format(self.name))
   
   @classmethod
   def how_many(cls):
      print("We have {:d} robots.".format(cls.population))
droid1 = Robot("R2-D2")
droid1.say_hi()
Robot.how_many()

droid2 = Robot("C-3PO")
droid2.say_hi()
Robot.how_many()

print("\nRobots can do some work here.\n")

print("Robots have finished their work. So let's destroy them.")
droid1.die()
droid2.die()

Robot.how_many()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

Hình minh họa này giúp chứng minh bản chất của các biến lớp và đối tượng.

  • "Dân số" thuộc về lớp "Robot". Do đó, nó được gọi là một biến lớp hoặc một đối tượng.

  • Ở đây, chúng tôi đề cập đến biến lớp dân số là Robot.population chứ không phải self.population.

Mẫu thiết kế trình lặp thuộc danh mục mẫu thiết kế hành vi. Các nhà phát triển bắt gặp mô hình trình lặp trong hầu hết mọi ngôn ngữ lập trình. Mẫu này được sử dụng theo cách giúp truy cập các phần tử của một tập hợp (lớp) theo cách tuần tự mà không cần hiểu thiết kế lớp bên dưới.

Làm thế nào để triển khai mô hình trình lặp?

Bây giờ chúng ta sẽ xem cách triển khai mô hình trình lặp.

import time

def fib():
   a, b = 0, 1
   while True:
      yield b
      a, b = b, a + b

g = fib()

try:
   for e in g:
      print(e)
      time.sleep(1)

except KeyboardInterrupt:
   print("Calculation stopped")

Đầu ra

Chương trình trên tạo ra kết quả sau:

Nếu bạn tập trung vào mẫu, chuỗi Fibonacci được in bằng mẫu lặp. Khi người dùng buộc phải chấm dứt, kết quả sau sẽ được in:

Giải trình

Mã python này tuân theo mẫu trình lặp. Ở đây, các toán tử tăng dần được sử dụng để bắt đầu đếm. Số lượng kết thúc khi người dùng buộc phải chấm dứt.

Từ điển là cấu trúc dữ liệu, bao gồm một tổ hợp giá trị khóa. Chúng được sử dụng rộng rãi thay cho JSON - JavaScript Object Notation. Từ điển được sử dụng để lập trình API (Giao diện lập trình ứng dụng). Một từ điển ánh xạ một nhóm đối tượng sang một nhóm đối tượng khác. Từ điển có thể thay đổi; điều này có nghĩa là chúng có thể được thay đổi khi cần thiết dựa trên các yêu cầu.

Làm thế nào để triển khai từ điển trong Python?

Chương trình sau đây cho thấy cách triển khai cơ bản của từ điển trong Python bắt đầu từ khi tạo đến khi thực hiện.

# Create a new dictionary
d = dict() # or d = {}

# Add a key - value pairs to dictionary
d['xyz'] = 123
d['abc'] = 345

# print the whole dictionary
print(d)

# print only the keys
print(d.keys())

# print only values
print(d.values())

# iterate over dictionary
for i in d :
   print("%s %d" %(i, d[i]))
	
# another method of iteration
for index, value in enumerate(d):
   print (index, value , d[value])

# check if key exist 23. Python Data Structure –print('xyz' in d)

# delete the key-value pair
del d['xyz']

# check again
print("xyz" in d)

Đầu ra

Chương trình trên tạo ra kết quả sau:

Note −Có những hạn chế liên quan đến việc triển khai các từ điển trong Python.

Hạn chế

Từ điển không hỗ trợ hoạt động trình tự của các kiểu dữ liệu trình tự như chuỗi, bộ giá trị và danh sách. Chúng thuộc về kiểu ánh xạ dựng sẵn.

Cấu trúc dữ liệu Danh sách là một kiểu dữ liệu đa năng trong Python, có thể được viết dưới dạng danh sách các giá trị được phân tách bằng dấu phẩy giữa các dấu ngoặc vuông.

Cú pháp

Đây là cú pháp cơ bản cho cấu trúc -

List_name = [ elements ];

Nếu bạn quan sát, cú pháp được khai báo giống như các mảng với điểm khác biệt duy nhất là danh sách có thể bao gồm các phần tử với các kiểu dữ liệu khác nhau. Mảng bao gồm các phần tử của cùng một kiểu dữ liệu. Một danh sách có thể chứa sự kết hợp của chuỗi, số nguyên và đối tượng. Danh sách có thể được sử dụng để thực hiện các ngăn xếp và hàng đợi.

Danh sách có thể thay đổi. Chúng có thể được thay đổi khi cần thiết.

Làm thế nào để triển khai danh sách?

Chương trình sau đây cho thấy việc triển khai các danh sách:

my_list = ['p','r','o','b','e']
# Output: p
print(my_list[0])

# Output: o
print(my_list[2])

# Output: e
print(my_list[4])

# Error! Only integer can be used for indexing
# my_list[4.0]

# Nested List
n_list = ["Happy", [2,0,1,5]]

# Nested indexing

# Output: a
print(n_list[0][1])

# Output: 5
print(n_list[1][3])

Đầu ra

Chương trình trên tạo ra kết quả sau:

Các hàm tích hợp của danh sách Python như sau:

  • Append()- Nó thêm phần tử vào cuối danh sách.

  • Extend()- Nó thêm các phần tử của danh sách vào danh sách khác.

  • Insert()- Nó chèn một mục vào chỉ mục xác định.

  • Remove()- Nó xóa phần tử khỏi danh sách được chỉ định.

  • Reverse()- Nó đảo ngược các phần tử trong danh sách.

  • sort() - Nó giúp sắp xếp các phần tử theo thứ tự thời gian.

Một tập hợp có thể được định nghĩa là tập hợp không có thứ tự có thể lặp lại, có thể thay đổi và không bao gồm các phần tử trùng lặp trong đó. Trong Python, lớp tập hợp là một ký hiệu của tập hợp toán học. Ưu điểm chính của việc sử dụng một tập hợp là nó bao gồm phương pháp được tối ưu hóa cao để kiểm tra phần tử cụ thể.

Python bao gồm một danh mục riêng biệt được gọi là tập hợp đông lạnh. Các tập hợp này là các đối tượng bất biến chỉ hỗ trợ các phương thức và toán tử tạo ra một kết quả cần thiết.

Làm thế nào để thực hiện các bộ?

Chương trình sau đây giúp thực hiện các tập hợp -

# Set in Python

# Creating two sets
set1 = set()
set2 = set()

# Adding elements to set1
for i in range(1, 6):
   set1.add(i)

# Adding elements to set2
for i in range(3, 8):
   set2.add(i)

print("Set1 = ", set1)
print("Set2 = ", set2)
print("\n")

# Union of set1 and set2
set3 = set1 | set2# set1.union(set2)
print("Union of Set1 & Set2: Set3 = ", set3)

# Intersection of set1 and set2
set4 = set1 & set2# set1.intersection(set2)
print("Intersection of Set1 & Set2: Set4 = ", set4)
print("\n")

# Checking relation between set3 and set4
if set3 > set4: # set3.issuperset(set4)
   print("Set3 is superset of Set4")
elif set3 < set4: # set3.issubset(set4)
   print("Set3 is subset of Set4")
else : # set3 == set4
   print("Set3 is same as Set4")

# displaying relation between set4 and set3
if set4 < set3: # set4.issubset(set3)
   print("Set4 is subset of Set3")
   print("\n")

# difference between set3 and set4
set5 = set3 - set4
print("Elements in Set3 and not in Set4: Set5 = ", set5)
print("\n")

# checkv if set4 and set5 are disjoint sets
if set4.isdisjoint(set5):
   print("Set4 and Set5 have nothing in common\n")

# Removing all the values of set5
set5.clear()

print("After applying clear on sets Set5: ")
print("Set5 = ", set5)

Đầu ra

Chương trình trên tạo ra kết quả sau:

Tập hợp đông lạnh có thể được chứng minh bằng chương trình sau:

normal_set = set(["a", "b","c"])

# Adding an element to normal set is fine
normal_set.add("d")

print("Normal Set")
print(normal_set)

# A frozen set
frozen_set = frozenset(["e", "f", "g"])

print("Frozen Set")
print(frozen_set)

Đầu ra

Chương trình trên tạo ra kết quả sau:

Hàng đợi là một tập hợp các đối tượng, xác định một cấu trúc dữ liệu đơn giản theo thủ tục FIFO (Fast In Fast Out) và LIFO (Last In First Out). Các thao tác chèn và xóa được gọi làenqueuedequeue các hoạt động.

Hàng đợi không cho phép truy cập ngẫu nhiên vào các đối tượng mà chúng chứa.

Làm thế nào để thực hiện thủ tục FIFO?

Chương trình sau đây giúp thực hiện FIFO -

import Queue

q = Queue.Queue()

#put items at the end of the queue
for x in range(4):
   q.put("item-" + str(x))

#remove items from the head of the queue
while not q.empty():
   print q.get()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Làm thế nào để thực hiện thủ tục LIFO?

Chương trình sau giúp thực hiện quy trình LIFO -

import Queue

q = Queue.LifoQueue()

#add items at the head of the queue
for x in range(4):
   q.put("item-" + str(x))

#remove items from the head of the queue
while not q.empty():
   print q.get()

Đầu ra

Chương trình trên tạo ra kết quả sau:

Hàng đợi ưu tiên là gì?

Hàng đợi ưu tiên là cấu trúc dữ liệu vùng chứa quản lý một tập hợp các bản ghi với các khóa được sắp xếp để cung cấp quyền truy cập nhanh vào bản ghi có khóa nhỏ nhất hoặc lớn nhất trong cấu trúc dữ liệu được chỉ định.

Làm thế nào để triển khai một hàng đợi ưu tiên?

Việc thực hiện hàng đợi ưu tiên như sau:

import Queue

class Task(object):
   def __init__(self, priority, name):
      self.priority = priority
      self.name = name
   
   def __cmp__(self, other):
      return cmp(self.priority, other.priority)

q = Queue.PriorityQueue()

q.put( Task(100, 'a not agent task') )
q.put( Task(5, 'a highly agent task') )
q.put( Task(10, 'an important task') )

while not q.empty():
   cur_task = q.get()
	print 'process task:', cur_task.name

Đầu ra

Chương trình trên tạo ra kết quả sau:

Tuần tự hóa chuỗi là quá trình ghi một trạng thái của đối tượng vào một luồng byte. Trong python, thư viện "pickle" được sử dụng để kích hoạt tuần tự hóa. Mô-đun này bao gồm một thuật toán mạnh mẽ để tuần tự hóa và hủy tuần tự hóa cấu trúc đối tượng Python. “Pickling” là quá trình chuyển đổi phân cấp đối tượng Python thành luồng byte và “giải nén” là quy trình ngược lại.

Trình diễn của mô-đun dưa chua như sau:

import pickle

#Here's an example dict
grades = { 'Alice': 89, 'Bob': 72, 'Charles': 87 }

#Use dumps to convert the object to a serialized string
serial_grades = pickle.dumps( grades )
print(serial_grades)

#Use loads to de-serialize an object
received_grades = pickle.loads( serial_grades )
print(received_grades)

Đầu ra

Chương trình trên tạo ra kết quả sau:

Đồng thời thường bị hiểu nhầm là song song. Đồng thời ngụ ý lập lịch trình mã độc lập được thực thi một cách có hệ thống. Chương này tập trung vào việc thực thi đồng thời cho một hệ điều hành sử dụng Python.

Chương trình sau đây giúp thực thi đồng thời cho một hệ điều hành:

import os
import time
import threading
import multiprocessing

NUM_WORKERS = 4

def only_sleep():
   print("PID: %s, Process Name: %s, Thread Name: %s" % (
      os.getpid(),
      multiprocessing.current_process().name,
      threading.current_thread().name)
   )
   time.sleep(1)

def crunch_numbers():
   print("PID: %s, Process Name: %s, Thread Name: %s" % (
      os.getpid(),
      multiprocessing.current_process().name,
      threading.current_thread().name)
   )
   x = 0
   while x < 10000000:
      x += 1
for _ in range(NUM_WORKERS):
   only_sleep()
end_time = time.time()
print("Serial time=", end_time - start_time)

# Run tasks using threads
start_time = time.time()
threads = [threading.Thread(target=only_sleep) for _ in range(NUM_WORKERS)]
[thread.start() for thread in threads]
[thread.join() for thread in threads]
end_time = time.time()

print("Threads time=", end_time - start_time)

# Run tasks using processes
start_time = time.time()
processes = [multiprocessing.Process(target=only_sleep()) for _ in range(NUM_WORKERS)]
[process.start() for process in processes]
[process.join() for process in processes]
end_time = time.time()

print("Parallel time=", end_time - start_time)

Đầu ra

Chương trình trên tạo ra kết quả sau:

Giải trình

"Multiprocessing" là một gói tương tự như mô-đun phân luồng. Gói này hỗ trợ đồng thời cục bộ và từ xa. Do mô-đun này, các lập trình viên có được lợi thế để sử dụng nhiều quy trình trên hệ thống nhất định.

Chống lại các mẫu tuân theo một chiến lược đối lập với các mẫu thiết kế được xác định trước. Chiến lược bao gồm các cách tiếp cận chung cho các vấn đề chung, có thể được chính thức hóa và có thể được coi là một phương pháp phát triển tốt. Thông thường, các mô hình chống là đối lập và không mong muốn. Các mẫu chống là một số mẫu nhất định được sử dụng trong phát triển phần mềm, được coi là các phương pháp lập trình tồi.

Các tính năng quan trọng của chống mẫu

Bây giờ chúng ta hãy xem một vài đặc điểm quan trọng của các mẫu chống.

Tính đúng đắn

Những mẫu này thực sự phá vỡ mã của bạn và khiến bạn làm những điều sai trái. Sau đây là một minh họa đơn giản về điều này -

class Rectangle(object):
def __init__(self, width, height):
self._width = width
self._height = height
r = Rectangle(5, 6)
# direct access of protected member
print("Width: {:d}".format(r._width))

Khả năng bảo trì

Một chương trình được cho là có thể bảo trì được nếu nó dễ hiểu và dễ sửa đổi theo yêu cầu. Mô-đun nhập khẩu có thể được coi là một ví dụ về khả năng bảo trì.

import math
x = math.ceil(y)
# or
import multiprocessing as mp
pool = mp.pool(8)

Ví dụ về chống mẫu

Ví dụ sau giúp chứng minh các mô hình chống lại -

#Bad
def filter_for_foo(l):
   r = [e for e in l if e.find("foo") != -1]
   if not check_some_critical_condition(r):
      return None
   return r

res = filter_for_foo(["bar","foo","faz"])

if res is not None:
   #continue processing
   pass

#Good
def filter_for_foo(l):
   r = [e for e in l if e.find("foo") != -1]
   if not check_some_critical_condition(r):
      raise SomeException("critical condition unmet!")
   return r

try:
   res = filter_for_foo(["bar","foo","faz"])
   #continue processing

except SomeException:
   i = 0
while i < 10:
   do_something()
   #we forget to increment i

Giải trình

Ví dụ bao gồm việc trình bày các tiêu chuẩn tốt và xấu để tạo một hàm trong Python.

Xử lý các ngoại lệ cũng là một tiêu chí chính của các mẫu thiết kế. Một ngoại lệ là một lỗi xảy ra trong quá trình thực thi một chương trình. Khi một lỗi cụ thể xảy ra, điều quan trọng là phải tạo một ngoại lệ. Điều này giúp hạn chế sự cố chương trình.

Tại sao sử dụng ngoại lệ?

Ngoại lệ là những cách thuận tiện để xử lý lỗi và các điều kiện đặc biệt trong một chương trình. Khi người dùng nghĩ rằng mã được chỉ định có thể tạo ra lỗi thì điều quan trọng là sử dụng xử lý ngoại lệ.

Ví dụ - Chia cho 0

import sys

randomList = ['a', 0, 2]

for entry in randomList:
   try:
      print("The entry is", entry)
      r = 1/int(entry)
      break
   except:
      print("Oops!",sys.exc_info()[0],"occured.")
      print("Next entry.")
      print()
print("The reciprocal of",entry,"is",r)

Đầu ra

Chương trình trên tạo ra kết quả sau:

Nâng cao ngoại lệ

Đặc biệt trong lập trình Python, các ngoại lệ được đưa ra khi lỗi mã tương ứng xảy ra tại thời điểm chạy. Điều này có thể được nâng lên một cách mạnh mẽ bằng cách sử dụng“raise” từ khóa.

Cú pháp

raise KeyboardInterrupt
Traceback (most recent call last):
...
KeyboardInterrupt