Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf

Mô hình thiết kế trong Python

Kho lưu trữ này tập trung vào 23 mẫu thiết kế GOF (Gang of Four) nổi tiếng được triển khai trong Python.

Nó là bổ sung cho cuốn sách của tôi có tiêu đề Các mẫu thiết kế trong Python (Asin: B08XLJ8Z2J)Design Patterns In Python (ASIN : B08XLJ8Z2J)

Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf

& nbsp; & nbsp; https://www.amazon.com/dp/b08xlj8z2j & nbsp; & nbsp; https://www.amazon.co.uk/dp/b08xlj8z2j & nbsp; & nbsp; https://www.amazon.in/dp/b08z282sbc & nbsp; & nbsp; https://www.amazon.de/dp/b08xlj8z2j & nbsp; & nbsp; https://www.amazon.fr/dp/b08xlj8z2j & nbsp; & nbsp; https://www.amazon.es/dp/b08xlj8z2j & nbsp; & nbsp; https://www.amazon.it/dp/b08xlj8z2j & nbsp; & nbsp; https://www.amazon.co.jp/dp/b08xlj8z2j & nbsp; & nbsp; https://www.amazon.ca/dp/b08xlj8z2j & nbsp; & nbsp; https://www.amazon.com.au/dp/b08xlj8z2j

Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.com/dp/B08XLJ8Z2J
 
Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.co.uk/dp/B08XLJ8Z2J
 
Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.in/dp/B08Z282SBC
 
Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.de/dp/B08XLJ8Z2J
 
Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.fr/dp/B08XLJ8Z2J
 
Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.es/dp/B08XLJ8Z2J
 
Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.it/dp/B08XLJ8Z2J
 
Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.co.jp/dp/B08XLJ8Z2J
 
Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.ca/dp/B08XLJ8Z2J
 
Hướng dẫn design patterns in python: common gof (gang of four) design patterns implemented in python pdf - các mẫu thiết kế trong python: các mẫu thiết kế gof (nhóm bốn) chung được triển khai trong python pdf
  https://www.amazon.com.au/dp/B08XLJ8Z2J

Truy cập khóa học

Có 4 cách có thể truy cập nội dung video trong khóa học này,

  1. Udemy: https://www.udemy.com/cference/design-patterns-in-python/?referralcode=7493DBBBF97FF2B0D24D
    • Nhận phiếu giảm giá giảm giá Udemy tại https://sbcode.net/couponsUdemy Discount Coupons at https://sbcode.net/coupons
    • Giấy chứng nhận hoàn thành
    • Đảm bảo hoàn lại tiền 30 ngày
  2. Tư cách thành viên YouTube: https://www.youtube.com/channel/ucmuili2awt2msugplzwfdog/join
    • Hủy thành viên bất cứ lúc nào
  3. SkillShare: https://skl.sh/34sm2xg
    • Giấy chứng nhận hoàn thành
    • Đảm bảo hoàn lại tiền 30 ngày
  4. Tư cách thành viên YouTube: https://www.youtube.com/channel/ucmuili2awt2msugplzwfdog/join
    • Hủy thành viên bất cứ lúc nào includes FREE Video Access Codes to view videos from the official documentation website at https://sbcode.net/python/

SkillShare: https://skl.sh/34sm2xg


Hủy đăng ký bất cứ lúc nào

Sách: https://www.amazon.com/dp/b08xlj8z2j: asin b08xlj8z2j(Paperback/Kindle) includes Video Access Codes to view videos for FREE from the official documentation website at https://sbcode.net/python/


Hủy đăng ký bất cứ lúc nào

Nhận phiếu giảm giá giảm giá Udemy tại https://sbcode.net/couponsUdemy Discount Coupons at https://sbcode.net/coupons


Giấy chứng nhận hoàn thành

Đảm bảo hoàn lại tiền 30 ngày

Tư cách thành viên YouTube: https://www.youtube.com/channel/ucmuili2awt2msugplzwfdog/join

Hủy thành viên bất cứ lúc nào

SkillShare: https://skl.sh/34sm2xg

Hủy đăng ký bất cứ lúc nào

Sách: https://www.amazon.com/dp/b08xlj8z2j: asin b08xlj8z2j

  • Sách bao gồm mã truy cập video miễn phí để xem video từ trang web tài liệu chính thức tại https://sbcode.net/python/
    • Tất cả các ví dụ mã trong cuốn sách có thể được tìm thấy trong các trang này.
    • TIỀN BOA
    • Các mẫu thiết kế trong Python (Bìa mềm/Kindle) bao gồm mã truy cập video để xem video miễn phí từ trang web tài liệu chính thức tại https://sbcode.net/python/
    • Ghi chú
    • Nếu bạn chỉ muốn đọc các bài viết về mẫu thiết kế của tôi và bạn không cần truy cập các video, thì bạn có thể đọc chúng qua tư cách thành viên trung bình
  • Tổng quan
    • Một mẫu thiết kế là một mô tả hoặc mẫu có thể được áp dụng nhiều lần cho một vấn đề thường được định kỳ trong thiết kế phần mềm.
    • Một sự quen thuộc của các mẫu thiết kế sẽ rất hữu ích khi lập kế hoạch, thảo luận, quản lý và ghi lại các ứng dụng của bạn từ bây giờ và vào tương lai.
    • Ngoài ra, trong suốt cuốn sách, vì mỗi mẫu thiết kế được thảo luận và thể hiện bằng mã ví dụ, tôi cũng giới thiệu các khái niệm mã hóa Python mới với mỗi mẫu thiết kế mới. Vì vậy, khi bạn tiến bộ qua cuốn sách và thử các ví dụ, bạn cũng sẽ có được kinh nghiệm và sự quen thuộc với một số chi tiết tốt hơn về lập trình với Python.
    • Vì vậy, trong cuốn sách này, bạn sẽ tìm hiểu về 23 mẫu thiết kế này,
    • Sáng tạo
    • Nhà máy
    • Nhà máy trừu tượng
  • Người xây dựng
    • Nguyên mẫu
    • Singleton
    • Cấu trúc
    • Người trang trí
    • Bộ chuyển đổi
    • Mặt tiền
    • Cầu
    • Tổng hợp
    • Trọng lượng bay
    • Ủy quyền
    • Hành vi

Yêu cầu

Chuỗi trách nhiệm

Mô hình quan sát

Chuỗi trách nhiệm

Mô hình quan sát
Design Patterns In Python
1. Design Patterns In Python
2. Development Environment Setup
3. Coding Conventions
4. UML Diagrams
5. Creational
6. Structural
7. Behavioral
8. Summary

Các mô hình thiết kế trong các mẫu thiết kế GOF (Gang of Four) phổ biến Python

Sean Bradley Bản quyền © 2019-2021 Sean Bradley

Mục lục

Mục lục 1. Các mẫu thiết kế trong Python

4

1.1 Các loại mẫu

5

1.2 Phạm vi lớp và các mẫu phạm vi đối tượng

5

2. Thiết lập môi trường phát triển

7

2.1 Mã ví dụ

8

2.2 Video khóa học

9

2.3 VSCODE

9

3. quy ước mã hóa

11

3.1 Bảng điều khiển tương tác Python so với các tập lệnh *.Py

11

3.2 PEP8

12

3.3 pylint

12

3.4 Thông báo cảnh báo và lỗi pylint thông thường

12

3.5 Giao diện dòng lệnh

13

4. Sơ đồ UML

15

4.1 Một lớp cơ bản

15

4.2 Hiệp hội trực tiếp

15

4.3 Một lớp mở rộng/kế thừa một lớp

16

4.4 Một lớp thực hiện giao diện

16

4.5 Tổng hợp

17

4.6 Thành phần

18

4.7 Chú thích giả

18

5. Sáng tạo

19

5.1 Mô hình thiết kế nhà máy

19

5.2 Mô hình thiết kế nhà máy trừu tượng

28

5.3 Mô hình thiết kế xây dựng

43

5.4 Mẫu thiết kế nguyên mẫu

53

5.5 Mô hình thiết kế Singleton

61

6. Cấu trúc

69

6.1 Mô hình thiết kế trang trí

69

Bản quyền © 2019-2021 Sean Bradley

- 2/238 -

Mục lục

Mục lục 1. Các mẫu thiết kế trong Python

78

1.1 Các loại mẫu

88

1.2 Phạm vi lớp và các mẫu phạm vi đối tượng

100

2. Thiết lập môi trường phát triển

109

2.1 Mã ví dụ

118

2.2 Video khóa học

127

2.3 VSCODE

135

3. quy ước mã hóa

135

3.1 Bảng điều khiển tương tác Python so với các tập lệnh *.Py

144

3.2 PEP8

153

3.3 pylint

165

3.4 Thông báo cảnh báo và lỗi pylint thông thường

180

3.5 Giao diện dòng lệnh

186

4. Sơ đồ UML

197

4.1 Một lớp cơ bản

207

4.2 Hiệp hội trực tiếp

213

4.3 Một lớp mở rộng/kế thừa một lớp

219

4.4 Một lớp thực hiện giao diện

227

8. Tóm tắt

237

Bản quyền © 2019-2021 Sean Bradley

- 2/238 -

6.2 Mô hình thiết kế bộ điều hợp

6.3 Mô hình thiết kế mặt tiền

Bản quyền © 2019-2021 Sean Bradley

- 4/238 -

1.1 Các loại mẫu

• Hành vi • Lệnh • Chuỗi trách nhiệm • Mô hình người quan sát • Thông dịch viên • Người lặp lại • Hòa giải • Memento • Trạng thái • Chiến lược • Mẫu • Khách truy cập

1.1 Các loại mẫu trong danh sách các mẫu ở trên, có các mô hình sáng tạo, cấu trúc và hành vi. • Sáng tạo: Tóm tắt quá trình khởi tạo để có sự tách biệt logic giữa các đối tượng được sáng tác và cuối cùng được biểu diễn. • Cấu trúc: Tập trung nhiều hơn vào cách các lớp và đối tượng được sáng tác bằng cách sử dụng các kỹ thuật cấu trúc khác nhau và để hình thành các cấu trúc có tính linh hoạt hơn hoặc thay đổi. • Hành vi: quan tâm đến các thuật toán bên trong, dòng xử lý, việc gán trách nhiệm và giao tiếp giữa các đối tượng.

1.2 Phạm vi lớp và các mẫu phạm vi đối tượng Mỗi mẫu có thể được chỉ định thêm cho dù nó liên quan cụ thể hơn đến các lớp hoặc đối tượng khởi tạo. Các mẫu phạm vi lớp học liên quan nhiều hơn đến các mối quan hệ giữa các lớp và các lớp con của chúng. Các mẫu phạm vi đối tượng liên quan nhiều hơn đến các mối quan hệ có thể được thay đổi ở mẫu thời gian chạy

Sự mô tả

Phạm vi

Loại hình

Nhà máy, nhà máy trừu tượng

Bảo vệ đối tượng

Lớp

Sáng tạo

Sáng tạo cho các lớp con

Bản quyền © 2019-2021 Sean Bradley

- 5/238 -

1.2 Phạm vi lớp và các mẫu phạm vi đối tượng

Họa tiết

Sự mô tả

Phạm vi

Loại hình

Nhà máy, nhà máy trừu tượng

Bảo vệ đối tượng

Lớp

Sáng tạo

Lớp

Sáng tạo

Lớp

Sáng tạo

Lớp

Sáng tạo

Sáng tạo cho các lớp con

- 5/238 -

1.2 Phạm vi lớp và các mẫu phạm vi đối tượng

Họa tiết

Người xây dựng, nguyên mẫu, singleton

Sự vật

Cấu trúc

Hành vi

Sáng tạo cho các đối tượng bộ điều hợp, cầu, composite,

Mô tả một cách

Người trang trí, mặt tiền, trọng lượng,

để lắp ráp

Ủy quyền

các đối tượng

Thông dịch viên, mẫu

Bản quyền © 2019-2021 Sean Bradley

Mô tả các thuật toán và điều khiển dòng chảy

Chuỗi trách nhiệm,

Mô tả làm thế nào

Chỉ huy, người lặp, hòa giải viên,

các nhóm đối tượng

Bản quyền © 2019-2021 Sean Bradley

Memento, người quan sát, trạng thái,

hợp tác

Chiến lược, du khách

- 6/238 -

Bản quyền © 2019-2021 Sean Bradley

- 8/238 -

2.2 Video khóa học

2.2 Video khóa học Là một phần của việc mua cuốn sách này, tôi cũng đã cung cấp cho bạn khả năng xem miễn phí, tất cả các video là một phần trong các mẫu thiết kế chính thức của tôi trong các khóa học Python trên Udemy, YouTube và Skillshare. Để xem các video, trong mỗi phần của cuốn sách này, bạn sẽ tìm thấy một số ID video SBCode. Truy cập https://sbcode.net/python/ và ở đầu mỗi trang hướng dẫn trên trang web, có các tùy chọn để nhập mã và xem video liên quan. Nhấn nút SBCode trong phần liên kết video trên trang web và sau đó nhập mã mà bạn tìm thấy trong mỗi phần liên quan của cuốn sách này.

2.3 VSCODE Nếu bạn đang làm việc trên Windows, thì tôi khuyên bạn nên cài đặt VSCode để sử dụng làm IDE của bạn khi học Python. Đây là tùy chọn và bạn có thể thích sử dụng Notepad hoặc bất kỳ IDE phổ biến nào khác mà bạn có thể tải xuống hoặc sử dụng trực tuyến cũng sẽ hỗ trợ bạn khi viết Python. Bạn có thể tải xuống VSCODE từ https://code.visualstudio.com/doad, sau đó bạn có thể mở VSCODE từ thư mục làm việc hiện tại của bạn bằng cách nhập mã. Tái bút E: \ Python_Design_Potype> Mã. Và VSCode sẽ mở sẵn cho bạn trong thư mục làm việc của bạn, nơi bạn có thể sử dụng nó để thêm các tệp hoặc thư mục mới khi cần.

Bản quyền © 2019-2021 Sean Bradley

- 9/238 -

2.3 VSCODE

Bản quyền © 2019-2021 Sean Bradley

- 10/238 -

3. quy ước mã hóa

3. Quy ước mã hóa ID video SBCode #29949D

3.1 Bảng điều khiển tương tác Python so với các tập lệnh *.Py Bạn có thể thực thi mã Python bằng cách ghi các tập lệnh của bạn vào các tệp văn bản và thường sử dụng tiện ích mở rộng .py. Các tệp văn bản trên hầu hết các hệ điều hành sẽ được mã hóa UTF-8 theo mặc định. Python cũng đọc các tệp văn bản được mã hóa UTF-8 theo mặc định. Tạo một tệp văn bản mới được gọi là example.py và thêm văn bản sau. In ("Hello World!") Và sau đó bạn có thể thực hiện nó bằng Python hoặc Python3 tùy thuộc vào hệ điều hành và phiên bản Python của bạn. PS> Python ./example.py Hello World! Bạn cũng có thể nhập mã Python trực tiếp vào bảng điều khiển tương tác Python bằng cách nhập chỉ Python hoặc Python3 từ dòng lệnh và sau đó nhấn Enter. Sau đó, bạn nhận được một lời nhắc như dưới đây. PS> Python Python 3.9.2 (Tags/V3.9.2: 1A79785, ngày 19 tháng 2 năm 2021, 13:44:55) [MSC ... Loại "Trợ giúp", "Bản quyền", "Tín dụng" hoặc "Giấy phép" để biết thêm thông tin . >>> Bây giờ bạn có thể nhập các lệnh Python trực tiếp. >>> in ("Xin chào thế giới!") Xin chào thế giới! >>> Để thoát khỏi bảng điều khiển tương tác Python, bạn thường có thể gõ thoát () hoặc nhấn Ctrl-Z sau đó nhấn ENTER này sẽ hiển thị các ví dụ về việc sử dụng cả hai tập lệnh *.py và bảng điều khiển tương tác để thực thi Python. Xem ra các ký tự >>> trong các khối mã để cho biết nếu tôi đang sử dụng bảng điều khiển tương tác Python hoặc tập lệnh *.py.

Bản quyền © 2019-2021 Sean Bradley

- 11/238 -

3.2 PEP8

3.2 PEP8 Kiểu dáng mã trong cuốn sách này được định dạng bằng cách sử dụng các đề xuất kiểu dáng PEP8. • Upper_case: Hằng số sẽ được xác định bằng cách sử dụng kiểu đặt tên Upper_case. • Pascalcase: Tên lớp sẽ sử dụng kiểu đặt tên PascalCase • Snake_case: Đối với tên biến, tên phương thức và đối số phương thức. • DocStrings: Các lớp và phương thức chứa tài liệu bổ sung là văn bản mô tả được đặt trong "hoặc" "" cho các chuỗi đa dòng. • _leading_underscore: Sử dụng dấu gạch dưới hàng đầu để chỉ ra các biến nên được coi là biến lớp riêng. Xem PEP-0008: https://www.python.org/dev/peps/pep-0008/

3.3 pylint Tôi sử dụng công cụ pylint để kiểm tra các khuyến nghị kiểu dáng mã. Trên hầu hết các hệ điều hành, bạn thường sẽ cài đặt pylint bằng cách sử dụng trình cài đặt PIP hoặc PIP3. pip cài đặt pylint Nếu sử dụng vScode, hãy mở bảng lệnh (ctrl+shift+p), sau đó đặt

Python: Bật lớp lót bật và

Python: Chọn Linter vào Pylint

3.4 CẢNH BÁO PYLINT thông thường và thông báo lỗi ID

Thông điệp

Sự mô tả

R0201

Phương pháp có thể là một

Phương pháp của bạn có một thuộc tính đề cập đến bản thân hoặc

chức năng (không có bản thân-

CLS, nhưng nó không cần thiết vì bạn không sử dụng

sử dụng)

bản thân hoặc CLS trong cơ thể phương pháp. Bạn có

Thay vào đó, tùy chọn sử dụng bộ trang trí @staticmethod trên các phương thức của bạn và để loại bỏ bản thân hoặc CL khỏi các thuộc tính phương thức.

Bản quyền © 2019-2021 Sean Bradley

- 12/238 -

3.5 Giao diện dòng lệnh

TÔI

Thông điệp

Sự mô tả

R0201

Phương pháp có thể là một

Phương pháp của bạn có một thuộc tính đề cập đến bản thân hoặc

chức năng (không có bản thân-

CLS, nhưng nó không cần thiết vì bạn không sử dụng

sử dụng)

bản thân hoặc CLS trong cơ thể phương pháp. Bạn có

Thay vào đó, tùy chọn sử dụng bộ trang trí @staticmethod trên các phương thức của bạn và để loại bỏ bản thân hoặc CL khỏi các thuộc tính phương thức.

- 12/238 -

E0110

W0221

Lớp học trừu tượng

Lớp thực hiện giao diện trừu tượng hoặc là

'ClassName' với

kế thừa từ một lớp trừu tượng khác, không phải

Phương pháp trừu tượng

thực hiện tất cả các phương pháp trừu tượng như mô tả

khởi tạo

trong chữ ký giao diện; hoặc nếu kéo dài, thì tất cả

(Lớp Tóm tắt-

chữ ký của lớp trừu tượng đang được

khởi tạo)

mở rộng.

Tham số khác nhau

Các đối số trong lớp trừu tượng của bạn không khớp với

từ ghi đè

Đối số trong lớp thực hiện của bạn. Kiểm tra chính tả

Phương thức 'Phương pháp'

của những lý lẽ.

(đối số-người khác) C0304

Đường mới cuối cùng

Pylint thích một tập tin để kết thúc bằng một dòng mới. Khi nào

mất tích (mất tích-

Sao chép mã từ trang web vào tệp .py,

Newline cuối cùng)

Mã sao chép có thể không kết thúc với một ký tự dòng mới. Bạn có thể thêm một theo cách thủ công bằng cách nhấn phím Enter trên bàn phím của mình ở cuối mã hoặc nếu bạn sử dụng VSCode, nhấn kết hợp khóa của Shift-Al-F sẽ tự động định dạng tệp *.py của bạn với dòng mới khi bạn Có linter pylint, hoặc linter khác, được bật.

W0612

Biến không sử dụng

Bạn có thể xóa biến không sử dụng khỏi mã của bạn. Nếu bạn không thể xóa biến không sử dụng thì hãy sử dụng _ làm tên biến. Xem phần The-underscoreonly-_Varable trong mẫu hòa giải để biết thêm thông tin.

3.5 Giao diện dòng lệnh Giao diện dòng lệnh (CLI) trên các hệ điều hành khác nhau (Windows, Linux, MacOSX, RaspberryPi) khác nhau về ngoại hình khá nhiều. Bạn có thể sử dụng CMD, PowerShell hoặc Git Bash trên Windows, Bash trên Linux hoặc Terminal trên MacOSX.

Bản quyền © 2019-2021 Sean Bradley

- 13/238 -

3.5 Giao diện dòng lệnh

-Windows PowerShell -ps> Python example.py ps e: \ python_design_patterns> python example.py -windows cmd -c: \> python example.py -git bash [email & nbsp; Ví dụ.py-Linux [Email & nbsp; được bảo vệ]: ~# python3 example.py [email & nbsp; .py # python3 example.py-macosx-hostname: ~ tên người dùng $ python3 example.py wikipedia-giao diện dòng lệnh: https://en.wikipedia.org/wiki/command-line_interface

Bản quyền © 2019-2021 Sean Bradley

- 13/238 -

3.5 Giao diện dòng lệnh

-Windows PowerShell -ps> Python example.py ps e: \ python_design_patterns> python example.py -windows cmd -c: \> python example.py -git bash [email & nbsp; Ví dụ.py-Linux [Email & nbsp; được bảo vệ]: ~# python3 example.py [email & nbsp; .py # python3 example.py-macosx-hostname: ~ tên người dùng $ python3 example.py wikipedia-giao diện dòng lệnh: https://en.wikipedia.org/wiki/command-line_interface

- 14/238 -

4. Sơ đồ UML

4. Sơ đồ UML ID video SBCode #735229

Các sơ đồ ngôn ngữ mô hình hóa thống nhất (UML) được sử dụng trong suốt cuốn sách này để giúp mô tả các mẫu. Dưới đây là một số ví dụ tự mô tả sơ đồ UML. Phần bên trái của sơ đồ cho thấy khái niệm cơ bản và phía bên phải cho thấy một ví dụ tiềm năng sử dụng.

4.1 Một lớp cơ bản

tư nhân công cộng

Khái niệm

Thí dụ

Tên lớp

Xe hơi

+ field1: type - _field2: loại

Bản quyền © 2019-2021 Sean Bradley

- 13/238 -

3.5 Giao diện dòng lệnh

Các sơ đồ ngôn ngữ mô hình hóa thống nhất (UML) được sử dụng trong suốt cuốn sách này để giúp mô tả các mẫu. Dưới đây là một số ví dụ tự mô tả sơ đồ UML. Phần bên trái của sơ đồ cho thấy khái niệm cơ bản và phía bên phải cho thấy một ví dụ tiềm năng sử dụng.

4.1 Một lớp cơ bản

tư nhân công cộng

Khái niệm

Thí dụ

Thí dụ

Tên lớp

Xe hơi

+ field1: type - _field2: loại

- _wheel_Count: int + chạy: false + start_engine (void): bool + set_speed (int): void

Thí dụ

Tên lớp

Tên lớp

Xe hơi

4.1 Một lớp cơ bản

tư nhân công cộng

Khái niệm

Thí dụ

Tên lớp

Tên lớp

Xe hơi

+ field1: type - _field2: loại

- _wheel_Count: int + chạy: false + start_engine (void): bool + set_speed (int): void

- meather_a (type): loại + phương thức_b (loại)

4.2 Liên kết định hướng một mũi tên đầy với một dòng. Classa sử dụng ClassB hoặc một đối tượng của ClassB. Classa gọi một phương thức lớp tĩnh, phương thức trừu tượng tĩnh hoặc phương thức/thuộc tính/trường/trường từ một đối tượng loại lớp. Ví dụ, người khởi động động cơ xe hơi.

- 15/238 -

4.3 Một lớp mở rộng/kế thừa một lớp

Bản quyền © 2019-2021 Sean Bradley

- 13/238 -

3.5 Giao diện dòng lệnh

-Windows PowerShell -ps> Python example.py ps e: \ python_design_patterns> python example.py -windows cmd -c: \> python example.py -git bash [email & nbsp; Ví dụ.py-Linux [Email & nbsp; được bảo vệ]: ~# python3 example.py [email & nbsp; .py # python3 example.py-macosx-hostname: ~ tên người dùng $ python3 example.py wikipedia-giao diện dòng lệnh: https://en.wikipedia.org/wiki/command-line_interface

4.1 Một lớp cơ bản

tư nhân công cộng

Khái niệm

Tên lớp

Xe hơi

+ field1: type - _field2: loại

Tên lớp

Thí dụ

Xe hơi

Tên lớp

Xe hơi

Thí dụ

LỚP

Sách

+ trường: gõ

+ trường: gõ

+ phương pháp (loại): loại

+ phương pháp (loại): loại

Classa

Thư viện

+ trường: gõ

+ trường: gõ

+ phương pháp (loại): loại

+ phương pháp (loại): loại

Classa

Thư viện

Bản quyền © 2019-2021 Sean Bradley

- 17/238 -

Thí dụ

LỚP

Sách

+ trường: gõ

+ trường: gõ

+ phương pháp (loại): loại

+ phương pháp (loại): loại

Classa

Thư viện

+ trường: gõ

+ trường: gõ

+ phương pháp (loại): loại

+ phương pháp (loại): loại

Classa

Thí dụ

LỚP

Thư viện

+ phương pháp (loại): loại

Classa

Thư viện

Classa

Thư viện

Bản quyền © 2019-2021 Sean Bradley

- 17/238 -

4.6 Thành phần

4.6 Thành phần Một viên kim cương đầy với một đường và đầu mũi tên. Classa bao gồm máy bay ClassB có thể bao gồm cánh và các bộ phận khác. Nhưng một chiếc máy bay không còn thực sự là một chiếc máy bay không có cánh của nó. Khái niệm

Cánh

Classa

Thư viện

Bản quyền © 2019-2021 Sean Bradley

- 17/238 -

4.6 Thành phần

4.6 Thành phần Một viên kim cương đầy với một đường và đầu mũi tên. Classa bao gồm máy bay ClassB có thể bao gồm cánh và các bộ phận khác. Nhưng một chiếc máy bay không còn thực sự là một chiếc máy bay không có cánh của nó. Khái niệm

Cánh

Máy bay

LỚP

+ trường: gõ

+ trường: gõ

+ trường: gõ

4.7 Chú thích mã giả Một hộp có đường đứt nét và một vòng tròn được đặt gần phương thức lớp. Mã giả là một mô tả ngôn ngữ đơn giản về các bước trong thuật toán và được sử dụng để mô tả một khái niệm mà không cần phải viết các dòng mã dài. Khái niệm

4.7 Chú thích mã giả Một hộp có đường đứt nét và một vòng tròn được đặt gần phương thức lớp. Mã giả là một mô tả ngôn ngữ đơn giản về các bước trong thuật toán và được sử dụng để mô tả một khái niệm mà không cần phải viết các dòng mã dài. Khái niệm

4.7 Chú thích mã giả Một hộp có đường đứt nét và một vòng tròn được đặt gần phương thức lớp. Mã giả là một mô tả ngôn ngữ đơn giản về các bước trong thuật toán và được sử dụng để mô tả một khái niệm mà không cần phải viết các dòng mã dài. Khái niệm

Bê tông

+ Yêu cầu (Loại): Loại

... Pseudocode () ...

Classa

Thư viện

Bản quyền © 2019-2021 Sean Bradley

- 17/238 -

Bản quyền © 2019-2021 Sean Bradley

- 21/238 -

5.1.5 đầu ra

5.1.5 Đầu ra Python ./factory/factory_concept.py Concreteproductb

5.1.6 Trường hợp sử dụng nhà máy ID video SBCode #5D7340

Một trường hợp sử dụng ví dụ là giao diện người dùng trong đó người dùng có thể chọn từ menu của các mục, chẳng hạn như ghế. Người dùng đã được lựa chọn bằng cách sử dụng một số loại giao diện điều hướng và không biết lựa chọn nào hoặc người dùng sẽ thực hiện bao nhiêu cho đến khi ứng dụng thực sự chạy và người dùng bắt đầu sử dụng nó. Vì vậy, khi người dùng chọn ghế, nhà máy sau đó lấy một số thuộc tính liên quan đến lựa chọn đó, chẳng hạn như ID, loại hoặc thuộc tính khác và sau đó quyết định lớp con có liên quan nào để khởi tạo để trả về đối tượng thích hợp.

5.1.7 Ví dụ về nhà máy Sơ đồ UML Các lớp con Thực hiện một giao diện chung Smallchair - _Height: int - _width: int - _depth: int + get_dimensions ()

Ichair + get_dimensions (): Dict

- _Height: int - _width: int - _depth: int + get_dimensions (): Dict

BigChair - _Height: int - _width: int - _depth: int Ứng dụng máy khách + get_dimensions (): Dict

Bản quyền © 2019-2021 Sean Bradley

- 22/238 -

5.1.8 Mã nguồn

5.1.8 Mã nguồn.

. def get_dimensions (): "Phương thức giao diện tĩnh"

. ): "Một phương pháp tĩnh để có được một chiếc ghế" nếu ghế == 'bigchair': trả lại bigchair () nếu ghế == 'trung bình

Bản quyền © 2019-2021 Sean Bradley

- 23/238 -

5.1.8 Mã nguồn

trả lại smallchair () không trả lại

. ).

. ).

Bản quyền © 2019-2021 Sean Bradley

- 24/238 -

5.1.9 Đầu ra

. ).

5.1.9 Đầu ra Python ./factory/client.py {'Width': 40, 'Độ sâu': 40, 'Chiều cao': 40}

5.1.10 Khái niệm mã hóa mới ABCMETA SBCODE VIDEO ID #E6BC73

Các lớp ABCMeta là một công cụ phát triển giúp bạn viết các lớp phù hợp với giao diện được chỉ định mà bạn đã thiết kế. ABCMeta đề cập đến các lớp cơ sở trừu tượng. Lợi ích của việc sử dụng các lớp ABCMeta để tạo các lớp trừu tượng là IDE và pylint của bạn sẽ chỉ ra cho bạn vào thời điểm phát triển liệu các lớp kế thừa của bạn có phù hợp với định nghĩa lớp mà bạn đã yêu cầu. Các giao diện trừu tượng không được khởi tạo trực tiếp trong các tập lệnh của bạn, mà thay vào đó được triển khai bởi các lớp con sẽ cung cấp mã triển khai cho các phương thức giao diện trừu tượng. Ví dụ: bạn không tạo ichair, nhưng bạn tạo ra nhỏ thực hiện các phương thức được mô tả trong giao diện ichair.

Bản quyền © 2019-2021 Sean Bradley

- 25/238 -

5.1.11 Tóm tắt

Một phương thức giao diện trừu tượng là một phương thức được khai báo, nhưng không có việc thực hiện. Việc thực hiện xảy ra tại lớp kế thừa lớp trừu tượng. Bạn không cần sử dụng các lớp và giao diện ABCMeta mà bạn đã tạo trong mã Python cuối cùng của mình. Bạn mã vẫn sẽ làm việc mà không có chúng. Bạn có thể thử nó bằng cách xóa các giao diện khỏi tất cả các lớp ghế ở trên và bạn sẽ thấy rằng chương trình Python của bạn vẫn sẽ chạy. Ví dụ, thay đổi lớp bigchair (ichair): sang lớp bigchair (): và nó vẫn sẽ hoạt động. Mặc dù có thể đảm bảo các lớp học của bạn là chính xác mà không sử dụng các lớp trừu tượng, nhưng thường dễ sử dụng các lớp trừu tượng làm phương thức sao lưu để kiểm tra tính chính xác, đặc biệt là nếu các dự án của bạn trở nên rất lớn và liên quan đến nhiều nhà phát triển. Lưu ý rằng trong tất cả các ví dụ mã của tôi, các lớp trừu tượng được đặt trước với vốn I, để chỉ ra rằng chúng là các giao diện trừu tượng. Họ không có mã trong phương pháp của họ. Họ không yêu cầu bản thân hoặc

Đối số CLS do sử dụng @staticmethod. Lớp kế thừa sẽ thực hiện mã trong mỗi phương thức mà lớp trừu tượng đang mô tả. Nếu các lớp con được kế thừa một lớp cơ sở trừu tượng và chúng không thực hiện các phương thức như mô tả, sẽ có lỗi pylint hoặc thông báo cảnh báo (E0110). Xem PEP 3119: https://www.python.org/dev/peps/pep-3119/

5.1.11 Tóm tắt • Mẫu nhà máy là một giao diện bảo vệ việc tạo đối tượng cuối cùng cho một lớp con. • Mô hình nhà máy là về việc chèn một lớp/trừu tượng khác giữa việc khởi tạo một đối tượng và nơi trong mã của bạn nó thực sự được sử dụng. • Không biết gì hoặc có bao nhiêu đối tượng sẽ được tạo cho đến khi chạy. • Bạn muốn bản địa hóa kiến ​​thức về các chi tiết cụ thể về việc khởi tạo một đối tượng cụ thể cho lớp con để khách hàng không cần quan tâm đến các chi tiết. • Bạn muốn tạo một khung bên ngoài, một ứng dụng có thể nhập/tham chiếu và ẩn các chi tiết của các chi tiết cụ thể liên quan đến việc tạo đối tượng/sản phẩm cuối cùng.

Bản quyền © 2019-2021 Sean Bradley

- 26/238 -

5.1.11 Tóm tắt

• Yếu tố duy nhất xác định mô hình nhà máy, là dự án của bạn bây giờ bảo vệ việc tạo ra các đối tượng cho lớp con mà nhà máy đã ủy thác cho nó.

Bản quyền © 2019-2021 Sean Bradley

- 26/238 -

5.1.11 Tóm tắt

• Yếu tố duy nhất xác định mô hình nhà máy, là dự án của bạn bây giờ bảo vệ việc tạo ra các đối tượng cho lớp con mà nhà máy đã ủy thác cho nó.

- 27/238 -

5.2 Mô hình thiết kế nhà máy trừu tượng

Bản quyền © 2019-2021 Sean Bradley

- 26/238 -

5.1.11 Tóm tắt

• Yếu tố duy nhất xác định mô hình nhà máy, là dự án của bạn bây giờ bảo vệ việc tạo ra các đối tượng cho lớp con mà nhà máy đã ủy thác cho nó.

- 27/238 -

5.2 Mô hình thiết kế nhà máy trừu tượng

5.2 Tóm tắt Mô hình thiết kế nhà máy 5.2.1 Tổng quan về video SBCode #62BDE8

Mô hình nhà máy trừu tượng thêm một lớp trừu tượng trên nhiều triển khai mô hình sáng tạo khác. Để bắt đầu, theo thuật ngữ đơn giản, hãy nghĩ rằng nếu nó như một nhà máy có thể trả lại các nhà máy. Mặc dù bạn sẽ tìm thấy các ví dụ về nó cũng bắt đầu được sử dụng để trả về trình tạo, nguyên mẫu, singletons hoặc các triển khai mô hình thiết kế khác.

Mô hình nhà máy trừu tượng thêm một lớp trừu tượng trên nhiều triển khai mô hình sáng tạo khác. Để bắt đầu, theo thuật ngữ đơn giản, hãy nghĩ rằng nếu nó như một nhà máy có thể trả lại các nhà máy. Mặc dù bạn sẽ tìm thấy các ví dụ về nó cũng bắt đầu được sử dụng để trả về trình tạo, nguyên mẫu, singletons hoặc các triển khai mô hình thiết kế khác.

Mô hình nhà máy trừu tượng thêm một lớp trừu tượng trên nhiều triển khai mô hình sáng tạo khác. Để bắt đầu, theo thuật ngữ đơn giản, hãy nghĩ rằng nếu nó như một nhà máy có thể trả lại các nhà máy. Mặc dù bạn sẽ tìm thấy các ví dụ về nó cũng bắt đầu được sử dụng để trả về trình tạo, nguyên mẫu, singletons hoặc các triển khai mô hình thiết kế khác.

Mô hình nhà máy trừu tượng thêm một lớp trừu tượng trên nhiều triển khai mô hình sáng tạo khác. Để bắt đầu, theo thuật ngữ đơn giản, hãy nghĩ rằng nếu nó như một nhà máy có thể trả lại các nhà máy. Mặc dù bạn sẽ tìm thấy các ví dụ về nó cũng bắt đầu được sử dụng để trả về trình tạo, nguyên mẫu, singletons hoặc các triển khai mô hình thiết kế khác.

5.2.2 Thuật ngữ • Khách hàng: Ứng dụng máy khách gọi nhà máy trừu tượng. Đó là quá trình tương tự như người tạo bê tông trong mô hình thiết kế nhà máy. • Nhà máy trừu tượng: Một giao diện chung trên tất cả các nhà máy phụ. • Nhà máy bê tông: Nhà máy phụ của nhà máy trừu tượng và chứa (các) phương pháp để cho phép tạo ra sản phẩm cụ thể. • Sản phẩm trừu tượng: Giao diện cho sản phẩm mà nhà máy phụ trở lại. • Sản phẩm cụ thể: Đối tượng cuối cùng được trả lại.

5.2.2 Thuật ngữ • Khách hàng: Ứng dụng máy khách gọi nhà máy trừu tượng. Đó là quá trình tương tự như người tạo bê tông trong mô hình thiết kế nhà máy. • Nhà máy trừu tượng: Một giao diện chung trên tất cả các nhà máy phụ. • Nhà máy bê tông: Nhà máy phụ của nhà máy trừu tượng và chứa (các) phương pháp để cho phép tạo ra sản phẩm cụ thể. • Sản phẩm trừu tượng: Giao diện cho sản phẩm mà nhà máy phụ trở lại. • Sản phẩm cụ thể: Đối tượng cuối cùng được trả lại.

5.2.2 Thuật ngữ • Khách hàng: Ứng dụng máy khách gọi nhà máy trừu tượng. Đó là quá trình tương tự như người tạo bê tông trong mô hình thiết kế nhà máy. • Nhà máy trừu tượng: Một giao diện chung trên tất cả các nhà máy phụ. • Nhà máy bê tông: Nhà máy phụ của nhà máy trừu tượng và chứa (các) phương pháp để cho phép tạo ra sản phẩm cụ thể. • Sản phẩm trừu tượng: Giao diện cho sản phẩm mà nhà máy phụ trở lại. • Sản phẩm cụ thể: Đối tượng cuối cùng được trả lại.

5.2.2 Thuật ngữ • Khách hàng: Ứng dụng máy khách gọi nhà máy trừu tượng. Đó là quá trình tương tự như người tạo bê tông trong mô hình thiết kế nhà máy. • Nhà máy trừu tượng: Một giao diện chung trên tất cả các nhà máy phụ. • Nhà máy bê tông: Nhà máy phụ của nhà máy trừu tượng và chứa (các) phương pháp để cho phép tạo ra sản phẩm cụ thể. • Sản phẩm trừu tượng: Giao diện cho sản phẩm mà nhà máy phụ trở lại. • Sản phẩm cụ thể: Đối tượng cuối cùng được trả lại.

- 28/238 -

5.2.3 Sơ đồ UML Tóm tắt Nhà máy

5.2.3 Tóm tắt Nhà máy Sơ đồ UML Các lớp con Thực hiện một giao diện chung Classa + Trường: Loại + created_Object (loại): Loại IABStractFactory

5.2.2 Thuật ngữ • Khách hàng: Ứng dụng máy khách gọi nhà máy trừu tượng. Đó là quá trình tương tự như người tạo bê tông trong mô hình thiết kế nhà máy. • Nhà máy trừu tượng: Một giao diện chung trên tất cả các nhà máy phụ. • Nhà máy bê tông: Nhà máy phụ của nhà máy trừu tượng và chứa (các) phương pháp để cho phép tạo ra sản phẩm cụ thể. • Sản phẩm trừu tượng: Giao diện cho sản phẩm mà nhà máy phụ trở lại. • Sản phẩm cụ thể: Đối tượng cuối cùng được trả lại.

- 28/238 -

5.2.3 Sơ đồ UML Tóm tắt Nhà máy

5.2.3 Tóm tắt Nhà máy Sơ đồ UML Các lớp con Thực hiện một giao diện chung Classa + Trường: Loại + created_Object (loại): Loại IABStractFactory

Nhà máy

Iclass

Bản quyền © 2019-2021 Sean Bradley

LỚP

+ trường: gõ

+ created_object (type): loại

Classc + trường: type + created_object (type): loại

Bản quyền © 2019-2021 Sean Bradley

- 30/238 -

5.2.4 Mã nguồn

Lớp Concreteproductb (iProduct): " Giao diện iProduct "def __init __ (self): self.name =" ConcreteProductc "def created_object (self): return self class factorya:" Lớp nhà máy "@staticmethod def create_object (some_property):" Hãy thử: nếu some_property == 'a': return comcreTeproducta () nếu some_property == 'b': return comceteproductb () nếu some_property == 'c' _e: in (_e) không trả về không

. Tóm tắtMethod def created_object (): Bản quyền © 2019-2021 Sean Bradley

- 31/238 -

5.2.4 Mã nguồn

Lớp Concreteproductb (iProduct): " Giao diện iProduct "def __init __ (self): self.name =" ConcreteProductc "def created_object (self): return self class factorya:" Lớp nhà máy "@staticmethod def create_object (some_property):" Hãy thử: nếu some_property == 'a': return comcreTeproducta () nếu some_property == 'b': return comceteproductb () nếu some_property == 'c' _e: in (_e) không trả về không

Bản quyền © 2019-2021 Sean Bradley

. Tóm tắtMethod def created_object (): Bản quyền © 2019-2021 Sean Bradley

- 31/238 -

"Một phương pháp giao diện trừu tượng" Lớp Concreteproducta (iProduct): " Một lớp cụ thể thực hiện giao diện iPluces "def __init __ (self): self.name =" ConcreteProductB "def created . A ': return ConcreteProducta () nếu some_property ==' B ': return cycreteProductB () nếu some_property ==' c ': return ConcreteProductc () Nâng ngoại lệ (' lớp không tìm thấy ') Không có

- 32/238 -

5.2.5 đầu ra

5.2.5 Đầu ra Python ./abstract_factory/abstract_factory_concept.py

Bản quyền © 2019-2021 Sean Bradley

5.2.6 Tóm tắt Nhà máy Ví dụ Sử dụng trường hợp ID video SBCode #13899E

Một trường hợp sử dụng ví dụ có thể là bạn có một cửa hàng nội thất phía trước. Bạn bán nhiều loại đồ nội thất khác nhau. Bạn bán ghế và bàn. Và chúng được sản xuất tại các nhà máy khác nhau bằng các quy trình không liên quan khác nhau không quan trọng đối với mối quan tâm của bạn. Bạn chỉ cần nhà máy để giao hàng. Bạn có thể tạo một mô -đun bổ sung gọi là Nội thất, để xử lý các nhà máy ghế và bàn, do đó loại bỏ các chi tiết triển khai khỏi khách hàng.

5.2.7 Tóm tắt Nhà máy Ví dụ Sơ đồ UML Xem sơ đồ UML này của một triển khai nhà máy đồ nội thất trừu tượng trả về ghế và bàn.

- 33/238 -

5.2.8 Mã nguồn

Các lớp con Thực hiện một giao diện chung Smallchair - _Height: int - _width: int - _depth: int + get_dimensions (): Dict Mediumchair ifurnaturefactory + get_furnio (loại): Loại

Chủ tịch + Get_Chair (Loại): Loại

Ichair + get_dimensions (): Dict

- lên

Nội thấtfactory + get_furnom (loại): loại

Các lớp con Thực hiện một giao diện chung Smalltable - _Height: int - _width: int - _depth: int + get_dimensions ()

Ứng dụng khách hàng

TableFactory + get_table (loại): Loại

Bản quyền © 2019-2021 Sean Bradley

Itable + get_dimensions (): Dict

Một trường hợp sử dụng ví dụ có thể là bạn có một cửa hàng nội thất phía trước. Bạn bán nhiều loại đồ nội thất khác nhau. Bạn bán ghế và bàn. Và chúng được sản xuất tại các nhà máy khác nhau bằng các quy trình không liên quan khác nhau không quan trọng đối với mối quan tâm của bạn. Bạn chỉ cần nhà máy để giao hàng. Bạn có thể tạo một mô -đun bổ sung gọi là Nội thất, để xử lý các nhà máy ghế và bàn, do đó loại bỏ các chi tiết triển khai khỏi khách hàng.

5.2.7 Tóm tắt Nhà máy Ví dụ Sơ đồ UML Xem sơ đồ UML này của một triển khai nhà máy đồ nội thất trừu tượng trả về ghế và bàn.

- 33/238 -

/abstract_factory/interface_furnio_factory.py # pylint: vô hiệu hóa = Too-few-public-methods "Giao diện nhà máy trừu tượng" từ ABC Nhập ABCMETA, Lớp học Tóm tắt Get_Furnig (Nội thất): "Phương pháp giao diện nhà máy trừu tượng tĩnh"

./abstract_factory/chair_factory.py

Bản quyền © 2019-2021 Sean Bradley

- 35/238 -

5.2.8 Mã nguồn

"Lớp nhà máy" từ Small_Chair Nhập Smallchair từ trung bình Nhận một chiếc ghế "Hãy thử: Nếu ghế == 'bigchair': return bigchair () nếu ghế == 'trung bình': trả về trung bình ) ngoại trừ ngoại lệ là _e: print (_e) không trả về không

. def get_dimensions (): "Phương thức giao diện tĩnh"

.

Bản quyền © 2019-2021 Sean Bradley

- 35/238 -

5.2.8 Mã nguồn

"Lớp nhà máy" từ Small_Chair Nhập Smallchair từ trung bình Nhận một chiếc ghế "Hãy thử: Nếu ghế == 'bigchair': return bigchair () nếu ghế == 'trung bình': trả về trung bình ) ngoại trừ ngoại lệ là _e: print (_e) không trả về không

. def get_dimensions (): "Phương thức giao diện tĩnh"

.

Bản quyền © 2019-2021 Sean Bradley

- 35/238 -

5.2.8 Mã nguồn

"Lớp nhà máy" từ Small_Chair Nhập Smallchair từ trung bình Nhận một chiếc ghế "Hãy thử: Nếu ghế == 'bigchair': return bigchair () nếu ghế == 'trung bình': trả về trung bình ) ngoại trừ ngoại lệ là _e: print (_e) không trả về không

. def get_dimensions (): "Phương thức giao diện tĩnh"

.

- 36/238 -

def __init __ (self): self._height = 40 self._width = 40 self._depth = 40 def get_dimensions (self): return {"chiều rộng": self._width, "chiều sâu": self._depth ._Chiều cao }

Bản quyền © 2019-2021 Sean Bradley

. def __init __ (self): self._height = 60 self._width = 60 self._depth = 60 def get_dimensions (self): return {"width": self._width, "chiều sâu" ._Chiều cao }

5.2.8 Mã nguồn

"Lớp nhà máy" từ Small_Chair Nhập Smallchair từ trung bình Nhận một chiếc ghế "Hãy thử: Nếu ghế == 'bigchair': return bigchair () nếu ghế == 'trung bình': trả về trung bình ) ngoại trừ ngoại lệ là _e: print (_e) không trả về không

. def get_dimensions (): "Phương thức giao diện tĩnh"

.

- 36/238 -

Bản quyền © 2019-2021 Sean Bradley

def __init __ (self): self._height = 40 self._width = 40 self._depth = 40 def get_dimensions (self): return {"chiều rộng": self._width, "chiều sâu": self._depth ._Chiều cao }

. def __init __ (self): self._height = 60 self._width = 60 self._depth = 60 def get_dimensions (self): return {"width": self._width, "chiều sâu" ._Chiều cao }

. tự): self._height = 80 self._width = 80 self._depth = 80 def get_dimensions (self):

5.2.9 Đầu ra Python. 60}

5.2.10 Khái niệm mã hóa mới Xử lý ngoại lệ ID video SBCode #9D07C3

Mã Python của bạn có thể tạo ra lỗi. Nó xảy ra với mọi người. Thật khó để thấy trước tất cả các lỗi có thể, nhưng bạn có thể cố gắng xử lý chúng trong trường hợp dù sao. Sử dụng thử, ngoại trừ và cuối cùng các từ khóa tùy chọn để quản lý xử lý lỗi. Trong mã ví dụ, nếu không có ghế hoặc bàn được trả về, một lỗi ngoại lệ được nêu ra và nó bao gồm một chuỗi văn bản có thể được đọc và ghi vào bảng điều khiển. Trong mã của bạn, bạn có thể sử dụng từ khóa RAISE để kích hoạt Python được xây dựng trong các ngoại lệ hoặc thậm chí tạo ra của riêng bạn. def get_furnaturot (đồ nội thất): "Phương pháp Get_Factory tĩnh" Hãy thử: Nếu đồ nội thất trong ['Smallchair', 'Mediumchair', 'Bigchair']: Return Ghế Return (). , 'BigTable']: Return TableFactory (). Get_Table (Nội thất)

Bản quyền © 2019-2021 Sean Bradley

- 40/238 -

5.2.10 Khái niệm mã hóa mới

Tăng ngoại lệ ('Không tìm thấy nhà máy') ngoại trừ ngoại lệ là _E: print (_e) trả về không nếu Woodentable được yêu cầu từ nhà máy, nó sẽ in không có nhà máy nào không cần phải luôn luôn có ngoại lệ để thực hiện. Trong trường hợp đó, bạn có thể xử lý khả năng của bất kỳ loại lỗi nào bằng cách sử dụng chỉ thử và ngoại trừ, với tùy chọn cuối cùng nếu bạn cần. thử: in (my_var) ngoại trừ: in ("xảy ra lỗi không xác định") Cuối cùng: in ("Đây là tùy chọn và sẽ được gọi ngay cả khi không có lỗi") mã trên tạo ra thông báo xảy ra lỗi vì my_var không xác định. Việc cố gắng/ngoại trừ cho phép chương trình tiếp tục chạy, như có thể được xác minh bằng dòng được in trong câu lệnh cuối cùng. Vì vậy, điều này đã cho bạn cơ hội để quản lý bất kỳ lỗi không lường trước nào theo bất kỳ cách nào bạn muốn. Ngoài ra, nếu mã của bạn không bao gồm thử/ngoại trừ và cuối cùng tùy chọn câu lệnh, trình thông dịch Python sẽ trả về lỗi tên hereRror: tên 'my_var'

được xác định và chương trình sẽ gặp sự cố ở dòng đó. Cũng lưu ý làm thế nào lỗi Python mặc định bắt đầu với NameError. Bạn có thể xử lý lỗi cụ thể này một cách rõ ràng bằng cách sử dụng thêm từ khóa. Hãy thử: in (my_var) ngoại trừ nameError: in ("Có một` nameRror` ") ngoại trừ: in (" xảy ra lỗi không xác định ") Cuối cùng: in (" Đây là tùy chọn và sẽ được gọi ngay cả khi không có lỗi " ) Bạn có thể thêm xử lý ngoại lệ cho nhiều loại lỗi như bạn muốn. Lỗi và ngoại lệ của Python: https://docs.python.org/3/tutorial/errors.html

Bản quyền © 2019-2021 Sean Bradley

- 40/238 -

5.2.10 Khái niệm mã hóa mới

Tăng ngoại lệ ('Không tìm thấy nhà máy') ngoại trừ ngoại lệ là _E: print (_e) trả về không nếu Woodentable được yêu cầu từ nhà máy, nó sẽ in không có nhà máy nào không cần phải luôn luôn có ngoại lệ để thực hiện. Trong trường hợp đó, bạn có thể xử lý khả năng của bất kỳ loại lỗi nào bằng cách sử dụng chỉ thử và ngoại trừ, với tùy chọn cuối cùng nếu bạn cần. thử: in (my_var) ngoại trừ: in ("xảy ra lỗi không xác định") Cuối cùng: in ("Đây là tùy chọn và sẽ được gọi ngay cả khi không có lỗi") mã trên tạo ra thông báo xảy ra lỗi vì my_var không xác định. Việc cố gắng/ngoại trừ cho phép chương trình tiếp tục chạy, như có thể được xác minh bằng dòng được in trong câu lệnh cuối cùng. Vì vậy, điều này đã cho bạn cơ hội để quản lý bất kỳ lỗi không lường trước nào theo bất kỳ cách nào bạn muốn. Ngoài ra, nếu mã của bạn không bao gồm thử/ngoại trừ và cuối cùng tùy chọn câu lệnh, trình thông dịch Python sẽ trả về lỗi tên hereRror: tên 'my_var'

Bản quyền © 2019-2021 Sean Bradley

- 40/238 -

5.2.10 Khái niệm mã hóa mới

Tăng ngoại lệ ('Không tìm thấy nhà máy') ngoại trừ ngoại lệ là _E: print (_e) trả về không nếu Woodentable được yêu cầu từ nhà máy, nó sẽ in không có nhà máy nào không cần phải luôn luôn có ngoại lệ để thực hiện. Trong trường hợp đó, bạn có thể xử lý khả năng của bất kỳ loại lỗi nào bằng cách sử dụng chỉ thử và ngoại trừ, với tùy chọn cuối cùng nếu bạn cần. thử: in (my_var) ngoại trừ: in ("xảy ra lỗi không xác định") Cuối cùng: in ("Đây là tùy chọn và sẽ được gọi ngay cả khi không có lỗi") mã trên tạo ra thông báo xảy ra lỗi vì my_var không xác định. Việc cố gắng/ngoại trừ cho phép chương trình tiếp tục chạy, như có thể được xác minh bằng dòng được in trong câu lệnh cuối cùng. Vì vậy, điều này đã cho bạn cơ hội để quản lý bất kỳ lỗi không lường trước nào theo bất kỳ cách nào bạn muốn. Ngoài ra, nếu mã của bạn không bao gồm thử/ngoại trừ và cuối cùng tùy chọn câu lệnh, trình thông dịch Python sẽ trả về lỗi tên hereRror: tên 'my_var'

được xác định và chương trình sẽ gặp sự cố ở dòng đó. Cũng lưu ý làm thế nào lỗi Python mặc định bắt đầu với NameError. Bạn có thể xử lý lỗi cụ thể này một cách rõ ràng bằng cách sử dụng thêm từ khóa. Hãy thử: in (my_var) ngoại trừ nameError: in ("Có một` nameRror` ") ngoại trừ: in (" xảy ra lỗi không xác định ") Cuối cùng: in (" Đây là tùy chọn và sẽ được gọi ngay cả khi không có lỗi " ) Bạn có thể thêm xử lý ngoại lệ cho nhiều loại lỗi như bạn muốn. Lỗi và ngoại lệ của Python: https://docs.python.org/3/tutorial/errors.html

- 41/238 -

5.2.11 Tóm tắt

Bản quyền © 2019-2021 Sean Bradley

- 43/238 -

5.3.3 Builder UML Sơ đồ

5.3.3 Builder UML Sơ đồ Ứng dụng máy khách iBuilder

+ build_part_a (type): type + build_part_b (type): type + build_part_c (type): loại

Giám đốc xây dựng + Construct (Loại): Loại

Sản phẩm + build_part_a (loại): loại + build_part_b (type): loại + build_part_c (type): loại

+ phần (loại): loại

5.3.4 Mã nguồn 1. Khách hàng tạo giám đốc. 2. Máy khách gọi phương thức Giám đốc xây dựng () quản lý từng bước của quy trình xây dựng. 3. Giám đốc trả lại sản phẩm cho khách hàng hoặc thay vào đó cũng có thể cung cấp một phương thức để khách hàng lấy lại sau.

. .

Bản quyền © 2019-2021 Sean Bradley

- 44/238 -

5.3.4 Mã nguồn

"Xây dựng phần C" @staticmethod @abstractmethod def get_result (): "Trả lại sản phẩm cuối cùng" Trình tạo lớp (iBuilder): "Người xây dựng cụ thể." def __init __ (self): self.product = sản phẩm () def build_part_a (self): self.product.parts.append ('a') return self def build_part_b (self) ) tự trả lại DEF BUILD_PART_C (tự): self.product.parts.append ('c') return self def get_result (self): return self Parts = [] Giám đốc lớp: "Giám đốc, xây dựng một đại diện phức tạp." @StaticMethod def Construct (): "Cấu trúc và trả về sản phẩm cuối cùng" Trở lại Builder () \ .Build_Part_A () \ .Build_Part_B () \ .Build_Part_C () \. (Sản phẩm.parts)

Bản quyền © 2019-2021 Sean Bradley

- 45/238 -

5.3.5 đầu ra

5.3.5 Đầu ra Python ./Builder/Builder_Concept.py ['A', 'B', 'C']]]

5.3.6 Builder sử dụng trường hợp ID video SBCode #81867F

Sử dụng mô hình xây dựng trong bối cảnh của một người xây dựng nhà. Có nhiều giám đốc có thể tạo ra các đối tượng phức tạp của riêng họ. Lưu ý rằng trong lớp Igloodirector, không phải tất cả các phương pháp của người nội trợ đều được gọi. Người xây dựng có thể xây dựng các đối tượng phức tạp theo bất kỳ thứ tự nào và bao gồm/loại trừ bất kỳ phần nào nó thích.

5.3.7 Ví dụ Sơ đồ UML IhouseBuilder

Igloodirector

+ set_building_type (int) + set_number_walls (int) + set_number_windows (int) + set_number_doors (int) + get_result ()

+ Construct (Loại): Loại Ứng dụng máy khách Castledirector + Cấu trúc (Loại): Loại: Loại

+ set_building_type (int) + set_number_walls (int) + set_number_windows (int) + set_number_doors (int) + get_result ()

+ Construct (Loại): Loại Ứng dụng máy khách Castledirector + Cấu trúc (Loại): Loại: Loại

HouseboatDirector + Cấu trúc (Loại): Loại

Bản quyền © 2019-2021 Sean Bradley

House + buildng_type: str + cửa: int + wall_m vật liệu: str + windows: int + xây dựng (): str

- 46/238 -

5.3.8 Mã nguồn

5.3.8 Mã nguồn. ) in (igloo.construction ()) in (Castle.construction ()) in (hòn thuyền.construction ())

. @StaticMethod def Construct (): "" "Cấu trúc và trả về sản phẩm cuối cùng lưu ý rằng trong igloodirector này, nó đã bỏ qua cuộc gọi windows set_number_of vì igloo này sẽ không có windows." " ") \ .set_wall_m vật liệu (" ICE ")

Bản quyền © 2019-2021 Sean Bradley

.

- 46/238 -

5.3.8 Mã nguồn

5.3.8 Mã nguồn. ) in (igloo.construction ()) in (Castle.construction ()) in (hòn thuyền.construction ())

. @StaticMethod def Construct (): "" "Cấu trúc và trả về sản phẩm cuối cùng lưu ý rằng trong igloodirector này, nó đã bỏ qua cuộc gọi windows set_number_of vì igloo này sẽ không có windows." " ") \ .set_wall_m vật liệu (" ICE ")

Bản quyền © 2019-2021 Sean Bradley

.

- 46/238 -

5.3.8 Mã nguồn

5.3.8 Mã nguồn. ) in (igloo.construction ()) in (Castle.construction ()) in (hòn thuyền.construction ())

Bản quyền © 2019-2021 Sean Bradley

. @StaticMethod def Construct (): "" "Cấu trúc và trả về sản phẩm cuối cùng lưu ý rằng trong igloodirector này, nó đã bỏ qua cuộc gọi windows set_number_of vì igloo này sẽ không có windows." " ") \ .set_wall_m vật liệu (" ICE ")

.

- 47/238 -

5.3.9 Output python ./builder/client.py This is a Ice Igloo with 1 door(s) and 0 window(s). This is a Sandstone Castle with 100 door(s) and 200 window(s). This is a Wood House Boat with 6 door(s) and 8 window(s).

5.3.10 New Coding Concepts Python List SBCODE Video ID #a2766f

In the file ./builder/builder_concept.py def __init__(self): self.parts = [] The [] is indicating a Python List. The list can store multiple items, they can be changed, they can have items added and removed, can be re-ordered, can be pre-filled with items when instantiated and is also very flexible.

Copyright © 2019-2021 Sean Bradley

- 50/238 -

5.3.11 Summary

PS> python >>> items = [] >>> items.append("shouldn't've") >>> items.append("y'aint") >>> items.extend(["whomst", "superfluity"]) >>> items ["shouldn't've", "y'aint", 'whomst', 'superfluity'] >>> items.reverse() >>> items ['superfluity', 'whomst', "y'aint", "shouldn't've"] >>> items.remove("y'aint") >>> items ['superfluity', 'whomst', "shouldn't've"] >>> items.insert(1, "phoque") >>> items ['superfluity', 'phoque', 'whomst', "shouldn't've"] >>> items.append("whomst") >>> items.count("whomst") 2 >>> len(items) 5 >>> items[2] = "bagnose" >>> items ['superfluity', 'phoque', 'bagnose', "shouldn't've", 'whomst'] >>> items[-2] "shouldn't've" Lists are used in almost every code example in this book. You will see all the many ways they can be used. In fact, a list was used in the Abstract Factory example, if furniture in ['SmallChair', 'MediumChair', 'BigChair']: ... This line, creates a list at runtime including the strings 'SmallChair', 'MediumChair' and 'BigChair'. If the value in furniture equals the same string as one of those items in the list, then the condition is true and the code within the if statement block will execute.

5.3.11 Summary • The Builder pattern is a creational pattern that is used to create more complex objects than you'd expect from a factory. • The Builder pattern should be able to construct complex objects in any order and include/ exclude whichever available components it likes.

Copyright © 2019-2021 Sean Bradley

- 51/238 -

5.3.11 Summary

• For different combinations of products than can be returned from a Builder, use a specific Director to create the bespoke combination. • You can use an Abstract Factory to add an abstraction between the client and Director.

Copyright © 2019-2021 Sean Bradley

- 52/238 -

5.4 Prototype Design Pattern

5.4 Prototype Design Pattern 5.4.1 Overview SBCODE Video ID #7d8d9f

The Prototype design pattern is good for when creating new objects requires more resources than you want to use or have available. You can save resources by just creating a copy of any existing object that is already in memory. E.g., A file you've downloaded from a server may be large, but since it is already in memory, you could just clone it, and work on the new copy independently of the original. In the Prototype patterns interface, you create a static clone method that should be implemented by all classes that use the interface. How the clone method is implemented in the concrete class is up to you. You will need to decide whether a shallow or deep copy is required. • A shallow copy, copies and creates new references one level deep, • A deep copy, copies and creates new references for all levels. In Python you have mutable objects such as Lists, Dictionaries, Sets and any custom Objects you may have created. A shallow copy, will create new copies of the objects with new references in memory, but the underlying data, e.g., the actual elements in a list, will point to the same memory location as the original list/object being copied. You will now have two lists, but the elements within the lists will point to the same memory location. So, changing any elements of a copied list will also affect the original list. Be sure to test your implementation that the copy method you use works as expected. Shallow copies are much faster to process than deep copies and deep copies are not always necessary if you are not going to benefit from using it.

5.4.2 Thuật ngữ • Giao diện nguyên mẫu: Giao diện mô tả phương thức Clone (). • Nguyên mẫu: Đối tượng/sản phẩm thực hiện giao diện nguyên mẫu. • Khách hàng: Ứng dụng máy khách sử dụng và tạo nguyên mẫu.

Bản quyền © 2019-2021 Sean Bradley

- 53/238 -

5.4.3 Sơ đồ UML nguyên mẫu

5.4.3 Nguyên mẫu Sơ đồ UML My Class iprototype

+ trường: gõ

+ nhân bản (loại): loại

+ nhân bản (loại): loại

Ứng dụng khách hàng

5.4.4 Thử nghiệm mã nguồn với mã khái niệm. Theo mặc định, nó sẽ sao chép các đối tượng bạn yêu cầu được nhân bản. Đối tượng có thể là bất kỳ loại từ số đến chuỗi đến từ điển đến bất kỳ tùy chỉnh nào bạn đã tạo. Trong ví dụ của tôi, tôi đã tạo một danh sách các số. Ở những ấn tượng đầu tiên, khi danh sách này được sao chép, có vẻ như danh sách đã được nhân bản đầy đủ. Nhưng các mục bên trong của danh sách không. Họ sẽ chỉ vào cùng một vị trí bộ nhớ với danh sách ban đầu; Tuy nhiên, số nhận dạng bộ nhớ của danh sách mới là mới và khác với bản gốc. Trong phương thức myClass.clone (), có một dòng self.field.copy () được nhận xét. Giải quyết dòng này, và nhận xét dòng trước khi nó trở thành # self.field. RE thực hiện tệp và bây giờ các mục danh sách cũng sẽ được sao chép. Tuy nhiên, điều này vẫn không phải là một bản sao sâu đầy đủ. Nếu các mục trong danh sách thực sự là các danh sách, từ điển hoặc các bộ sưu tập khác, thì chỉ có cấp độ thứ nhất của bản sao đó sẽ được nhân bản vào số nhận dạng bộ nhớ mới. Tôi gọi đây là một bản sao 2 cấp. Đối với một bản sao đệ quy đầy đủ, hãy sử dụng phương thức Copy.DeepCopy () là một phần của một phần dành riêng

Sao chép nhập bao gồm với Python. Tôi chứng minh điều này trong trường hợp sử dụng ví dụ thêm xuống. Hãy nhớ rằng các bản sao sâu đầy đủ có khả năng có thể chậm hơn nhiều đối với hệ thống phân cấp đối tượng rất phức tạp.

./prototype/prototype_concept.py # pylint: vô hiệu: quá

Bản quyền © 2019-2021 Sean Bradley

- 54/238 -

5.4.4 Mã nguồn

Từ ABC Nhập ABCMeta, Tóm tắtMethod Class iprototype (metaclass = abcmeta): "Giao diện với phương thức sao chép" @staticmethod @abstractmethod def clone (): "" chi tiết trong lớp cụ thể của bạn "" "lớp myclass (iprototype):" một lớp cụ thể "def __init __ (self, trường): self.field = trường Kỹ thuật sao chép nông "Loại trả về (self) (self.field # một bản sao nông được trả về # self.field.copy () # Đây cũng là một bản sao nông, nhưng có # cũng sao chép cấp độ đầu tiên của trường. Vì vậy, nó # về cơ bản là một bản sao nông nhưng sâu 2 cấp. đến # Bộ sưu tập sao chép sâu trong bộ sưu tập bên trong #, # EG Danh sách danh sách, # Sử dụng https://docs.python.org/3/l Library/copy.html thay thế. # # # # # # # # Xem ví dụ bên dưới.) Def __str __ (self): return f "{id (self)} \ tfield = {self.field} \ ttype = {type (self.field)}" # máy khách đối tượng1 = myClass ([1, 2, 3, 4]) in (f "object1 {object 1} ") Object2 = object1.clone ()

# Tạo đối tượng chứa danh sách

# Dòng vô tính

# Thay đổi giá trị của một trong các phần tử danh sách trong Object2, # để xem liệu nó cũng sửa đổi phần tử danh sách trong Object1. # Nếu nó thay đổi bản sao đối tượng1S, thì bản sao đã được thực hiện # bằng cách sử dụng quy trình sao chép mức 1 cấp. # Sửa đổi phương thức bản sao ở trên để thử bản sao 2 mức 2 thay vì so sánh và so sánh đối tượng đầu ra2.field [1] = 101 # So sánh Object1 và Object2

Bản quyền © 2019-2021 Sean Bradley

- 55/238 -

5.4.5 đầu ra

PRIN

5.4.5 Đầu ra khi sử dụng phương pháp sao chép nông. Thay đổi mục bên trong của danh sách Object2S, cũng ảnh hưởng đến danh sách Object1s. Python.

type = type = type =

Khi sử dụng phương pháp tiếp cận nông cạn hoặc sao chép sâu 2 cấp. Thay đổi mục bên trong của danh sách Object2S, không ảnh hưởng đến danh sách Object1s. Đọc ghi chú dưới đây để cảnh báo. Python.

type = type = type =

Khi sử dụng phương pháp tiếp cận nông cạn hoặc sao chép sâu 2 cấp. Thay đổi mục bên trong của danh sách Object2S, không ảnh hưởng đến danh sách Object1s. Đọc ghi chú dưới đây để cảnh báo. Python.

- 55/238 -

5.4.5 đầu ra

Bản quyền © 2019-2021 Sean Bradley

- 54/238 -

5.4.4 Mã nguồn

Từ ABC Nhập ABCMeta, Tóm tắtMethod Class iprototype (metaclass = abcmeta): "Giao diện với phương thức sao chép" @staticmethod @abstractmethod def clone (): "" chi tiết trong lớp cụ thể của bạn "" "lớp myclass (iprototype):" một lớp cụ thể "def __init __ (self, trường): self.field = trường Kỹ thuật sao chép nông "Loại trả về (self) (self.field # một bản sao nông được trả về # self.field.copy () # Đây cũng là một bản sao nông, nhưng có # cũng sao chép cấp độ đầu tiên của trường. Vì vậy, nó # về cơ bản là một bản sao nông nhưng sâu 2 cấp. đến # Bộ sưu tập sao chép sâu trong bộ sưu tập bên trong #, # EG Danh sách danh sách, # Sử dụng https://docs.python.org/3/l Library/copy.html thay thế. # # # # # # # # Xem ví dụ bên dưới.) Def __str __ (self): return f "{id (self)} \ tfield = {self.field} \ ttype = {type (self.field)}" # máy khách đối tượng1 = myClass ([1, 2, 3, 4]) in (f "object1 {object 1} ") Object2 = object1.clone ()

# Tạo đối tượng chứa danh sách

# Dòng vô tính

# Thay đổi giá trị của một trong các phần tử danh sách trong Object2, # để xem liệu nó cũng sửa đổi phần tử danh sách trong Object1. # Nếu nó thay đổi bản sao đối tượng1S, thì bản sao đã được thực hiện # bằng cách sử dụng quy trình sao chép mức 1 cấp. # Sửa đổi phương thức bản sao ở trên để thử bản sao 2 mức 2 thay vì so sánh và so sánh đối tượng đầu ra2.field [1] = 101 # So sánh Object1 và Object2

- 55/238 -

Bản quyền © 2019-2021 Sean Bradley

5.4.5 đầu ra

5.4.8 Mã nguồn

Document_copy_3 = gốc_document.clone (2) # 2 Cấp bản sao nông Document_copy_3.name = "Sao chép 3" # Điều này không sửa đổi bản gốc_Document vì nó thay đổi phần tử của danh sách # [1] [0] Document_copy_3.list [1] [0] = " Sửa đổi gốc_document vì nó # Deep sao chép tất cả các cấp độ khi sử dụng Mode 3 document_copy_4.list [1] [0] = "5678" in (document_copy_4) in (bản gốc_document) print ()

. , l): self.name = name self.list = l def clone (self, mode): "Phương thức nhân bản này sử dụng các kỹ thuật sao chép khác nhau" nếu chế độ == 1: # kết quả ở cấp 1 bản sao nông của tài liệu doc_list = self.list If mode == 2: # kết quả ở cấp 2 bản sao nông của tài liệu # vì nó cũng tạo các tài liệu tham khảo mới cho danh sách cấp 1 # Bản sao sâu đệ quy. Chậm hơn nhưng dẫn đến một bản sao mới # trong đó không có phần tử phụ nào được chia sẻ bởi tham chiếu doc_list = copy.deepcopy (self.list) loại trả về (self) 2021 Sean Bradley

- 58/238 -

5.4.9 Đầu ra

doc_list

# Phương thức sao chép được quyết định bởi đối số chế độ

) def __str __ (self): "Ghi đè phương thức __str__ mặc định cho đối tượng của chúng tôi." trả về f "{id (self)} \ tname = {self.name} \ tlist = {self.list}"

. Clone (Mode): "" "Bản sao, sâu hoặc nông. Tùy thuộc vào bạn, bạn muốn thực hiện các chi tiết trong lớp cụ thể của bạn như thế nào" ""

5.4.9 Đầu ra Python ./prototype/client.py 2520526585808 Tên = Bản gốc

Danh sách = [[1, 2, 3, 4], [5, 6, 7, 8]]]

2520526585712 2520526585808

Tên = Sao chép 1 Tên = Bản gốc

Danh sách = [[1, 2, 3, 4], [5, 6, 200, 8]] list = [[1, 2, 3, 4], [5, 6, 200, 8]]

2520526585664 2520526585808

Tên = Sao chép 2 Tên = Bản gốc

Danh sách = [[1, 2, 3, 4], [9, 10, 11, 12]] list = [[1, 2, 3, 4], [5, 6, 200, 8]]

2520526585520 2520526585808

Tên = Sao chép 3 Tên = Bản gốc

list = [[1, 2, 3, 4], ['1234', 6, 200, 8]] list = [[1, 2, 3, 4], ['1234', 6, 200, 8]]

2520526585088 2520526585808

Tên = Sao chép 4 Tên = Bản gốc

list = [[1, 2, 3, 4], ['5678', 6, 200, 8]] list = [[1, 2, 3, 4], ['1234', 6, 200, 8]]

5.4.10 Khái niệm mã hóa mới Python id () Chức năng SBCode Video ID #08B4A7

Bản quyền © 2019-2021 Sean Bradley

- 59/238 -

5.4.11 Tóm tắt

Hàm python id () trả về địa chỉ bộ nhớ của một đối tượng. Tất cả các đối tượng trong Python sẽ có một địa chỉ bộ nhớ. Bạn có thể kiểm tra xem một đối tượng là duy nhất trong Python bằng cách so sánh ID của nó. Trong các ví dụ trên, tôi có thể biết các bản sao của từ điển và danh sách sâu sắc như thế nào, bởi vì ID của các mục bên trong sẽ khác nhau. Tức là, họ chỉ ra các định danh bộ nhớ khác nhau. Lưu ý rằng mỗi khi bạn bắt đầu một quy trình Python, ID được gán trong thời gian chạy có thể sẽ khác nhau. Cũng lưu ý rằng các số nguyên trong Python cũng có ID riêng. in (id (0)) in (id (1)) in (id (2)) xuất ra 2032436013328 2032436013360 2032436013392

5.4.11 Tóm tắt • Giống như các mẫu sáng tạo khác, một nguyên mẫu được sử dụng để tạo một đối tượng trong thời gian chạy. • Một nguyên mẫu được tạo từ một đối tượng đã được khởi tạo. Hãy tưởng tượng sử dụng đối tượng hiện có làm mẫu lớp để tạo một đối tượng mới, thay vì gọi một lớp cụ thể. • Khả năng tạo một nguyên mẫu có nghĩa là bạn không cần tạo nhiều lớp cho các kết hợp cụ thể của các đối tượng. Bạn có thể tạo một đối tượng, có cấu hình cụ thể và sau đó sao chép phiên bản này nhiều lần, thay vì tạo một đối tượng mới từ định nghĩa lớp được xác định trước. • Các nguyên mẫu mới có thể được tạo vào thời gian chạy, mà không biết loại thuộc tính nào mà nguyên mẫu cuối cùng có thể có. Ví dụ: bạn có một đối tượng tinh vi được tạo ngẫu nhiên từ nhiều yếu tố và bạn muốn sao chép nó thay vì áp dụng tất cả các chức năng giống nhau nhiều lần cho đến khi đối tượng mới khớp với bản gốc. • Một nguyên mẫu cũng hữu ích khi bạn muốn tạo một bản sao của một đối tượng, nhưng việc tạo bản sao đó có thể rất tốn tài nguyên. Ví dụ: bạn có thể tạo một chiếc thuyền nhà mới từ ví dụ xây dựng hoặc sao chép một chiếc thuyền nhà hiện có từ một trong bộ nhớ. • Khi thiết kế phương thức Clone () của bạn, bạn nên xem xét các yếu tố nào sẽ được sao chép nông, sâu như thế nào và liệu bản sao sâu đệ quy đầy đủ có cần thiết hay không. • Để sao chép sâu đệ quy, hãy sử dụng thư viện tại https://docs.python.org/3/l Library/copy.html

Bản quyền © 2019-2021 Sean Bradley

- 60/238 -

5.5 Mô hình thiết kế Singleton

5.5 Mẫu thiết kế Singleton 5.5.1 Tổng quan về video SBCode #F4A24D

Đôi khi bạn cần một đối tượng trong một ứng dụng chỉ có một trường hợp. Bạn không muốn có nhiều phiên bản, ví dụ, bạn có một trò chơi với điểm số và bạn muốn điều chỉnh nó. Bạn có thể đã vô tình tạo ra một số trường hợp của lớp giữ đối tượng điểm số. Hoặc, bạn có thể đang mở kết nối cơ sở dữ liệu, không cần phải tạo nhiều, khi bạn có thể sử dụng hệ thống hiện có trong bộ nhớ. Bạn có thể muốn một thành phần ghi nhật ký và bạn muốn đảm bảo tất cả các lớp sử dụng cùng một thể hiện. Vì vậy, mỗi lớp có thể khai báo thành phần logger của riêng họ, nhưng đằng sau hậu trường, tất cả đều chỉ vào cùng một địa chỉ bộ nhớ (ID). Bằng cách tạo một lớp và tuân theo mẫu singleton, bạn có thể thực thi rằng ngay cả khi bất kỳ số lượng phiên bản nào được tạo, chúng vẫn sẽ đề cập đến lớp gốc. Singleton có thể được truy cập trên toàn cầu, nhưng nó không phải là một biến toàn cầu. Đó là một lớp có thể được khởi tạo bất cứ lúc nào, nhưng sau khi nó được khởi tạo đầu tiên, bất kỳ trường hợp mới nào cũng sẽ chỉ ra cùng một trường hợp như lần đầu tiên. Để một lớp hoạt động như một singleton, nó không nên chứa bất kỳ tài liệu tham khảo nào cho bản thân mà sử dụng các biến tĩnh, phương thức tĩnh và/hoặc phương thức lớp.

5.5.2 SINGLETON UML Sơ đồ

Ứng dụng khách hàng Singleton

+ Giá trị: Loại + __New __ (CLS)

5.5.3 Mã nguồn Trong mã nguồn, tôi ghi đè phương thức Lớp __New__ để trả về một tham chiếu cho chính nó. Điều này sau đó làm cho phương pháp __init__ không liên quan. Khi chạy ví dụ, thử nghiệm nhận xét phương thức __new__ và bạn sẽ thấy rằng ID của các trường hợp không còn trỏ đến cùng một vị trí bộ nhớ của lớp, mà thay vào đó là số nhận dạng bộ nhớ mới. Lớp học không còn là một singleton.

Bản quyền © 2019-2021 Sean Bradley

- 60/238 -

5.5 Mô hình thiết kế Singleton

5.5 Mẫu thiết kế Singleton 5.5.1 Tổng quan về video SBCode #F4A24D

Đôi khi bạn cần một đối tượng trong một ứng dụng chỉ có một trường hợp. Bạn không muốn có nhiều phiên bản, ví dụ, bạn có một trò chơi với điểm số và bạn muốn điều chỉnh nó. Bạn có thể đã vô tình tạo ra một số trường hợp của lớp giữ đối tượng điểm số. Hoặc, bạn có thể đang mở kết nối cơ sở dữ liệu, không cần phải tạo nhiều, khi bạn có thể sử dụng hệ thống hiện có trong bộ nhớ. Bạn có thể muốn một thành phần ghi nhật ký và bạn muốn đảm bảo tất cả các lớp sử dụng cùng một thể hiện. Vì vậy, mỗi lớp có thể khai báo thành phần logger của riêng họ, nhưng đằng sau hậu trường, tất cả đều chỉ vào cùng một địa chỉ bộ nhớ (ID). Bằng cách tạo một lớp và tuân theo mẫu singleton, bạn có thể thực thi rằng ngay cả khi bất kỳ số lượng phiên bản nào được tạo, chúng vẫn sẽ đề cập đến lớp gốc. Singleton có thể được truy cập trên toàn cầu, nhưng nó không phải là một biến toàn cầu. Đó là một lớp có thể được khởi tạo bất cứ lúc nào, nhưng sau khi nó được khởi tạo đầu tiên, bất kỳ trường hợp mới nào cũng sẽ chỉ ra cùng một trường hợp như lần đầu tiên. Để một lớp hoạt động như một singleton, nó không nên chứa bất kỳ tài liệu tham khảo nào cho bản thân mà sử dụng các biến tĩnh, phương thức tĩnh và/hoặc phương thức lớp.

Bản quyền © 2019-2021 Sean Bradley

5.5.2 SINGLETON UML Sơ đồ

Ứng dụng khách hàng Singleton

+ Giá trị: Loại + __New __ (CLS)

5.5.5 Singleton sử dụng trường hợp ID video SBCode #746648

Trong ví dụ, có ba trò chơi được tạo ra. Tất cả đều là những trường hợp độc lập được tạo ra từ lớp riêng của họ, nhưng tất cả họ đều có chung bảng xếp hạng. Bảng xếp hạng là một singleton. Không quan trọng làm thế nào các trò chơi được tạo ra, hoặc làm thế nào họ tham khảo bảng xếp hạng, nó luôn luôn là một singleton. Mỗi trò chơi độc lập thêm một người chiến thắng và tất cả các trò chơi có thể đọc bảng xếp hạng thay đổi bất kể trò chơi nào được cập nhật.

Bản quyền © 2019-2021 Sean Bradley

- 63/238 -

5.5.6 Sơ đồ uml ví dụ

5.5.6 Sơ đồ uml ví dụ

Bảng xếp hạng - _Table: Từ điển + __New __ (cls) + print () + add_winner (vị trí, tên)

Game1

Game2

Game3

+ init () + add_winner (vị trí, tên)

+ init () + add_winner (vị trí, tên)

+ init () + add_winner (vị trí, tên)

Ứng dụng khách hàng

Igame + add_winner (vị trí, tên)

5.5.7 Mã nguồn. Từ Game1 Nhập Game1 từ Game2 Nhập Game2 từ Game3 Nhập Game3 # Client # Tất cả các trò chơi chia sẻ và quản lý cùng một bảng xếp hạng vì đây là một singleton. Game1 = game1 () game1.add_winner (2, "cosmo") game2 = game2 () game2.add_winner (3, "sean") game3 = game3 () game3.add_winner (1, "emmy")

Bản quyền © 2019-2021 Sean Bradley

- 63/238 -

5.5.6 Sơ đồ uml ví dụ

Bảng xếp hạng - _Table: Từ điển + __New __ (cls) + print () + add_winner (vị trí, tên)

Game1

Game2

Game3

Bản quyền © 2019-2021 Sean Bradley

+ init () + add_winner (vị trí, tên)

5.5.6 Sơ đồ uml ví dụ

Bảng xếp hạng - _Table: Từ điển + __New __ (cls) + print () + add_winner (vị trí, tên)

Game1

Game2

Bản quyền © 2019-2021 Sean Bradley

Game3

+ init () + add_winner (vị trí, tên)

Ứng dụng khách hàng

Igame + add_winner (vị trí, tên)

5.5.7 Mã nguồn. Từ Game1 Nhập Game1 từ Game2 Nhập Game2 từ Game3 Nhập Game3 # Client # Tất cả các trò chơi chia sẻ và quản lý cùng một bảng xếp hạng vì đây là một singleton. Game1 = game1 () game1.add_winner (2, "cosmo") game2 = game2 () game2.add_winner (3, "sean") game3 = game3 () game3.add_winner (1, "emmy")

- 64/238 -

5.5.7 Mã nguồn

Game1.leaderboard.print () game2.leaderboard.print () game3.leaderboard.print ()

5.5.10 Tóm tắt • Để trở thành một người độc thân, chỉ phải có một bản sao của singleton, bất kể bao nhiêu lần, hoặc trong lớp nào nó được khởi tạo. • Bạn muốn các thuộc tính hoặc phương thức có thể truy cập toàn cầu trên toàn bộ ứng dụng của bạn, để các lớp khác có thể sử dụng singleton. • Bạn có thể sử dụng singletons trong các lớp khác, như tôi đã làm với bảng xếp hạng và tất cả họ sẽ sử dụng cùng một singleton bất kể. • Bạn muốn quyền truy cập được kiểm soát vào một thể hiện duy nhất. • Để một lớp hoạt động như một singleton, nó không nên chứa bất kỳ tài liệu tham khảo nào cho bản thân.

Bản quyền © 2019-2021 Sean Bradley

- 68/238 -

6. Cấu trúc

6. Mẫu thiết kế cấu trúc 6.1 Bộ trang trí 6.1.1 Tổng quan về SBCode Video ID #AB01CD

Mô hình trang trí là một mô hình cấu trúc, cho phép bạn đính kèm trách nhiệm bổ sung vào một đối tượng trong thời gian chạy. Các mẫu trang trí được sử dụng trong cả hai mô hình định hướng đối tượng và chức năng. Mô hình trang trí khác với tính năng ngôn ngữ Python của các nhà trang trí Python trong cú pháp và mục đích hoàn chỉnh của nó. Đó là một khái niệm tương tự theo cách mà nó là một trình bao bọc, nhưng nó cũng có thể được áp dụng trong thời gian chạy tự động. Các mẫu trang trí thêm khả năng mở rộng mà không cần sửa đổi đối tượng ban đầu. Người trang trí chuyển tiếp yêu cầu đến đối tượng kèm theo và có thể thực hiện các hành động bổ sung. Bạn có thể trang trí tổ đệ quy.

6.1.2 Thuật ngữ • Giao diện thành phần: Giao diện cho các đối tượng. • Thành phần: Đối tượng có thể được trang trí. • Nhà trang trí: Lớp áp dụng các trách nhiệm bổ sung cho thành phần được trang trí. Nó cũng thực hiện cùng một giao diện thành phần.

Bản quyền © 2019-2021 Sean Bradley

- 68/238 -

6. Cấu trúc

6. Mẫu thiết kế cấu trúc 6.1 Bộ trang trí 6.1.1 Tổng quan về SBCode Video ID #AB01CD

Mô hình trang trí là một mô hình cấu trúc, cho phép bạn đính kèm trách nhiệm bổ sung vào một đối tượng trong thời gian chạy. Các mẫu trang trí được sử dụng trong cả hai mô hình định hướng đối tượng và chức năng. Mô hình trang trí khác với tính năng ngôn ngữ Python của các nhà trang trí Python trong cú pháp và mục đích hoàn chỉnh của nó. Đó là một khái niệm tương tự theo cách mà nó là một trình bao bọc, nhưng nó cũng có thể được áp dụng trong thời gian chạy tự động. Các mẫu trang trí thêm khả năng mở rộng mà không cần sửa đổi đối tượng ban đầu. Người trang trí chuyển tiếp yêu cầu đến đối tượng kèm theo và có thể thực hiện các hành động bổ sung. Bạn có thể trang trí tổ đệ quy.

6.1.2 Thuật ngữ • Giao diện thành phần: Giao diện cho các đối tượng. • Thành phần: Đối tượng có thể được trang trí. • Nhà trang trí: Lớp áp dụng các trách nhiệm bổ sung cho thành phần được trang trí. Nó cũng thực hiện cùng một giao diện thành phần.

- 69/238 -

- 69/238 -

6.1.3 Sơ đồ trang trí UML

6.1.3 Sơ đồ trang trí UML

6.1.3 Bộ trang trí Sơ đồ UML Icomponent + Phương pháp (Loại): Loại

Thành phần

Bản quyền © 2019-2021 Sean Bradley

Người trang trí

+ trường: gõ

+ phương pháp (loại): loại

Ứng dụng khách hàng

6.1.4 Mã nguồn. "@staticmethod @abstractmethod def phương thức ():" Một phương pháp để thực hiện "Thành phần lớp (iComponent):" Một thành phần có thể được trang trí hoặc không "Phương thức def (tự): (Icomponent): "Người trang trí cũng thực hiện icomponent"

- 70/238 -

6.1.5 đầu ra

Bản quyền © 2019-2021 Sean Bradley

def __init __ (self, obj): "Đặt tham chiếu đến đối tượng được trang trí" self.Object = obj def phương thức (self): "Một phương thức để thực hiện phương thức trang trí" return f "({self.Object.method ()}) " # Thành phần máy khách = Thành phần () in (Thành phần.method ()) In (Decorator (Thành phần) .Method ())

6.1.5 Đầu ra Python ./decorator/decorator_concept.py Phương pháp thành phần Phương pháp trang trí (Phương pháp thành phần)

6.1.6 Bộ trang trí sử dụng trường hợp SBCode Video ID #EB9F25

Hãy tạo một lớp tùy chỉnh được gọi là giá trị sẽ giữ một số. Sau đó thêm các trình trang trí cho phép bổ sung (thêm) và trừ (phụ) vào một số (giá trị). Các trình trang trí bổ sung và phụ có thể chấp nhận số nguyên trực tiếp, một đối tượng giá trị tùy chỉnh hoặc các đối tượng khác

Thêm và trang trí phụ. Thêm, phụ và giá trị tất cả thực hiện giao diện Ivalue và có thể được sử dụng đệ quy.

- 71/238 -

6.1.7 Sơ đồ UML ví dụ

6.1.7 Sơ đồ UML ví dụ

6.1.7 Sơ đồ UML ví dụ

6.1.7 Ví dụ Sơ đồ UML Ivalue + __STR __ ()

6.1.7 Ví dụ Sơ đồ UML Ivalue + __STR __ ()

6.1.7 Ví dụ Sơ đồ UML Ivalue + __STR __ ()

6.1.3 Bộ trang trí Sơ đồ UML Icomponent + Phương pháp (Loại): Loại

Thành phần

Bản quyền © 2019-2021 Sean Bradley

Người trang trí

+ trường: gõ

+ phương pháp (loại): loại

Ứng dụng khách hàng

6.1.6 Bộ trang trí sử dụng trường hợp SBCode Video ID #EB9F25

Bản quyền © 2019-2021 Sean Bradley

Hãy tạo một lớp tùy chỉnh được gọi là giá trị sẽ giữ một số. Sau đó thêm các trình trang trí cho phép bổ sung (thêm) và trừ (phụ) vào một số (giá trị). Các trình trang trí bổ sung và phụ có thể chấp nhận số nguyên trực tiếp, một đối tượng giá trị tùy chỉnh hoặc các đối tượng khác

Thêm và trang trí phụ. Thêm, phụ và giá trị tất cả thực hiện giao diện Ivalue và có thể được sử dụng đệ quy.

- 71/238 -

6.1.7 Sơ đồ UML ví dụ

6.1.7 Ví dụ Sơ đồ UML Ivalue + __STR __ ()

Bản quyền © 2019-2021 Sean Bradley

cộng

Giá trị

Phụ

+ giá trị: int

+ __str __ (bản thân): bản thân.

Dunder __str__ Phương thức ID video SBCode #496AC4

Khi bạn in () một đối tượng, nó sẽ in ra loại đối tượng và vị trí bộ nhớ trong hex. Lớp học tập: ABC = 123 in (Bài kiểm tra ())

Bản quyền © 2019-2021 Sean Bradley

- 75/238 -

6.1.11 Tóm tắt

Đầu ra

Bạn có thể thay đổi đầu ra mặc định này bằng cách triển khai phương thức __str__ Dunder trong lớp của bạn. Dunder là viết tắt để nói Double Undercore. Các phương thức Dunder là các phương thức được xác định trước trong Python mà bạn có thể ghi đè với các triển khai của riêng mình. Class scassPleclass: ABC = 123 def __str __ (self): trả về "cái gì đó khác nhau" in (bài kiểm tra

Phương thức __str__ được ghi đè để trả về một phiên bản chuỗi của giá trị số nguyên. Điều này cho phép in giá trị số của bất kỳ đối tượng nào thực hiện giao diện Ivalue thay vì in một chuỗi giống như một cái gì đó như bên dưới.

__Str__ Dunder cũng được ghi đè trong mã khái niệm Protoype.

6.1.11 Tóm tắt • Sử dụng trình trang trí khi bạn muốn thêm trách nhiệm cho các đối tượng một cách linh hoạt mà không ảnh hưởng đến đối tượng bên trong. • Bạn muốn tùy chọn để loại bỏ bộ trang trí khỏi một đối tượng trong trường hợp bạn không còn cần nó nữa. • Đây là một phương pháp thay thế để tạo ra nhiều kết hợp các lớp con. Tức là, thay vì tạo một lớp con với tất cả các kết hợp các đối tượng A, B, C theo bất kỳ thứ tự nào và bao gồm/ loại trừ các đối tượng, bạn có thể tạo 3 đối tượng có thể trang trí cho nhau theo bất kỳ thứ tự nào bạn muốn. Ví dụ: (d (a (c))) hoặc (b (c)) hoặc (a (b (a (c))) • Bộ trang trí, so với sử dụng kế thừa tĩnh để mở rộng, linh hoạt hơn vì bạn có thể dễ dàng thêm /Xóa các bộ trang trí trong thời gian chạy. Ví dụ: sử dụng trong một hàm đệ quy.

Bản quyền © 2019-2021 Sean Bradley

- 75/238 -

6.1.11 Tóm tắt

Đầu ra

Bản quyền © 2019-2021 Sean Bradley

- 75/238 -

6.1.11 Tóm tắt

Đầu ra

Bạn có thể thay đổi đầu ra mặc định này bằng cách triển khai phương thức __str__ Dunder trong lớp của bạn. Dunder là viết tắt để nói Double Undercore. Các phương thức Dunder là các phương thức được xác định trước trong Python mà bạn có thể ghi đè với các triển khai của riêng mình. Class scassPleclass: ABC = 123 def __str __ (self): trả về "cái gì đó khác nhau" in (bài kiểm tra

6.2.2 Thuật ngữ • Mục tiêu: Giao diện hoặc lớp cụ thể miền cần được điều chỉnh. • Giao diện bộ điều hợp: Giao diện của mục tiêu mà bộ điều hợp sẽ cần thực hiện. • Bộ điều hợp: Lớp bộ điều hợp bê tông chứa quá trình điều chỉnh. • Khách hàng: Ứng dụng khách sẽ sử dụng bộ điều hợp.

Bản quyền © 2019-2021 Sean Bradley

- 78/238 -

6.2.3 Sơ đồ UML Bộ điều hợp

6.2.3 Sơ đồ UML Bộ điều hợp IA

Ib

+ trường: gõ

+ trường: gõ

+ phương thức_a (loại): loại

+ phương thức_b (loại): loại

Classa

Lớp học

LỚP

+ trường: gõ

+ trường: gõ

+ trường: gõ

+ phương thức_a (loại): loại

+ phương thức_a (loại): loại

+ phương thức_b (loại): loại

Classa

Lớp học

LỚP

Bản quyền © 2019-2021 Sean Bradley

Ứng dụng khách hàng

6.2.4 Mã nguồn Trong mã nguồn khái niệm này, có hai lớp, Classa và ClassB, với các chữ ký phương thức khác nhau. Hãy xem xét rằng Classa cung cấp giao diện tương thích và ưa thích nhất cho máy khách. Tôi có thể tạo đối tượng của cả hai lớp trong máy khách và nó hoạt động. Nhưng trước khi sử dụng từng phương thức đối tượng, tôi cần kiểm tra có điều kiện để xem loại lớp nào mà tôi đang gọi vì chữ ký phương thức là khác nhau. Nó có nghĩa là khách hàng đang làm thêm. Thay vào đó, tôi có thể tạo một giao diện bộ điều hợp cho lớp không tương thích, giúp giảm nhu cầu về logic có điều kiện bổ sung.

./ad CHƯƠNG

Bản quyền © 2019-2021 Sean Bradley

- 79/238 -

6.2.4 Mã nguồn

def method_a (): "một phương pháp trừu tượng a" classa (ia): "một lớp mẫu các thực hiện ia" def phương thức_a (self): print ("phương pháp a") lớp ib (metaclass = abcmeta): "giao diện cho giao diện cho một đối tượng "@staticmethod @abstractmethod def method_b ():" một phương thức trừu tượng b "classb (ib):" một lớp mẫu thực hiện ib "def phương thức_b (self): print (" Phương pháp B ") lớp lớp (IA) : "Classb không có phương thức_A, vì vậy chúng ta có thể tạo một bộ điều hợp" def __init __ (self): self.class_b = classb () def phương thức_a (self): "Gọi Lớp B phương thức_B thay vào đó" self.class_b.method_b () # Máy khách # Trước khi bộ điều hợp tôi cần kiểm tra lớp đối tượng để biết phương thức nào để gọi. Các mục = [classa (), classB ()] cho mục trong các mục: nếu isInstance (item, classB): item.method_b () Chữ ký dưới dạng các mục (ưa thích) các mục = [classa (), classBad CHƯƠNG ()] cho mục trong các mục: item.method_a ()

- 80/238 -

6.2.5 đầu ra

6.2.5 Phương pháp phương pháp Phương pháp Python đầu ra

Bản quyền © 2019-2021 Sean Bradley

./ad CHƯƠNG/ad CHƯƠNG_concept.py a b a b

6.2.6 Bộ điều hợp sử dụng trường hợp ID video SBCode #AE7042

Ví dụ khách hàng có thể sản xuất một khối lập phương bằng các công cụ khác nhau. Mỗi giải pháp được phát minh bởi một công ty khác nhau. Giao diện người dùng máy khách quản lý sản phẩm khối bằng cách chỉ ra chiều rộng, chiều cao và độ sâu. Điều này tương thích với công ty A sản xuất công cụ khối, nhưng không phải là công ty B sản xuất phiên bản công cụ Cube của riêng họ sử dụng giao diện khác với các tham số khác nhau. Trong ví dụ này, khách hàng sẽ sử dụng lại giao diện cho khối của công ty A và tạo một khối tương thích từ công ty B. Một bộ chuyển đổi sẽ cần Sửa đổi công cụ khối của họ cho trường hợp sử dụng tên miền cụ thể của chúng tôi. Công ty tưởng tượng của tôi cần sử dụng cả hai nhà cung cấp khối vì có nhu cầu lớn về các khối và khi một nhà cung cấp bận rộn, sau đó tôi có thể hỏi nhà cung cấp khác.

- 81/238 -

6.2.7 Ví dụ Sơ đồ UML

6.2.7 Ví dụ Sơ đồ UML Icubea

IcubeB

+ chiều rộng: int + chiều cao: int + độ sâu: int

+ top_left_front: [int, int, int] + bottom_right_back: [int, int, int] + created (tlf, brb)

6.2.7 Ví dụ Sơ đồ UML

6.2.7 Ví dụ Sơ đồ UML

IcubeB

IcubeB

+ chiều rộng: int + chiều cao: int + độ sâu: int

Classa

Lớp học

Bản quyền © 2019-2021 Sean Bradley

- 82/238 -

6.2.8 Mã nguồn

F "Công ty A Building Cube Id: {id (cube)}," f "{cube.width} x {cube.Height} x {cube.depth}") Counter = Counter "Công ty A đang bận rộn, cố gắng công ty B") Cube = CubeBad CHƯƠNG () Thành công = cube.Man sản xuất (chiều rộng, chiều cao, độ sâu) Nếu thành công: in "{Cube.width} x {cube.Height} x {cube.depth}") Counter = Counter .sleep(1) print(f"{TOTALCUBES} cubes have been manufactured")

. Một biến tĩnh cho biết lần cuối cùng một khối được sản xuất last_time = int (Time.time ()) def __init __ (self): self.width = self.Height = self.depth = 0 def Sản xuất (tự, chiều rộng, chiều cao, độ sâu ). Cubea.last_time = Bây giờ trả về True Return False # Busy

./ad CHƯƠNG/cube_b.py

Bản quyền © 2019-2021 Sean Bradley

- 83/238 -

6.2.8 Mã nguồn

F "Công ty A Building Cube Id: {id (cube)}," f "{cube.width} x {cube.Height} x {cube.depth}") Counter = Counter "Công ty A đang bận rộn, cố gắng công ty B") Cube = CubeBad CHƯƠNG () Thành công = cube.Man sản xuất (chiều rộng, chiều cao, độ sâu) Nếu thành công: in "{Cube.width} x {cube.Height} x {cube.depth}") Counter = Counter .sleep(1) print(f"{TOTALCUBES} cubes have been manufactured")

. Một biến tĩnh cho biết lần cuối cùng một khối được sản xuất last_time = int (Time.time ()) def __init __ (self): self.width = self.Height = self.depth = 0 def Sản xuất (tự, chiều rộng, chiều cao, độ sâu ). Cubea.last_time = Bây giờ trả về True Return False # Busy

./ad CHƯƠNG/cube_b.py

- 83/238 -

# pylint: vô hiệu hóa = phương pháp quá công khai "Một lớp khối từ công ty B" Nhập thời gian từ Interface_Cube_B Nhập lớp IcubeB Class CubeB (IcubeB): "Một công cụ lập phương giả thuyết từ Công ty B" # Một biến tĩnh cho biết lần cuối cùng Một khối đã được sản xuất last_time = int (Time.time ()) def Tạo (self, top_left_front, bottom_right_back): now = int (Time.time ()) nếu bây giờ> int (cubeB.last_time + 2): cubeb.last_time = Bây giờ trả về đúng trả về sai # bận

. Đối với Cubeb thực hiện icubea "def __init __ (self): self.cube = cubeB () self.width = self.Height = self.depth = 0 def Sản xuất hơn 0+độ sâu/2]) Trả lại thành công

./ad CHƯƠNG

- 84/238 -

6.2.9 đầu ra

Từ ABC Nhập ABCMeta, Lớp Tóm tắtMethod ICUBEA (metaclass = abcmeta): "Giao diện cho một đối tượng" @staticmethod @abstractmethod def Sản xuất (chiều rộng, chiều cao, độ sâu): "Sản xuất khối lập phương"

./ad CHƯƠNG def created (top_left_front, bottom_right_back): "Sản xuất một khối lập phương với các chi phối bù [0, 0, 0]" "

Bản quyền © 2019-2021 Sean Bradley

6.2.9 Đầu ra Python ./ad CHƯƠNG 2968196317136, Công ty A đang bận rộn, cố gắng Công ty B B Xây dựng Cube ID: 2968196317136, Công ty A xây dựng ID Cube: 2968196317040, Công ty A đang bận rộn Công ty A đang bận, cố gắng Công ty B Công ty B Xây dựng ID: 2968196317136, 5 khối đã được sản xuất

2x3x7 8x2x8 4x6x4

5x4x8 2x2x9

6.2.10 Khái niệm mã hóa mới Python isInstance () Chức năng SBCode Video ID #AA3328

- 85/238 -

6.2.10 Khái niệm mã hóa mới

Bản quyền © 2019-2021 Sean Bradley

- 86/238 -

6.2.11 Tóm tắt

Trong. Bây giờ = int (Time.time ()) nếu bây giờ> int (cubea.last_time + 1): cubea.last_time = Bây giờ trả về true, tôi cũng sử dụng mô -đun thời gian để ngủ trong một giây giữa các vòng để mô phỏng độ trễ 1 giây. Xem ./ad CHƯƠNG Xây dựng mỗi khối.

6.2.11 Tóm tắt • Sử dụng bộ điều hợp khi bạn muốn sử dụng một lớp hiện có, nhưng giao diện của nó không phù hợp với những gì bạn cần. • Bộ điều hợp điều chỉnh giao diện của lớp cha cho các tình huống đó khi không khả thi để sửa đổi lớp cha là dành riêng cho miền cho trường hợp sử dụng của bạn. • Bộ điều hợp rất có thể sẽ cung cấp một giao diện thay thế so với đối tượng, lớp hoặc giao diện hiện có, nhưng nó cũng có thể cung cấp thêm chức năng mà đối tượng được điều chỉnh có thể chưa cung cấp. • Một bộ chuyển đổi tương tự như một bộ trang trí ngoại trừ nó thay đổi giao diện thành đối tượng, trong khi bộ trang trí thêm trách nhiệm mà không thay đổi giao diện. Điều này cũng cho phép người trang trí được sử dụng đệ quy. • Một bộ chuyển đổi tương tự như mẫu cầu và có thể trông giống hệt nhau sau khi hoàn thành việc tái cấu trúc. Tuy nhiên, mục đích tạo bộ điều hợp là khác nhau. Cây cầu là kết quả của việc tái cấu trúc các giao diện hiện có, trong khi bộ điều hợp là về việc thích nghi trên các giao diện hiện có không khả thi để sửa đổi do nhiều ràng buộc hiện có. Ví dụ: bạn không có quyền truy cập vào mã gốc hoặc nó có thể có các phụ thuộc đã sử dụng nó và sửa đổi nó sẽ ảnh hưởng tiêu cực đến những phụ thuộc đó.

Bản quyền © 2019-2021 Sean Bradley

- 87/238 -

6.3 Mô hình thiết kế mặt tiền

6.3 Mẫu thiết kế mặt tiền 6.3.1 Tổng quan về video SBCode #46770C

Đôi khi bạn có một hệ thống trở nên khá phức tạp theo thời gian khi nhiều tính năng được thêm hoặc sửa đổi. Nó có thể hữu ích để cung cấp một API đơn giản hóa trên nó. Đây là mô hình mặt tiền. Mẫu mặt tiền về cơ bản là một giao diện thay thế, giảm hoặc đơn giản hóa cho một tập hợp các giao diện khác, trừu tượng hóa và triển khai trong một hệ thống có thể đầy đủ phức tạp và/hoặc kết hợp chặt chẽ. Nó cũng có thể được coi là một giao diện cấp cao hơn giúp che chắn cho người tiêu dùng khỏi các biến chứng cấp thấp không cần thiết của việc tích hợp vào nhiều hệ thống con.

6.3.2 Mặt tiền Sơ đồ UML + Phương pháp_A (Loại): Loại + Phương thức_B (Loại): Loại + Phương thức_C (Loại): Loại + Phương thức_D (Loại): Loại + Phương thức_E (Loại): Loại

Khách hàng

Hệ thống con

Hệ thống con

Hệ thống con

+ trường: gõ

+ trường: gõ

+ trường: gõ

+ phương thức_a (loại): loại

+ phương thức_b (loại): loại

+ method_c (type): loại

Hệ thống con

Hệ thống con

+ trường: gõ

+ trường: gõ

+ phương thức_a (loại): loại

+ phương thức_b (loại): loại

+ method_c (type): loại

Bản quyền © 2019-2021 Sean Bradley

Hệ thống con

Hệ thống con

+ phương thức_d (loại): loại

+ phương thức_e (loại): loại

6.3.3 Mã nguồn ./facade/facade_concept.py

- 88/238 -

6.3.3 Mã nguồn

# pylint: vô hiệu hóa = phương pháp quá công khai "Khái niệm mẫu mặt tiền" SubSystemClassa: "một lớp phức tạp giả thuyết" @StaticMethod def (): "Một phương pháp phức tạp giả thuyết" Trả về Phương pháp phức tạp "@staticmethod def (giá trị):" Một phương pháp phức tạp giả thuyết "Giá trị trả về Lớp SubSystemClassc:" Một lớp phức tạp giả thuyết "@StaticMethod def Phương thức (giá trị):" Một mặt tiền đơn giản hóa cung cấp các dịch vụ của các hệ thống con "@staticmethod def sub_system_class_a ():" Sử dụng phương thức hệ thống con "return SubSystemClassa (). Phương thức () @staticmethod def sub_system_class_b (giá trị):" . SystemClassb.method ("b")) in (subsystemClassc.method ({"c": [1, 2, 3]})) # hoặc sử dụng bản in mặt tiền đơn giản (mặt tiền (). 2021 Sean Bradley

- 89/238 -

Bản quyền © 2019-2021 Sean Bradley

- 90/238 -

6.3.6 Sơ đồ uml ví dụ

6.3.6 Ví dụ Sơ đồ UML Gameapi + get_balance (user_id): decimal + game_state (game_id): dict + get_history (): dict + thay đổi_pwd (user_id):

Khách hàng

Báo cáo

- _Balance: thập phân

+ get_history (): dict + log_event (sự kiện): bool

+ get_balance (user_id): thập phân + điều chỉnh_balance (user_id, thập phân): thập phân + created_wallet (user_id): bool

Người dùng - _user_id: str - _user_name: str - _password: str + register_user (dict): int + edit_user (user_id, dict): bool + thay đổi_pwd (user_id, str): bool

GameEngine - _Clock: int - _entries: Dict + Game_State: Dict + Đồng hồ: Int + Mục

6.3.7 Mã nguồn. Ngủ (1) Gameapi.submit_entry (user_id, thập phân ('5')))

Bản quyền © 2019-2021 Sean Bradley

- 91/238 -

6.3.7 Mã nguồn

Time.s ngủ (1) in () in ("---- snapshot gameestate ----") in (gameapi.game_state ()) Time.s ngủ (1) Lịch sử = gameapi.get_history () in () in () "---- Báo cáo lịch sử ----") cho hàng trong lịch sử: in (f "{hàng}: {lịch sử [hàng] [0]}: {history [row] [1]}") print () in ("---- snapshot gamestate ----") in (gameapi.game_state ())

./facade/game_api.py "từ từ từ từ

Trò chơi API mặt tiền "Nhập khẩu thập phân Người dùng thập phân Nhập khẩu ví Nhập ví Game_Engine Nhập GameEngine Báo cáo nhập khẩu

Class gameapi (): "Trò chơi API mặt tiền" @staticmethod def get_balance (user_id: str) -> decimal: "Nhận cân bằng người chơi" ví lại.get_balance (user_id) @staticmethod def game_state () Trò chơi hiện tại "return GameEngine (). : "Thay đổi mật khẩu người dùng" Bản quyền © 2019-2021 Sean Bradley

- 92/238 -

6.3.7 Mã nguồn

Time.s ngủ (1) in () in ("---- snapshot gameestate ----") in (gameapi.game_state ()) Time.s ngủ (1) Lịch sử = gameapi.get_history () in () in () "---- Báo cáo lịch sử ----") cho hàng trong lịch sử: in (f "{hàng}: {lịch sử [hàng] [0]}: {history [row] [1]}") print () in ("---- snapshot gamestate ----") in (gameapi.game_state ())

./facade/game_api.py "từ từ từ từ

Trò chơi API mặt tiền "Nhập khẩu thập phân Người dùng thập phân Nhập khẩu ví Nhập ví Game_Engine Nhập GameEngine Báo cáo nhập khẩu

Class gameapi (): "Trò chơi API mặt tiền" @staticmethod def get_balance (user_id: str) -> decimal: "Nhận cân bằng người chơi" ví lại.get_balance (user_id) @staticmethod def game_state () Trò chơi hiện tại "return GameEngine (). : "Thay đổi mật khẩu người dùng" Bản quyền © 2019-2021 Sean Bradley

- 92/238 -

6.3.7 Mã nguồn

Time.s ngủ (1) in () in ("---- snapshot gameestate ----") in (gameapi.game_state ()) Time.s ngủ (1) Lịch sử = gameapi.get_history () in () in () "---- Báo cáo lịch sử ----") cho hàng trong lịch sử: in (f "{hàng}: {lịch sử [hàng] [0]}: {history [row] [1]}") print () in ("---- snapshot gamestate ----") in (gameapi.game_state ())

./facade/game_api.py "từ từ từ từ

Bản quyền © 2019-2021 Sean Bradley

- 94/238 -

6.3.7 Mã nguồn

) trả về cls._wallets [user_id]

. __New __ (CLS): Trả về CLS @ClassMethod def get_history (CLS) -> DIRT: "Một phương pháp để truy xuất tất cả các sự kiện lịch sử" Trả về CLS._Reports @ClassMethod def log_event (CLS, EVEL: STR) -> BOOL: " Thêm một sự kiện mới vào bản ghi "cls._reports [cls._row_id] = (Time.time (), sự kiện) cls._row_id = cls._row_id + 1 return true

. : list [tuple [str, decimal]] = [] _game_open = true def __new __ (cls): Nếu cls._instance không có:

Bản quyền © 2019-2021 Sean Bradley

- 95/238 -

6.3.8 đầu ra

cls._instance = GameEngine cls._start_time = int (Time.time ()) cls._clock = 60 return cls._instance @ClassMethod def get_game_state (cls) -> Dict: "Nhận một ảnh chụp nhanh về trạng thái trò chơi hiện tại" . : cls._entries} @classmethod def subsit_entry (cls, user_id: str, entry: decimal) -> bool: "Gửi một mục mới cho người dùng trong trò chơi này" now = int (Time.time ()) Time_remaining = CLS. _start_time - bây giờ + cls._clock nếu time_remaining> 0: nếu ví.get_balance (user_id)> thập phân ('1'): nếu ví.adjust_balance (user_id, decimal (' - 1')): cls._entries.append ((((( user_id, entry)) báo cáo.log_event (f "mục nhập mới` {Entry} `Được gửi bởi` {user_id}} ") trả về báo cáo thực.LOG_EVENT (f" Số dư điều chỉnh sự cố cho `{user_id}` ") trả về báo cáo sai. log_event (f "số dư người dùng cho` {user_id} `xuống thấp") trả về giả mạo e báo cáo.log_event ("trò chơi đóng") trả về sai

6.3.8 Python đầu ra. )]} ---- Báo cáo Lịch sử --- 0: 1614087127.327007: Người dùng mới `Sean` đã tạo Bản quyền © 2019-2021 Sean Bradley

- 96/238 -

6.3.9 Khái niệm mã hóa mới

1 2 3 4 5 6

:::::

1614087127.327007: Ví cho `Sean` được tạo và đặt thành 0 1614087127.327007: Cung cấp cho người dùng mới` Sean` Đăng ký tiền thưởng của 10 1614087127.327007: Điều chỉnh số dư cho `Sean`. Cân bằng mới = 10 1614087128.3278701: Kiểm tra số dư cho `Sean` = 10 1614087128.3278701: Điều chỉnh cân bằng cho` Sean`. New Balance = 9 1614087128.3278701: Mục nhập mới `5` Được gửi bởi` Sean`

---- Snapshot Gamestate --- {'Đồng hồ': 58, 'Game_open': Đúng, 'Mục nhập': [('Sean', Decimal ('5'))]}

6.3.9 Khái niệm mã hóa mới Mô -đun thập phân SBCode ID #F46FDD

Mô-đun thập phân cung cấp hỗ trợ cho số học dấu phẩy động thập phân chính xác. Nếu đại diện cho các giá trị tiền trong Python, tốt hơn là sử dụng loại thập phân hơn là nổi. Phao sẽ có lỗi làm tròn so với thập phân. Từ nhập khẩu thập phân in thập phân (1.1 + 2.2) # Thêm bản in phao (thập phân ('1.1') + thập phân ('2.2')) . Tuy nhiên, hãy lưu ý rằng khi tạo số thập phân, hãy chắc chắn vượt qua trong một biểu diễn chuỗi, nếu không nó sẽ tạo ra một số thập phân từ một chiếc phao. từ nhập khẩu thập phân * in (thập phân (1.1)) # thập phân từ in float (thập phân ('1.1'))

Bản quyền © 2019-2021 Sean Bradley

- 97/238 -

6.3.9 Khái niệm mã hóa mới

1 2 3 4 5 6

:::::

1614087127.327007: Ví cho `Sean` được tạo và đặt thành 0 1614087127.327007: Cung cấp cho người dùng mới` Sean` Đăng ký tiền thưởng của 10 1614087127.327007: Điều chỉnh số dư cho `Sean`. Cân bằng mới = 10 1614087128.3278701: Kiểm tra số dư cho `Sean` = 10 1614087128.3278701: Điều chỉnh cân bằng cho` Sean`. New Balance = 9 1614087128.3278701: Mục nhập mới `5` Được gửi bởi` Sean`

Bản quyền © 2019-2021 Sean Bradley

- 98/238 -

6.3.10 Tóm tắt

Để kiểm tra loại, bạn có thể cài đặt một mô -đun bổ sung có tên mypy pip cài đặt mypy và sau đó chạy nó đối với mã của bạn, mypy ./facade/client.py thành công: Không có vấn đề nào được tìm thấy trong 1 tệp nguồn myPy cũng sẽ kiểm tra bất kỳ mô -đun nhập khẩu nào cùng nhau thời gian. Nếu làm việc với tiền, thì nên thêm kiểm tra thêm vào mã của bạn. Kiểm tra việc sử dụng loại đó phù hợp trong suốt mã của bạn, đặc biệt là khi sử dụng số thập phân, là một ý tưởng tốt sẽ làm cho mã của bạn mạnh mẽ hơn. Ví dụ: nếu tôi không nhất quán trong việc sử dụng số thập phân trong suốt mã của mình, thì tôi sẽ thấy một cảnh báo được tô sáng. Mypy. dự kiến ​​"tuple [str, decimal]" facade/game_api.py: 34: Lỗi: Đối số 2 thành "subform_entry" của "gameEngine" có loại "thập phân" không tương thích; Dự kiến ​​"Int" đã tìm thấy 2 lỗi trong 2 tệp (đã kiểm tra 1 tệp nguồn)

6.3.10 Tóm tắt • Sử dụng khi bạn muốn cung cấp một giao diện đơn giản cho một hệ thống con phức tạp. • Bạn muốn lớp các hệ thống con của mình thành một sự trừu tượng dễ hiểu hơn. • Nhà máy trừu tượng và mặt tiền có thể được coi là rất giống nhau. Một nhà máy trừu tượng là về việc tạo ra giao diện trên một số lớp sáng tạo của các đối tượng tương tự, trong khi mặt tiền giống như một lớp API trên nhiều mô hình sáng tạo, cấu trúc và/hoặc hành vi. • Người hòa giải tương tự như mặt tiền theo cách mà nó trừu tượng hóa các lớp hiện có. Mặt tiền không nhằm mục đích sửa đổi, tải cân bằng hoặc áp dụng bất kỳ logic bổ sung nào. Một hệ thống con không cần phải xem xét sự tồn tại của mặt tiền, nó vẫn sẽ hoạt động mà không có nó. • Mặt tiền là giao diện tối thiểu cũng có thể được thực hiện dưới dạng đơn lẻ. • Mặt tiền là một lớp tùy chọn không làm thay đổi hệ thống con. Hệ thống con không cần phải biết về mặt tiền, và thậm chí có thể được sử dụng bởi nhiều mặt tiền khác được tạo ra cho các đối tượng khác nhau.

Bản quyền © 2019-2021 Sean Bradley

- 99/238 -

6.4 Mô hình thiết kế cầu

6.4 Mẫu thiết kế cầu 6.4.1 Tổng quan về video SBCode #83202D

Mẫu cầu tương tự như mẫu bộ điều hợp ngoại trừ trong ý định mà bạn đã phát triển nó. Cây cầu là một cách tiếp cận để tái cấu trúc mã hiện có, trong khi bộ điều hợp tạo ra một giao diện trên đầu mã hiện có thông qua các phương tiện có sẵn hiện có mà không tái cấu trúc bất kỳ mã hoặc giao diện hiện có nào. Động lực để chuyển đổi mã của bạn thành mẫu cầu là nó có thể được ghép nối chặt chẽ. Có logic và sự trừu tượng gần nhau là giới hạn các lựa chọn của bạn trong cách bạn có thể mở rộng giải pháp của mình theo cách bạn cần. Ví dụ: bạn có thể có một lớp xe, tạo ra một chiếc xe rất đẹp. Nhưng bạn muốn tùy chọn thay đổi thiết kế một chút, hoặc thuê ngoài trách nhiệm tạo ra các thành phần khác nhau. Mẫu cầu là một quá trình về việc tách sự trừu tượng và thực hiện, vì vậy điều này sẽ cung cấp cho bạn nhiều cách sử dụng các lớp học mới. Xe = car () in (xe)> xe có bánh xe và động cơ và cửa sổ và mọi thứ khác. Nhưng bạn muốn ủy thác động cơ một cách linh hoạt từ một tập hợp các lớp hoặc giải pháp riêng biệt. Động cơ = enginea () car = car (enginea) Một cây cầu không tồn tại trước đó, nhưng vì sau khi tách giao diện và logic, mỗi bên có thể được mở rộng độc lập với nhau. Ngoài ra, việc áp dụng một cây cầu trong mã của bạn nên sử dụng thành phần thay vì kế thừa. Điều này có nghĩa là bạn chỉ định mối quan hệ trong thời gian chạy, thay vì mã hóa cứng trong định nghĩa lớp. Tức là, xe = xe (enginea) chứ không phải xe hơi (Enginea): Việc triển khai cây cầu thường sẽ sạch hơn một giải pháp bộ chuyển đổi đã được bắt vít. Vì nó liên quan đến việc tái cấu trúc mã hiện có, thay vì xếp lớp trên các giải pháp kế thừa hoặc bên thứ ba mà có thể không dành cho trường hợp sử dụng cụ thể của bạn. Bạn là nhà thiết kế của cây cầu, nhưng cả hai cách tiếp cận vấn đề có thể hoạt động bất kể.

Bản quyền © 2019-2021 Sean Bradley

- 100/238 -

6.4.2 Thuật ngữ

Phần người thực hiện của một cây cầu, có thể có một hoặc nhiều triển khai có thể cho mỗi lần trừu tượng hóa tinh tế. Ví dụ: người triển khai có thể in lên giấy hoặc màn hình hoặc định dạng cho trình duyệt web. Và phía trừu tượng có thể cho phép nhiều hoán vị của mọi hình dạng mà bạn có thể tưởng tượng.

6.4.2 Thuật ngữ • Giao diện trừu tượng: Một giao diện được thực hiện bởi sự trừu tượng hóa tinh tế mô tả các phương pháp phổ biến để thực hiện. • Tóm tắt tinh tế: Một sự tinh chỉnh của một ý tưởng vào một hoặc hai lớp khác. Các lớp nên thực hiện giao diện trừu tượng và gán người thực hiện cụ thể. • Giao diện người thực hiện: Giao diện người thực hiện mà người triển khai cụ thể thực hiện. • Người thực hiện cụ thể: Logic thực hiện mà sự trừu tượng hóa tinh tế sẽ sử dụng.

6.4.3 Sơ đồ UML tinh chế

ConcreteImplementera + Phương thức (loại): Loại

IABStraction

Iimplementers

+ phương pháp (loại): loại

+ phương pháp (loại): loại

Ứng dụng khách hàng

RefinedAbstractionB + Trình triển khai: Loại + Phương thức (Loại): Loại

ConcreteImplementerB + Phương thức (loại): Loại

6.4.4 Mã nguồn trong mã trình diễn khái niệm, hãy tưởng tượng rằng các lớp được ghép nối chặt chẽ. Lớp cụ thể sẽ in ra một số văn bản vào bảng điều khiển. Sau khi trừu tượng hóa lớp học dọc theo một điểm chung, bây giờ nó linh hoạt hơn. Việc thực hiện và đã được tách ra khỏi sự trừu tượng và bây giờ nó có thể in ra cùng một văn bản theo hai cách khác nhau. BEFIT bây giờ là mỗi sự trừu tượng hóa và người thực hiện tinh tế giờ đây có thể được làm việc độc lập mà không ảnh hưởng đến các triển khai khác.

Bản quyền © 2019-2021 Sean Bradley

- 101/238 -

6.4.4 Mã nguồn

. Phương thức ( *args): "Phương pháp xử lý" lớp tinh chỉnh Phương thức (*args) Lớp RefinedabStractionB (IABStraction): "Một bản tóm tắt tinh tế" def __init __ (self, người thực hiện) Iimplementers (metaclass = abcmeta): "Giao diện người thực hiện" @staticmethod @abstractmethod def (*args: tuple) -> none: "Phương thức triển khai" Lớp ConcreteImplementera (iimplementer): " args: tuple) -> none: print (args) lớp bê tông người cố vấn "

Bản quyền © 2019-2021 Sean Bradley

- 101/238 -

6.4.4 Mã nguồn

. Phương thức ( *args): "Phương pháp xử lý" lớp tinh chỉnh Phương thức (*args) Lớp RefinedabStractionB (IABStraction): "Một bản tóm tắt tinh tế" def __init __ (self, người thực hiện) Iimplementers (metaclass = abcmeta): "Giao diện người thực hiện" @staticmethod @abstractmethod def (*args: tuple) -> none: "Phương thức triển khai" Lớp ConcreteImplementera (iimplementer): " args: tuple) -> none: print (args) lớp bê tông người cố vấn "

- 102/238 -

6.4.5 đầu ra

@StaticMethod def Phương thức (*args: tuple) -> none: for arg in args: print (arg) # máy khách refined_abstraction_a = refinedabstractiona (bê tông RefinedAbstractionB (ConcreteImplementerB) ablined_abstraction_b.method ('A', 'B', 'C'))

Bản quyền © 2019-2021 Sean Bradley

- 101/238 -

6.4.4 Mã nguồn

. Phương thức ( *args): "Phương pháp xử lý" lớp tinh chỉnh Phương thức (*args) Lớp RefinedabStractionB (IABStraction): "Một bản tóm tắt tinh tế" def __init __ (self, người thực hiện) Iimplementers (metaclass = abcmeta): "Giao diện người thực hiện" @staticmethod @abstractmethod def (*args: tuple) -> none: "Phương thức triển khai" Lớp ConcreteImplementera (iimplementer): " args: tuple) -> none: print (args) lớp bê tông người cố vấn "

- 102/238 -

6.4.5 đầu ra

@StaticMethod def Phương thức (*args: tuple) -> none: for arg in args: print (arg) # máy khách refined_abstraction_a = refinedabstractiona (bê tông RefinedAbstractionB (ConcreteImplementerB) ablined_abstraction_b.method ('A', 'B', 'C'))

6.4.5 Đầu ra Python ./bridge/bridge_concept.py ('A', 'B', 'C')

6.4.6 sử dụng cây cầu ID video SBCode #96A335

Trong ví dụ này, tôi vẽ một hình vuông và một vòng tròn. Cả hai đều có thể được phân loại là hình dạng. Hình dạng được thiết lập như giao diện trừu tượng. Các trừu tượng tinh tế, hình vuông và vòng tròn, thực hiện giao diện iShape. Khi các đối tượng hình vuông và vòng tròn được tạo, chúng cũng được gán cho người thực hiện phù hợp là SquareMplementer và CircleImplementer. Khi mỗi phương thức vẽ của hình dạng được gọi, phương thức tương đương trong người thực hiện của họ được gọi. Quảng trường và vòng tròn được bắc cầu và mỗi người thực hiện và trừu tượng có thể được làm việc độc lập.

- 103/238 -

@StaticMethod def Phương thức (*args: tuple) -> none: for arg in args: print (arg) # máy khách refined_abstraction_a = refinedabstractiona (bê tông RefinedAbstractionB (ConcreteImplementerB) ablined_abstraction_b.method ('A', 'B', 'C'))

6.4.5 Đầu ra Python ./bridge/bridge_concept.py ('A', 'B', 'C')

6.4.6 sử dụng cây cầu ID video SBCode #96A335

Trong ví dụ này, tôi vẽ một hình vuông và một vòng tròn. Cả hai đều có thể được phân loại là hình dạng. Hình dạng được thiết lập như giao diện trừu tượng. Các trừu tượng tinh tế, hình vuông và vòng tròn, thực hiện giao diện iShape. Khi các đối tượng hình vuông và vòng tròn được tạo, chúng cũng được gán cho người thực hiện phù hợp là SquareMplementer và CircleImplementer. Khi mỗi phương thức vẽ của hình dạng được gọi, phương thức tương đương trong người thực hiện của họ được gọi. Quảng trường và vòng tròn được bắc cầu và mỗi người thực hiện và trừu tượng có thể được làm việc độc lập.

@StaticMethod def Phương thức (*args: tuple) -> none: for arg in args: print (arg) # máy khách refined_abstraction_a = refinedabstractiona (bê tông RefinedAbstractionB (ConcreteImplementerB) ablined_abstraction_b.method ('A', 'B', 'C'))

6.4.5 Đầu ra Python ./bridge/bridge_concept.py ('A', 'B', 'C')

6.4.6 sử dụng cây cầu ID video SBCode #96A335

Trong ví dụ này, tôi vẽ một hình vuông và một vòng tròn. Cả hai đều có thể được phân loại là hình dạng. Hình dạng được thiết lập như giao diện trừu tượng. Các trừu tượng tinh tế, hình vuông và vòng tròn, thực hiện giao diện iShape. Khi các đối tượng hình vuông và vòng tròn được tạo, chúng cũng được gán cho người thực hiện phù hợp là SquareMplementer và CircleImplementer. Khi mỗi phương thức vẽ của hình dạng được gọi, phương thức tương đương trong người thực hiện của họ được gọi. Quảng trường và vòng tròn được bắc cầu và mỗi người thực hiện và trừu tượng có thể được làm việc độc lập.

- 103/238 -

Bản quyền © 2019-2021 Sean Bradley

- 101/238 -

6.4.4 Mã nguồn

. Phương thức ( *args): "Phương pháp xử lý" lớp tinh chỉnh Phương thức (*args) Lớp RefinedabStractionB (IABStraction): "Một bản tóm tắt tinh tế" def __init __ (self, người thực hiện) Iimplementers (metaclass = abcmeta): "Giao diện người thực hiện" @staticmethod @abstractmethod def (*args: tuple) -> none: "Phương thức triển khai" Lớp ConcreteImplementera (iimplementer): " args: tuple) -> none: print (args) lớp bê tông người cố vấn "

- 102/238 -

6.4.5 đầu ra

Bản quyền © 2019-2021 Sean Bradley

- 105/238 -

6.4.9 Đầu ra

. self.Mplementer = expender () def Draw (self): self.implementer.draw_implementation ()

./bridge/interface_shape_implementer.py # pylint: vô hiệu hóa = Too-few-public-methods "Giao diện người triển khai hình dạng" từ ABC Nhập ABCMETA, Lớp Tóm tắtMethod IshapeImplementer (Metaclass = ABCMETA): " ): "Phương pháp mà các bản tóm tắt tinh tế sẽ thực hiện"

. Draw (): "Phương pháp sẽ được xử lý tại người thực hiện hình dạng"

6.4.9 Đầu ra

Bản quyền © 2019-2021 Sean Bradley

. self.Mplementer = expender () def Draw (self): self.implementer.draw_implementation ()

./bridge/interface_shape_implementer.py # pylint: vô hiệu hóa = Too-few-public-methods "Giao diện người triển khai hình dạng" từ ABC Nhập ABCMETA, Lớp Tóm tắtMethod IshapeImplementer (Metaclass = ABCMETA): " ): "Phương pháp mà các bản tóm tắt tinh tế sẽ thực hiện"

. Draw (): "Phương pháp sẽ được xử lý tại người thực hiện hình dạng"

- 106/238 -

6.4.10 Khái niệm mã hóa mới

Python ./bridge/client.py ****** ** ************* ** ****** ************** ****************************

Bản quyền © 2019-2021 Sean Bradley

6.4.10 Khái niệm mã hóa mới đối số *Args. ID video sbcode #c979fc

Đối số *Args có tất cả các đối số đã được gửi đến phương thức này và gói chúng thành một tuple. Nó rất hữu ích khi bạn không biết có bao nhiêu đối số, hoặc loại nào, sẽ được gửi đến một phương thức và bạn muốn phương thức hỗ trợ bất kỳ số lượng đối số hoặc loại được gửi đến nó. Nếu bạn muốn phương thức của mình nghiêm ngặt về các loại mà nó có thể chấp nhận, thì tập hợp cụ thể để chấp nhận danh sách, từ điển, đặt hoặc tuple và xử lý đối số như vậy trong phần thân phương thức, nhưng

*Đối số Args là một lựa chọn phổ biến khác mà bạn sẽ thấy trong mã nguồn trên internet. Ví dụ: khi sử dụng *args trong chữ ký phương thức của bạn, bạn có thể gọi nó với bất kỳ số lượng đối số nào thuộc bất kỳ loại nào. def my_method (*args): for arg in args: print (arg) my_method (1, 22, [3], {4})

- 107/238 -

6.4.11 Tóm tắt

1 22 [3] {4}

Python tuple sbcode video id #cf5cc0

Bản quyền © 2019-2021 Sean Bradley

Một tuple python tương tự như một danh sách. Ngoại trừ các mục trong tuple được đặt hàng, không thể thay đổi và cho phép trùng lặp. Một tuple có thể được khởi tạo bằng cách sử dụng dấu ngoặc tròn () hoặc tuple (), câu [] cho một danh sách và

{} cho một tập hợp hoặc từ điển. PS> Python >>> Các mặt hàng = ("Alpha", "Bravo", "Charlie", "Alpha") >>> in (mục) ('Alpha', 'Bravo', 'Charlie', 'Alpha')>> >> In (Len (vật phẩm)) 4

6.4.11 Tóm tắt • Sử dụng khi bạn muốn tách một giải pháp trong đó sự trừu tượng và thực hiện có thể được ghép nối chặt chẽ và bạn muốn chia nó thành các phần khái niệm nhỏ hơn. • Khi bạn đã thêm sự trừu tượng của cây cầu, bạn sẽ có thể mở rộng từng bên của nó một cách riêng biệt mà không phá vỡ bên kia. • Ngoài ra, một khi sự trừu tượng của cây cầu tồn tại, bạn có thể dễ dàng tạo ra các triển khai cụ thể thêm cho các sản phẩm tương tự khác cũng có thể được phân chia trên các dòng khái niệm tương tự. • Mẫu cầu tương tự như mẫu bộ điều hợp ngoại trừ trong ý định mà bạn đã phát triển nó. Cây cầu là một cách tiếp cận để tái cấu trúc mã hiện có, trong khi bộ điều hợp thích nghi với mã hiện có thông qua các giao diện và phương thức hiện có mà không thay đổi nội bộ.

- 108/238 -

6.5 Mẫu thiết kế tổng hợp

Bản quyền © 2019-2021 Sean Bradley

- 109/238 -

6.5.3 Sơ đồ UML tổng hợp

6.5.3 Sơ đồ UML tổng hợp Icomponent + tham chiếu_TO_PARENT: Loại

Ứng dụng khách hàng

+ Phương thức (loại): loại + tách ra (loại): Loại

Lá cây

Tổng hợp

+ tham chiếu_to_parent: gõ

+ Các thành phần: Danh sách + Tham chiếu_TO_PARENT: Loại

+ Phương thức (loại): loại + tách ra (loại): Loại

Lá cây

Tổng hợp

+ tham chiếu_to_parent: gõ

+ Các thành phần: Danh sách + Tham chiếu_TO_PARENT: Loại

Bản quyền © 2019-2021 Sean Bradley

+ phương pháp (loại): loại + đính kèm (loại): loại + tách ra (loại): loại + xóa (loại): loại

6.5.4 Mã nguồn Trong mã khái niệm này, hai lá được tạo, Leaf_A và Leaf_B và hai vật liệu tổng hợp được tạo, composite_1 và composite_2.

Leaf_a được gắn vào composite_1. Sau đó, tôi thay đổi suy nghĩ của mình và gắn lá_a thành composite_2. Sau đó tôi đính kèm composite_1 vào composite_2.

Bản quyền © 2019-2021 Sean Bradley

Leaf_b không được gắn vào vật liệu tổng hợp. .

- 110/238 -

6.5.4 Mã nguồn

@staticmethod @abstractmethod def phương thức (): "Một phương thức mỗi thùng chứa lá và composite nên thực hiện" @staticmethod @abstractmethod def Det được thêm vào một composite, nhưng không phải là một lá "Phương thức def (self): Parent_id = (id (self.reference_to_parent) nếu self.reference_to_parent không phải là không có) in (f" \ t \ tid: {id (self) } \ tparent: \ t {Parent_id} ") def tách (self):" tách chiếc lá này khỏi tổng hợp cha mẹ của nó "nếu self.reference_to_parent không phải là không composite có thể chứa lá và vật liệu tổng hợp "def __init __ (self): self.components = [] phương thức def (self): Parent_id = (id (self.reference_to_parent) nếu self.reference_to_parent không phải là không có) : {id (self)} \ tparent: \ t {Parent_id} \ t "f" Các thành phần: {len (self.components)} ") cho thành phần trong bản thân. ): "" "Lá tách rời/ tổng hợp từ bất kỳ tham chiếu cha mẹ hiện tại nào và sau đó đặt tham chiếu cha mẹ vào thành phần tổng hợp này (self) "" ""

- 111/238 -

6.5.5 đầu ra

DEF DELETE (tự, thành phần): "Loại bỏ lá/composite khỏi bản thân composite này. : self.reference_to_parent.delete (self) self.reference_to_parent = none # máy khách LEAP_A = LEAF () LEAT_B = LEAF () composite_1 = composite () composite_2 = composite () Leaf_a)} ") in (f" Leaf_b \ t \ tid: {id (Leaf_b)} ") in (f" composite_1 \ tid: {id (composite_1)} ") Composite_2)} ") Trong bất kỳ vật liệu tổng hợp nào composite_2.method () # composite_2 chứa cả composite_1 và Leaf_a

Bản quyền © 2019-2021 Sean Bradley

6.5.5 Đầu ra Python.

ID: 2050574298848 ID: 2050574298656 ID: 2050574298272 ID: 2050574298128

ID: 2050574298656 ID: 2050574298128 ID: 2050574298848

Cha mẹ: Không cha mẹ: Không có thành phần: 2 Cha mẹ: 2050574298128

- 112/238 -

6.5.6 Trường hợp sử dụng tổng hợp

Thành phần: 0

ID: 2050574298272

Ứng dụng khách hàng

+ Phương thức (loại): loại + tách ra (loại): Loại

Lá cây

Tổng hợp

+ tham chiếu_to_parent: gõ

+ Các thành phần: Danh sách + Tham chiếu_TO_PARENT: Loại

+ Phương thức (loại): loại + tách ra (loại): Loại

Lá cây

Tổng hợp

Bản quyền © 2019-2021 Sean Bradley

+ tham chiếu_to_parent: gõ

+ Các thành phần: Danh sách + Tham chiếu_TO_PARENT: Loại

+ phương pháp (loại): loại + đính kèm (loại): loại + tách ra (loại): loại + xóa (loại): loại

.

Tệp lớp (iComponent): "Lớp tệp. Các tệp là lá" def __init __ (self, name): self.name = name def Dir (self, indit không phải là không ai khác) in (f "{thụt lề} {self.name} \ t \ t" f "id: {id (self)} \ tparent: \ t {Parent_id}") def Det (self): " Tách tệp này (lá) khỏi tổng hợp cha mẹ của nó "nếu self.reference_to_parent không phải là không: self.reference_to_parent.delete (self)

./composite/Folder.py

Bản quyền © 2019-2021 Sean Bradley

- 114/238 -

6.5.8 Mã nguồn

"Một thư mục, hoạt động như một hỗn hợp." Từ Interface_Component Nhập icomponent

Thư mục lớp (iComponent): "Lớp thư mục có thể chứa các thư mục và tệp khác" def __init __ (self, name): self.name = name self.components = [] def Dir (self, indent = "") "{thụt lề} {self.name} \ t \ tid: {id (self)} \ t" f "các thành phần: {len (self.components)}") "." .Append (Thành phần) DEF DELETE (Self, Thành phần): "" "Xóa tệp/thư mục khỏi thư mục này để bản thân. Thư mục này từ thư mục chính của nó "Nếu self.reference_to_parent không phải là không: self.reference_to_parent.delete (self) self.reference

.

Bản quyền © 2019-2021 Sean Bradley

- 114/238 -

6.5.8 Mã nguồn

"Một thư mục, hoạt động như một hỗn hợp." Từ Interface_Component Nhập icomponent

Thư mục lớp (iComponent): "Lớp thư mục có thể chứa các thư mục và tệp khác" def __init __ (self, name): self.name = name self.components = [] def Dir (self, indent = "") "{thụt lề} {self.name} \ t \ tid: {id (self)} \ t" f "các thành phần: {len (self.components)}") "." .Append (Thành phần) DEF DELETE (Self, Thành phần): "" "Xóa tệp/thư mục khỏi thư mục này để bản thân. Thư mục này từ thư mục chính của nó "Nếu self.reference_to_parent không phải là không: self.reference_to_parent.delete (self) self.reference

.

- 115/238 -

6.5.9 đầu ra

Từ ABC Nhập ABCMETA, Tóm tắtMethod

lớp iComponent (metaclass = abcmeta): "Giao diện thành phần" tham chiếu_to_parent = none @staticmethod @abstractmethod def dir (thụt lề): "một phương thức mỗi lá và thùng chứa tổng hợp sẽ triển khai" @staticmethod @abstractmethod def (): "" Trước khi một chiếc lá được gắn vào một composite để nó có thể làm sạch bất kỳ tài liệu tham khảo cha mẹ nào "" "

6.5.9 Đầu ra Python. thư mục_b ID: 2028913433184 .... 456.TXT ID: 2028913434432

Các thành phần: 4 Cha mẹ: 202891333984 Phụ huynh: 202891333984 Thành phần: 1 Phụ huynh: 2028913432848 Thành phần: 1 Phụ huynh: 2028913433184

root .. abc.txt .. 123.txt .. thư mục_b .... 456.txt .... thư mục_a ...... xyz.txt

Các thành phần: 3 Phụ huynh: 202891333984 Phụ huynh: 202891333984 Thành phần: 2 Phụ huynh: 2028913433184 Thành phần: 1 Phụ huynh: 2028913432848

ID: 202891333984 ID: 2028913333888 ID: 202891333792 ID: 2028913433184 ID: 202891343432 ID: 2028913432848 ID: 202891343432

6.5.10 Khái niệm mã hóa mới Biểu thức có điều kiện (toán tử ternary). ID video sbcode #12b2b0

Trong. Bản quyền © 2019-2021 Sean Bradley

- 116/238 -

6.5.11 Tóm tắt

6.6 Mẫu thiết kế Flykweight 6.6.1 Tổng quan về video SBCode #98A1C6

Bay trong thuật ngữ Fly weight có nghĩa là nhẹ/không nặng. Thay vì tạo hàng ngàn đối tượng chia sẻ các thuộc tính chung và dẫn đến tình huống sử dụng một lượng lớn bộ nhớ hoặc các tài nguyên khác, bạn có thể sửa đổi các lớp của mình để chia sẻ đồng thời nhiều trường hợp bằng cách sử dụng một số loại tham chiếu đến đối tượng được chia sẻ thay thế. Ví dụ tốt nhất để mô tả đây là một tài liệu chứa nhiều từ và câu và được tạo thành từ nhiều chữ cái. Thay vì lưu trữ một đối tượng mới cho mỗi chữ cái riêng lẻ mô tả phông chữ, vị trí, màu sắc, phần đệm và nhiều thứ tiềm năng khác của nó. Bạn có thể chỉ lưu trữ một ID tra cứu của một ký tự trong một bộ sưu tập nào đó và sau đó tạo tự động tạo đối tượng với định dạng thích hợp của nó, v.v., chỉ khi bạn cần. Cách tiếp cận này tiết kiệm rất nhiều bộ nhớ với chi phí sử dụng một số CPU bổ sung thay vào đó để tạo đối tượng tại thời điểm trình bày. Mẫu Flykg, mô tả cách bạn có thể chia sẻ các đối tượng thay vì tạo hàng ngàn đối tượng gần như lặp đi lặp lại một cách không cần thiết. Một trọng lượng hoạt động như một đối tượng độc lập trong bất kỳ số lượng bối cảnh nào. Một bối cảnh có thể là một ô trong bảng hoặc div trên trang HTML. Một bối cảnh đang sử dụng trọng lượng. Bạn có thể có nhiều bối cảnh và khi họ yêu cầu một trọng lượng, họ sẽ nhận được một đối tượng có thể đã được chia sẻ giữa các bối cảnh khác hoặc đã tự mình ở một nơi khác. Khi mô tả các đối thủ, rất hữu ích khi mô tả nó về các thuộc tính nội tại và bên ngoài. Nội tại (trong hoặc bao gồm) là các thuộc tính của một trọng lượng là nội bộ và duy nhất từ ​​các đối thủ khác. Ví dụ: một trọng lượng mới cho mỗi chữ cái của bảng chữ cái. Mỗi chữ cái là nội tại cho trọng lượng. Bên ngoài (bên ngoài hoặc bên ngoài) là các thuộc tính được sử dụng để trình bày trọng lượng về mặt ngữ cảnh mà nó sẽ được sử dụng. Ví dụ: nhiều chữ cái trong một chuỗi có thể được căn chỉnh với nhau. Thuộc tính bên ngoài của mỗi chữ cái là định vị mới của X và Y trên lưới.

6.6.2 Thuật ngữ • Giao diện Flykg: Một giao diện trong đó một trọng lượng nhận được các thuộc tính bên ngoài của nó. • Bêlơu điểm: Đối tượng Flyk cân lưu trữ các thuộc tính nội tại và thực hiện giao diện để áp dụng các thuộc tính bên ngoài.

Bản quyền © 2019-2021 Sean Bradley

- 118/238 -

6.6.3 Sơ đồ UML Fly Weight

• Các máy bay không được chia sẻ: Không phải tất cả các máy bay sẽ được chia sẻ, Flykg cho phép chia sẻ, không thực thi nó. Cũng có thể các đối thủ có thể chia sẻ các đối thủ khác nhưng vẫn chưa được sử dụng trong bất kỳ bối cảnh nào ở bất cứ đâu. • Nhà máy Flykg: Tạo và quản lý các máy bay trong thời gian chạy. Nó tái sử dụng các đối thủ trong bộ nhớ, hoặc tạo ra một nhu cầu mới. • Khách hàng: Ứng dụng máy khách sử dụng và tạo trọng lượng.

6.6.3 Sơ đồ UML của Fly Weight Ifly weight + Trường: Loại

Ứng dụng khách hàng

+ phương pháp (loại): loại

Định nghĩa bài văn

Fly Weightfactory

Trọng lượng bay

+ trường: gõ

+ trường: gõ

+ trường: gõ

+ phương pháp (loại): loại

Định nghĩa bài văn

+ phương pháp (loại): loại

Định nghĩa bài văn

Fly Weightfactory

Bản quyền © 2019-2021 Sean Bradley

- 118/238 -

6.6.3 Sơ đồ UML Fly Weight

• Các máy bay không được chia sẻ: Không phải tất cả các máy bay sẽ được chia sẻ, Flykg cho phép chia sẻ, không thực thi nó. Cũng có thể các đối thủ có thể chia sẻ các đối thủ khác nhưng vẫn chưa được sử dụng trong bất kỳ bối cảnh nào ở bất cứ đâu. • Nhà máy Flykg: Tạo và quản lý các máy bay trong thời gian chạy. Nó tái sử dụng các đối thủ trong bộ nhớ, hoặc tạo ra một nhu cầu mới. • Khách hàng: Ứng dụng máy khách sử dụng và tạo trọng lượng.

6.6.5 đầu ra

Bản quyền © 2019-2021 Sean Bradley

- 120/238 -

6.6.6 Trường hợp sử dụng hạng nặng

Python ./fly weight/fly weight_concept.py Abracadabra Abracadabra có 11 chữ cái Fly WeightFactory có 5 Flykights

6.6.6 Fly Weight sử dụng trường hợp SBCode Video ID #D9FFBD

Trong ví dụ này, tôi tạo một bảng động với 3 hàng và 3 cột mỗi bảng. Các cột sau đó được lấp đầy với một số loại văn bản, và cũng được chọn để được để lại, phải hoặc trung tâm được căn chỉnh. Các chữ cái là các đối thủ và chỉ một mã chỉ ra chữ được lưu trữ. Các chữ cái và số được chia sẻ nhiều lần. Các cột là các bối cảnh và chúng vượt qua các van bên ngoài mô tả sự kết hợp của các chữ cái, biện minh bên trái, phải hoặc trung tâm và chiều rộng của cột bảng sau đó được sử dụng cho phần đệm không gian.

6.6.7 Ví dụ Sơ đồ UML Ứng dụng máy khách Fly Weight

Fly WeightFactory - _fly Weights: Dict

+ mã: int

+ get_fly weight (mã): Fly weight

Bảng cột

Hàng ngang

+ hàng: danh sách

+ cột: Danh sách

+ Draw ()

+ get_data (): str

+ Dữ liệu: str + chiều rộng: int + justify: int + get_data (): str

6.6.8 Mã nguồn.

Bản quyền © 2019-2021 Sean Bradley

- 121/238 -

6.6.8 Mã nguồn

Bảng.Rows [0] .Columns [0] .Data Table.Rows [0] .Columns [1] .Data Table.Rows [0] .Columns [2] .Data Bảng.Rows [1] .Columns [0] .Data Bảng.Rows [1] .Columns [1] .Data Bảng.Rows [1] .Columns [2] .Data Bảng.Rows [2] .Columns [0]. 1] .Data Bảng.Rows [2] .Columns [2] .Data

= = = = = = = = =

"Abra" "112233" "Cadabra" "Racadab" "12345" "332211" "Cadabra" "445566" "AA 22 BB"

Bảng.Rows [0] .Columns [0] .Justify Table.Rows [1] .Columns [0]. .Justify Bảng.Rows [1] .Columns [2]. .

= 1 = 1 = 1 = 2 = 2 = 2 15 15 15

Bảng.Draw () in (f "Fly WeightFactory có {flyweightfactory.get_count ()} Flyweights")

. , mã: int) -> none: self.code = mã

. CLS

Bản quyền © 2019-2021 Sean Bradley

- 122/238 -

6.6.8 Mã nguồn

Bảng.Rows [0] .Columns [0] .Data Table.Rows [0] .Columns [1] .Data Table.Rows [0] .Columns [2] .Data Bảng.Rows [1] .Columns [0] .Data Bảng.Rows [1] .Columns [1] .Data Bảng.Rows [1] .Columns [2] .Data Bảng.Rows [2] .Columns [0]. 1] .Data Bảng.Rows [2] .Columns [2] .Data

= = = = = = = = =

"Abra" "112233" "Cadabra" "Racadab" "12345" "332211" "Cadabra" "445566" "AA 22 BB"

Bản quyền © 2019-2021 Sean Bradley

Bảng.Rows [0] .Columns [0] .Justify Table.Rows [1] .Columns [0]. .Justify Bảng.Rows [1] .Columns [2]. .

6.6.8 Mã nguồn

Bảng.Rows [0] .Columns [0] .Data Table.Rows [0] .Columns [1] .Data Table.Rows [0] .Columns [2] .Data Bảng.Rows [1] .Columns [0] .Data Bảng.Rows [1] .Columns [1] .Data Bảng.Rows [1] .Columns [2] .Data Bảng.Rows [2] .Columns [0]. 1] .Data Bảng.Rows [2] .Columns [2] .Data

= = = = = = = = =

Bản quyền © 2019-2021 Sean Bradley

- 124/238 -

6.6.9 đầu ra

6.6.9 Đầu ra Python ./flyweight/client.py ---------------------------------------------- -| abra | 112233 | Cadabra | | Racadab | 12345 | 332211 | | Cadabra | 445566 | AA 22 BB | ---------------------------------------- Fly WeightFactory có 12 đối thủ

6.6.10 Khái niệm mã hóa mới Chuỗi Biện minh SBCode Video ID #DD45E8

Trong. Đây là những lệnh đặc biệt trên các chuỗi cho phép bạn đệm các chuỗi và căn chỉnh chúng bên trái, phải, trung tâm tùy thuộc vào tổng chiều dài chuỗi. Ví dụ, >>> "ABCD" .Center (10) 'ABCD'

>>> "ABCD" .RJUST (10) 'ABCD'

>>> "ABCD" .ljust (10) 'ABCD'

6.6.11 Tóm tắt • Khách hàng chỉ nên truy cập các đối tượng Flykg chỉ thông qua một đối tượng Fly WeightFactory để đảm bảo rằng chúng được chia sẻ. • Các giá trị nội tại được lưu trữ bên trong trong trọng lượng. • Các giá trị bên ngoài được chuyển sang trọng lượng và tùy chỉnh nó tùy thuộc vào ngữ cảnh. • Triển khai Fly Weight là sự cân bằng giữa việc lưu trữ tất cả các đối tượng trong bộ nhớ, so với việc lưu trữ các phần nhỏ duy nhất trong bộ nhớ và có khả năng tính toán các giá trị bên ngoài trong các đối tượng ngữ cảnh.

Bản quyền © 2019-2021 Sean Bradley

- 125/238 -

6.6.11 Tóm tắt

• Sử dụng trọng lượng để lưu bộ nhớ khi nó có lợi. Phần bù là CPU có thể được yêu cầu trong quá trình tính toán và chuyển các giá trị bên ngoài cho các đối thủ. • Fly weight làm giảm dấu chân bộ nhớ vì nó chia sẻ các đối tượng và cho phép khả năng tạo ra các thuộc tính bên ngoài một cách tự động. • Các bối cảnh thường sẽ tính toán các giá trị bên ngoài được sử dụng bởi các đối thủ, nhưng nó không cần thiết. Các giá trị có thể được lưu trữ hoặc tham chiếu từ các đối tượng khác nếu cần thiết. • Khi kiến ​​trúc trọng lượng bay, bắt đầu bằng việc xem xét phần nào của một đối tượng chung có thể được chia và áp dụng bằng các thuộc tính bên ngoài.

Bản quyền © 2019-2021 Sean Bradley

- 126/238 -

6.7 Mẫu thiết kế proxy

6.7 Mẫu thiết kế proxy 6.7.1 Tổng quan về ID video SBCode #C0F2D0

Mẫu thiết kế proxy là một lớp hoạt động như một giao diện cho một lớp hoặc đối tượng khác. Proxy có thể dành cho bất cứ điều gì, chẳng hạn như kết nối mạng, đối tượng trong bộ nhớ, tệp hoặc bất cứ thứ gì khác bạn cần để cung cấp sự trừu tượng giữa. Các loại proxy, • proxy ảo: một đối tượng có thể lưu trữ các phần của đối tượng thực, sau đó tải hoàn toàn toàn bộ đối tượng khi cần thiết. • Proxy từ xa: Có thể chuyển tiếp các tin nhắn đến một đối tượng thực sự tồn tại trong một không gian địa chỉ khác. • Proxy bảo vệ: Áp dụng một lớp xác thực trước đối tượng thực. • Tham khảo thông minh: Một đối tượng có thuộc tính nội bộ có thể được ghi đè hoặc thay thế. Chức năng bổ sung có thể được cung cấp tại Trừu tượng proxy nếu được yêu cầu. Ví dụ: bộ nhớ đệm, ủy quyền, xác nhận, khởi tạo lười biếng, ghi nhật ký. Proxy nên thực hiện giao diện chủ đề càng nhiều càng tốt để proxy và chủ thể xuất hiện giống hệt với máy khách. Mẫu proxy cũng có thể được gọi là vá khỉ hoặc tăng cường đối tượng

6.7.2 Thuật ngữ • Proxy: Một đối tượng có giao diện giống hệt với chủ đề thực. Có thể hoạt động như một người giữ chỗ cho đến khi chủ đề thực được tải hoặc vì người gác cổng áp dụng chức năng bổ sung. • Giao diện chủ thể: Một giao diện được thực hiện bởi cả proxy và chủ đề thực. • Chủ đề thực: đối tượng thực sự mà proxy đại diện. • Khách hàng: Ứng dụng máy khách sử dụng và tạo proxy.

Bản quyền © 2019-2021 Sean Bradley

- 127/238 -

6.7.3 Sơ đồ uml proxy

6.7.3 Sơ đồ uml isubject Ứng dụng máy khách + Yêu cầu (Loại): Loại

Proxy + Yêu cầu (Loại): Loại

RealSubject + request (loại): Loại

... real_subject.Request () ...

6.7.4 Mã nguồn. Chủ đề proxy và thực tế "@staticmethod @abstractmethod def yêu cầu ():" Một phương pháp để thực hiện "lớp RealSubject (isubject):" self.enormous_data = [1, 2, 3] yêu cầu def (self): return self.enormous_data class proxy (isubject): "" "

Bản quyền © 2019-2021 Sean Bradley

- 128/238 -

6.7.5 đầu ra

Proxy. Trong trường hợp này, proxy sẽ hoạt động như một bộ đệm cho `toror_data` và chỉ điền vào to lớn khi nó thực sự cần thiết" "" def __init __ (self): self.enormous_data = [] self.real_subject ): "" "Sử dụng proxy làm bộ đệm và tải dữ liệu vào đó chỉ khi cần" "" nếu self.enormous_data == []: in ("Kéo dữ liệu từ RealSubject") .Request () return self.enormous_data in ("Kéo dữ liệu từ bộ đệm proxy") return self.enormous_data # atal atal = proxy () # sử dụng chủ đề in (id (chủ đề)) Muốn hiển thị nó. In (chủ đề.

6.7.5 Python đầu ra.

6.7.6 sử dụng proxy Trường hợp SBCode Video ID #883F9A

Trong ví dụ này, tôi tự động thay đổi lớp của một đối tượng. Vì vậy, về cơ bản tôi đang sử dụng một đối tượng làm proxy cho các lớp khác.

Bản quyền © 2019-2021 Sean Bradley

- 129/238 -

6.7.7 Sơ đồ uml ví dụ

Mỗi khi phương thức Tell_Me_The_Future () được gọi; Nó sẽ ngẫu nhiên thay đổi đối tượng để sử dụng một lớp khác. Đối tượng Proteus sau đó sẽ sử dụng các thuộc tính tĩnh tương tự và phương thức lớp của lớp mới.

6.7.7 Ví dụ Sơ đồ UML Ứng dụng máy khách Iproteus

+ Tell_Me_The_Future () + Tell_Me_Yout_Form ()

Lion + Tell_Me_The_Future () + Tell_Me_Yout_Form ()

Serpent + Tell_Me_The_Future () + Tell_Me_Yout_Form ()

Leopard + Tell_Me_The_Future () + Tell_Me_Yout_Form ()

6.7.8 Mã nguồn ./proxy/client.py "Ví dụ Proxy Tell_me_your_form () proteus.tell_me_the_future () proteus.tell_me_your_form () proteus.tell_me_the_future () proteus.tell_me_your_form ()

./proxy/interface_proteus.py "Giao diện Proteus"

Bản quyền © 2019-2021 Sean Bradley

- 129/238 -

6.7.7 Sơ đồ uml ví dụ

Mỗi khi phương thức Tell_Me_The_Future () được gọi; Nó sẽ ngẫu nhiên thay đổi đối tượng để sử dụng một lớp khác. Đối tượng Proteus sau đó sẽ sử dụng các thuộc tính tĩnh tương tự và phương thức lớp của lớp mới.

6.7.7 Ví dụ Sơ đồ UML Ứng dụng máy khách Iproteus

+ Tell_Me_The_Future () + Tell_Me_Yout_Form ()

Bản quyền © 2019-2021 Sean Bradley

- 129/238 -

6.7.7 Sơ đồ uml ví dụ

Mỗi khi phương thức Tell_Me_The_Future () được gọi; Nó sẽ ngẫu nhiên thay đổi đối tượng để sử dụng một lớp khác. Đối tượng Proteus sau đó sẽ sử dụng các thuộc tính tĩnh tương tự và phương thức lớp của lớp mới.

6.7.7 Ví dụ Sơ đồ UML Ứng dụng máy khách Iproteus

+ Tell_Me_The_Future () + Tell_Me_Yout_Form ()

Bản quyền © 2019-2021 Sean Bradley

- 129/238 -

6.7.7 Sơ đồ uml ví dụ

Mỗi khi phương thức Tell_Me_The_Future () được gọi; Nó sẽ ngẫu nhiên thay đổi đối tượng để sử dụng một lớp khác. Đối tượng Proteus sau đó sẽ sử dụng các thuộc tính tĩnh tương tự và phương thức lớp của lớp mới.

6.7.7 Ví dụ Sơ đồ UML Ứng dụng máy khách Iproteus

+ Tell_Me_The_Future () + Tell_Me_Yout_Form ()

Lion + Tell_Me_The_Future () + Tell_Me_Yout_Form ()

Serpent + Tell_Me_The_Future () + Tell_Me_Yout_Form ()

Leopard + Tell_Me_The_Future () + Tell_Me_Yout_Form ()

Bản quyền © 2019-2021 Sean Bradley

- 133/238 -

6.7.11 Tóm tắt

6.7.11 Tóm tắt • Các yêu cầu chuyển tiếp proxy về chủ đề thực khi có thể, tùy thuộc vào loại proxy. • Proxy ảo có thể lưu trữ các phần tử của một chủ thể thực trước khi tải toàn bộ đối tượng vào bộ nhớ. • Proxy bảo vệ có thể cung cấp một lớp xác thực. Ví dụ: proxy nginx có thể thêm hạn chế xác thực cơ bản vào yêu cầu HTTP. • Proxy có thể thực hiện nhiều nhiệm vụ nếu cần thiết. • Proxy khác với bộ chuyển đổi. Bộ điều hợp sẽ cố gắng điều chỉnh hai giao diện hiện có với nhau. Proxy sẽ sử dụng giao diện tương tự như chủ đề. • Nó cũng rất giống với mặt tiền, ngoại trừ bạn có thể thêm trách nhiệm, giống như người trang trí. Các nhà trang trí tuy nhiên có thể được sử dụng đệ quy. • Mục đích của proxy là cung cấp một sự đứng lên khi trực tiếp truy cập trực tiếp vào một chủ thể thực. • Mô hình thiết kế proxy cũng có thể được gọi là mẫu thiết kế thay thế.

Bản quyền © 2019-2021 Sean Bradley

- 134/238 -

7. Hành vi

7. Hành vi 7.1 Mẫu thiết kế lệnh 7.1.1 Tổng quan về video sbcode #8c8ea3

Mẫu lệnh là một mẫu thiết kế hành vi, trong đó một sự trừu tượng tồn tại giữa một đối tượng gọi một lệnh và đối tượng thực hiện nó. Ví dụ: một nút sẽ gọi Invoker, sẽ gọi lệnh đã đăng ký trước, rằng người nhận sẽ thực hiện. Một lớp cụ thể sẽ ủy thác một yêu cầu cho một đối tượng lệnh, thay vì thực hiện trực tiếp yêu cầu. Sử dụng mô hình thiết kế lệnh cho phép bạn tách biệt các mối quan tâm và giải quyết các vấn đề về các mối quan tâm độc lập với nhau. Ví dụ: ghi nhật ký thực thi lệnh và kết quả của nó. Mẫu lệnh là một giải pháp tốt để thực hiện chức năng hoàn tác/làm lại vào ứng dụng của bạn. Sử dụng: • Các nút GUI, menu • Ghi âm macro • Hoàn tác đa cấp/làm lại • Mạng - Gửi toàn bộ các đối tượng lệnh qua mạng, ngay cả khi một đợt • Xử lý song song hoặc nhóm luồng • Hành vi giao dịch • Wizards

7.1.2 Thuật ngữ • Người nhận: Đối tượng sẽ nhận và thực thi lệnh. • Invoker: Đối tượng gửi lệnh đến máy thu. Ví dụ: một nút. • Đối tượng lệnh: Bản thân, một đối tượng, thực hiện một phương thức thực thi hoặc hành động và chứa tất cả thông tin cần thiết để thực thi nó.

Bản quyền © 2019-2021 Sean Bradley

- 135/238 -

7.1.3 Sơ đồ mẫu lệnh UML

• Khách hàng: Ứng dụng hoặc Thành phần nhận thức được người nhận, Invoker và lệnh.

7.1.3 Mẫu lệnh Sơ đồ UML Invoker Icommand

- _Commands: Loại

+ thực thi (loại): loại

+ Đăng ký (Loại): Loại + Thực thi (Loại): Loại

Lệnh2

Lệnh1

- _Receiver: Loại

- _Receiver: Loại

+ __init __ (người nhận) + Phương thức (loại): Loại

+ __init __ (người nhận) + Phương thức (loại): Loại

Ứng dụng máy khách của người nhận

+ Run_Command1 (Loại): Loại + Run_Command2 (Loại): Loại

7.1.4 Mã nguồn Máy khách khởi tạo một người nhận chấp nhận các lệnh nhất định làm mọi việc. Sau đó, máy khách tạo ra hai đối tượng lệnh sẽ gọi một trong các lệnh cụ thể trên máy thu. Sau đó, máy khách tạo ra một invoker, ví dụ: giao diện người dùng với các nút và đăng ký cả hai lệnh vào từ điển của các lệnh. Máy khách không gọi các lệnh của người nhận trực tiếp, nhưng thông qua Invoker, sau đó gọi phương thức EXECUTE () của đối tượng đã đăng ký. Sự trừu tượng hóa này giữa Invoker, Command và Trình nhận, cho phép Invoker thêm chức năng bổ sung như lịch sử, phát lại, hoàn tác/làm lại, ghi nhật ký, cảnh báo và bất kỳ điều hữu ích nào khác có thể được yêu cầu.

.

Bản quyền © 2019-2021 Sean Bradley

- 136/238 -

7.1.4 Mã nguồn

Class Icommand (metaclass = abcmeta): # pylint: vô hiệu hóa = quá công khai "giao diện lệnh, tất cả các lệnh sẽ triển khai" @staticmethod @abstractmethod def EXECUTE (): "Phương thức thực thi bắt buộc mà tất cả các đối tượng lệnh sẽ sử dụng" Lớp Invoker: "Lớp Invoker" def __init __ (self): self._commands = {} def register (self, lệnh_name, lệnh): "Đăng ký lệnh trong invoker" self._commands Command_Name): "Thực hiện bất kỳ lệnh đã đăng ký nào" nếu lệnh_name trong self._commands.keys (): self._commands [Command_name] .Execute () Bộ thu "@staticmethod def Run_Command_1 ():" Một tập hợp các hướng dẫn để chạy "print (" lệnh thực thi 1 ") @staticmethod def run_command_2 ():" Command1 (Icommand): # pylint: vô hiệu hóa = quá công khai-phương pháp OMMAND trên máy thu được chỉ định "" "def __init __ (self, người nhận): self._receiver = người nhận def exec

# pylint: vô hiệu hóa = phương pháp quá công khai quá

Bản quyền © 2019-2021 Sean Bradley

- 137/238 -

7.1.5 đầu ra

"" "Một đối tượng lệnh, thực hiện giao diện ICommand và chạy lệnh trên máy thu được chỉ định" "" def __init __ (self, người nhận) Máy khách # Tạo một máy thu thu = Trình nhận () # Tạo lệnh Command1 = Command1 (Trình nhận) Lệnh2 = Command2 (Trình nhận) # Đăng ký các lệnh với invoker invoker = invoker () invoker.register ("1", lệnh1) invoker. Đăng ký ("2", Command2) # Thực hiện các lệnh được đăng ký trên Invoker Invoker.execute ("1") Invoker.execute ("2") Invoker.execute ("1") Invoker.execute ("2")

7.1.5 Đầu ra Python ./command/command_concept.py Lệnh thực thi 1 Lệnh thực thi 2 Lệnh thực thi 1 Lệnh thực thi 2 Lệnh 2

7.1.6 Lệnh sử dụng trường hợp SBCode Video ID #30566D

Đây sẽ là một công tắc ánh sáng thông minh. Công tắc ánh sáng này sẽ giữ một lịch sử của mỗi lần một trong các lệnh của nó được gọi. Và nó có thể phát lại các lệnh của nó.

Bản quyền © 2019-2021 Sean Bradley

- 137/238 -

7.1.5 đầu ra

"" "Một đối tượng lệnh, thực hiện giao diện ICommand và chạy lệnh trên máy thu được chỉ định" "" def __init __ (self, người nhận) Máy khách # Tạo một máy thu thu = Trình nhận () # Tạo lệnh Command1 = Command1 (Trình nhận) Lệnh2 = Command2 (Trình nhận) # Đăng ký các lệnh với invoker invoker = invoker () invoker.register ("1", lệnh1) invoker. Đăng ký ("2", Command2) # Thực hiện các lệnh được đăng ký trên Invoker Invoker.execute ("1") Invoker.execute ("2") Invoker.execute ("1") Invoker.execute ("2")

7.1.5 Đầu ra Python ./command/command_concept.py Lệnh thực thi 1 Lệnh thực thi 2 Lệnh thực thi 1 Lệnh thực thi 2 Lệnh 2

7.1.6 Lệnh sử dụng trường hợp SBCode Video ID #30566D

Đây sẽ là một công tắc ánh sáng thông minh. Công tắc ánh sáng này sẽ giữ một lịch sử của mỗi lần một trong các lệnh của nó được gọi. Và nó có thể phát lại các lệnh của nó.

- 138/238 -

7.1.7 Sơ đồ uml ví dụ

7.1.7 Sơ đồ uml ví dụ

Một công tắc ánh sáng thông minh có thể được mở rộng trong tương lai để được gọi là từ xa hoặc tự động tùy thuộc vào các cảm biến.

Một công tắc ánh sáng thông minh có thể được mở rộng trong tương lai để được gọi là từ xa hoặc tự động tùy thuộc vào các cảm biến.

7.1.7 Ví dụ Công tắc sơ đồ UML - _Commands: Loại iswitch + Đăng ký (lệnh_name, lệnh) + exec

+ thực thi ()

Switchoncommand

SwitchoffCommand

- _Receiver: ánh sáng

Bản quyền © 2019-2021 Sean Bradley

+ __init __ (ánh sáng) + exec ()

Ứng dụng khách hàng ánh sáng

+ Turn_on () + Turn_off ()

7.1.8 Mã nguồn ./command/client.py "từ từ từ từ

Mẫu lệnh sử dụng ví dụ trường hợp. Một công tắc ánh sáng thông minh "Nhập ánh sáng Công tắc công tắc Nhập công tắc chuyển đổi công tắc

Bản quyền © 2019-2021 Sean Bradley

# Tạo đèn thu đèn = light () # Tạo lệnh switch_on = switchoncommand (light) switch_off = switchoffCommand (light) # đăng ký các lệnh với công tắc invoker = switch () switch.register ("trên", switch_on) switch.register ( "Tắt", Switch_off)

Ứng dụng khách hàng ánh sáng

+ Turn_on () + Turn_off ()

7.1.8 Mã nguồn ./command/client.py "từ từ từ từ

# pylint: vô hiệu hóa = phương pháp quá công khai quá

Mẫu lệnh sử dụng ví dụ trường hợp. Một công tắc ánh sáng thông minh "Nhập ánh sáng Công tắc công tắc Nhập công tắc chuyển đổi công tắc

# Tạo đèn thu đèn = light () # Tạo lệnh switch_on = switchoncommand (light) switch_off = switchoffCommand (light) # đăng ký các lệnh với công tắc invoker = switch () switch.register ("trên", switch_on) switch.register ( "Tắt", Switch_off)

Bản quyền © 2019-2021 Sean Bradley

- 139/238 -

7.1.8 Mã nguồn

# Thực hiện các lệnh được đăng ký trên Invoker Switch.execute ("ON") Switch.execute ("TẮT") Switch.execute ("ON") Switch.execute ("TẮT") # Hiển thị lịch sử Switch.show_history () # Phát lại hai lệnh thực hiện cuối cùng Switch.replay_last (2)

. : "Một tập hợp các hướng dẫn để chạy" in ("tắt đèn")

. def __init __ (self): self._commands = {} self._history = []

. sẽ triển khai "@staticmethod @abstractmethod def exec ():" Phương thức thực thi bắt buộc mà tất cả các đối tượng lệnh sẽ sử dụng "

7.1.9 Đầu ra Python ./ vào : Tắt đèn bật tắt đèn tắt

Bản quyền © 2019-2021 Sean Bradley

- 142/238 -

7.1.10 Khái niệm mã hóa mới

7.1.10 Khái niệm mã hóa mới _Single Dẫn đầu SBCode Video ID #37437A

Đơn vị dấu gạch dưới hàng đầu, trên các biến lớp của bạn là một chỉ số hữu ích cho các nhà phát triển khác rằng thuộc tính này nên được coi là riêng tư. Riêng tư, theo các ngôn ngữ kiểu C, có nghĩa là biến/trường/thuộc tính được ẩn và không thể được truy cập bên ngoài lớp. Nó chỉ có thể được sử dụng nội bộ bằng các phương pháp lớp riêng của nó. Python không có khái niệm truy cập công cộng/riêng nên biến không thực sự riêng tư và vẫn có thể được sử dụng bên ngoài lớp trong các mô -đun khác. Nó chỉ là một cấu trúc hữu ích mà bạn sẽ thấy các nhà phát triển sử dụng như một khuyến nghị không tham chiếu biến này trực tiếp bên ngoài lớp này, nhưng thay vào đó sử dụng một phương thức hoặc thuộc tính chuyên dụng.

7.1.11 Tóm tắt • Không nên quản lý trạng thái trong chính đối tượng lệnh. • Có thể có một hoặc nhiều người gọi có thể thực thi lệnh sau đó. • Đối tượng lệnh đặc biệt hữu ích nếu bạn muốn hoàn tác/làm lại các lệnh vào thời điểm sau. • Mẫu lệnh tương tự như mẫu Memento theo cách nó cũng có thể được sử dụng cho mục đích hoàn tác/làm lại. Tuy nhiên, mẫu Memento là về việc ghi và thay thế trạng thái của một đối tượng, trong khi mẫu lệnh thực hiện một lệnh được xác định trước. Ví dụ: vẽ, rẽ, thay đổi kích thước, lưu, v.v.

Bản quyền © 2019-2021 Sean Bradley

- 142/238 -

7.1.10 Khái niệm mã hóa mới

7.1.10 Khái niệm mã hóa mới _Single Dẫn đầu SBCode Video ID #37437A

Đơn vị dấu gạch dưới hàng đầu, trên các biến lớp của bạn là một chỉ số hữu ích cho các nhà phát triển khác rằng thuộc tính này nên được coi là riêng tư. Riêng tư, theo các ngôn ngữ kiểu C, có nghĩa là biến/trường/thuộc tính được ẩn và không thể được truy cập bên ngoài lớp. Nó chỉ có thể được sử dụng nội bộ bằng các phương pháp lớp riêng của nó. Python không có khái niệm truy cập công cộng/riêng nên biến không thực sự riêng tư và vẫn có thể được sử dụng bên ngoài lớp trong các mô -đun khác. Nó chỉ là một cấu trúc hữu ích mà bạn sẽ thấy các nhà phát triển sử dụng như một khuyến nghị không tham chiếu biến này trực tiếp bên ngoài lớp này, nhưng thay vào đó sử dụng một phương thức hoặc thuộc tính chuyên dụng.

7.1.11 Tóm tắt • Không nên quản lý trạng thái trong chính đối tượng lệnh. • Có thể có một hoặc nhiều người gọi có thể thực thi lệnh sau đó. • Đối tượng lệnh đặc biệt hữu ích nếu bạn muốn hoàn tác/làm lại các lệnh vào thời điểm sau. • Mẫu lệnh tương tự như mẫu Memento theo cách nó cũng có thể được sử dụng cho mục đích hoàn tác/làm lại. Tuy nhiên, mẫu Memento là về việc ghi và thay thế trạng thái của một đối tượng, trong khi mẫu lệnh thực hiện một lệnh được xác định trước. Ví dụ: vẽ, rẽ, thay đổi kích thước, lưu, v.v.

Bản quyền © 2019-2021 Sean Bradley

- 142/238 -

7.1.10 Khái niệm mã hóa mới

7.1.10 Khái niệm mã hóa mới _Single Dẫn đầu SBCode Video ID #37437A

Đơn vị dấu gạch dưới hàng đầu, trên các biến lớp của bạn là một chỉ số hữu ích cho các nhà phát triển khác rằng thuộc tính này nên được coi là riêng tư. Riêng tư, theo các ngôn ngữ kiểu C, có nghĩa là biến/trường/thuộc tính được ẩn và không thể được truy cập bên ngoài lớp. Nó chỉ có thể được sử dụng nội bộ bằng các phương pháp lớp riêng của nó. Python không có khái niệm truy cập công cộng/riêng nên biến không thực sự riêng tư và vẫn có thể được sử dụng bên ngoài lớp trong các mô -đun khác. Nó chỉ là một cấu trúc hữu ích mà bạn sẽ thấy các nhà phát triển sử dụng như một khuyến nghị không tham chiếu biến này trực tiếp bên ngoài lớp này, nhưng thay vào đó sử dụng một phương thức hoặc thuộc tính chuyên dụng.

7.1.11 Tóm tắt • Không nên quản lý trạng thái trong chính đối tượng lệnh. • Có thể có một hoặc nhiều người gọi có thể thực thi lệnh sau đó. • Đối tượng lệnh đặc biệt hữu ích nếu bạn muốn hoàn tác/làm lại các lệnh vào thời điểm sau. • Mẫu lệnh tương tự như mẫu Memento theo cách nó cũng có thể được sử dụng cho mục đích hoàn tác/làm lại. Tuy nhiên, mẫu Memento là về việc ghi và thay thế trạng thái của một đối tượng, trong khi mẫu lệnh thực hiện một lệnh được xác định trước. Ví dụ: vẽ, rẽ, thay đổi kích thước, lưu, v.v.

- 143/238 -

7.2 Chuỗi mô hình thiết kế trách nhiệm

Bản quyền © 2019-2021 Sean Bradley

- 145/238 -

7.2.5 đầu ra

Tải trọng = tải trọng - 1 tải trọng = người kế thừa2 (). Xử lý (tải trọng) Trả về Lớp tải trọng kế thừa ngẫu nhiên.randint (1, 3) nếu kiểm tra == 1: tải trọng = tải trọng * 2 tải trọng = kế thừa Trở lại chuỗi tải chuỗi (): "Một chuỗi có người kế thừa đầu tiên mặc định" @staticmethod def start (tải trọng): "Đặt người kế thừa đầu tiên sẽ sửa đổi tải trọng" return Comment1 (). Xử lý (tải trọng) # chuỗi máy khách = chuỗi .

7.2.5 Đầu ra Python.

7.2.6 Chuỗi Trách nhiệm sử dụng trường hợp SBCode Video ID #D89543

Bản quyền © 2019-2021 Sean Bradley

- 146/238 -

7.2.7 Ví dụ Sơ đồ UML

Trong ví dụ ATM dưới đây, chuỗi được mã hóa cứng trong khách hàng trước tiên để phân phối số tiền là £ 50, sau đó là £ 20 và sau đó là 10 bảng theo thứ tự. Thứ tự chuỗi mặc định này giúp đảm bảo rằng số lượng ghi chú tối thiểu sẽ được phân phối. Nếu không, nó có thể phân phối 5 x £ 10 khi tốt hơn là phân phối 1 x £ 50. Mỗi người kế nhiệm có thể được gọi lại một cách đệ quy cho mỗi mệnh giá tùy thuộc vào giá trị được yêu cầu rút tiền.

7.2.7 Ví dụ Sơ đồ UML Idispenser + next_successor (IDispensor) + tay cầm (số tiền)

Phân phối10

Người phân phối20

Pha xử lý 50

- _successor: Idispenser

- _successor: Idispenser

- _successor: Idispenser

+ next_successor (idispensor) + tay cầm (số tiền)

+ next_successor (idispensor) + tay cầm (số tiền)

+ next_successor (idispensor) + tay cầm (số tiền)

Máy khách atmdispenserchain

+ Chain1: Despenser10 + Chain1: Despenser20 + Chain1: Despenser50

7.2.8 Mã nguồn. <10 hoặc số lượng % 10! = 0: In ("Số tiền phải dương và trong nhiều 10 giây.")

Bản quyền © 2019-2021 Sean Bradley

- 147/238 -

7.2.8 Mã nguồn

Atm.chain1.handle (số tiền) in ("Bây giờ hãy tự làm hỏng mình")

.

Chuỗi bộ phân phối ATM "Bộ phân phối 10 Bộ phân phối nhập khẩu 10 Bộ phân phối nhập khẩu 20 Phân phối nhập khẩu 50 Bộ phân phối nhập khẩu 50

Lớp ATMDispenserchain: "Khách hàng chuỗi"

# pylint: vô hiệu hóa = phương pháp quá công khai quá

def __init __ (self): # khởi tạo chuỗi kế thừa self.chain1 = dispenser50 () self.chain2 = dispenser20 () self.chain3 = Dispenser10 () 10s cuối cùng. Chuỗi kế thừa # sẽ được tính toán lại một cách linh hoạt trong thời gian chạy. self.chain1.next_successor (self.chain2) self.chain2.next_successor (self.chain3)

. Trong chuỗi "" "@staticmethod @abstractmethod def (số lượng):" "" Xử lý sự kiện "" "

.

- 148/238 -

7.2.8 Mã nguồn

Atm.chain1.handle (số tiền) in ("Bây giờ hãy tự làm hỏng mình")

.

Bản quyền © 2019-2021 Sean Bradley

Phân phối10

Người phân phối20

Pha xử lý 50

7.2.9 Đầu ra Python.

7.2.10 Khái niệm mã hóa mới Bộ phận SBCode Video ID #56C97D

Thông thường phân chia sử dụng một đơn / ký tự và sẽ trả về một bản nổi ngay cả khi các số là số nguyên hoặc chính xác chia hết mà không có phần còn lại, ví dụ:

Bản quyền © 2019-2021 Sean Bradley

- 150/238 -

7.2.11 Tóm tắt

PS> Python >>> 9/3 3.0 Python phiên bản 3 cũng có tùy chọn trả về phiên bản số nguyên (tầng) của số bằng cách sử dụng các ký tự đôi // thay thế. PS> Python >>> 9 // 3 3 Xem PEP-0238: https://www.python.org/dev/peps/pep-0238/

Chấp nhận ID video SBCode đầu vào của người dùng #675635

Trong tệp. Lệnh đầu vào cho phép tập lệnh của bạn chấp nhận đầu vào của người dùng từ dấu nhắc lệnh. Trong ví dụ ATM, khi bạn bắt đầu, nó sẽ yêu cầu người dùng nhập một số. Sau đó, khi người dùng nhấn phím Enter, đầu vào được chuyển đổi thành số nguyên và giá trị được kiểm tra nếu hợp lệ. Số lượng = int (input ("nhập số tiền vào rút tiền:")) nếu số tiền <10 hoặc số lượng % 10! = 0: ... Tiếp tục lưu ý rằng trong Python 2.x, hãy sử dụng lệnh Raw_Input () thay vì đầu vào () . Xem PEP-3111: https://www.python.org/dev/peps/pep-3111/

7.2.11 Tóm tắt • Đối tượng sẽ truyền qua chuỗi cho đến khi được xử lý đầy đủ. • Đối tượng không biết người kế thừa nào hoặc bao nhiêu người sẽ xử lý nó. • Người kế thừa tiếp theo trong chuỗi được chọn động trong thời gian chạy tùy thuộc vào logic từ người kế nhiệm hiện tại. • Người kế thừa thực hiện một giao diện chung khiến chúng hoạt động độc lập với nhau, để chúng có thể được sử dụng đệ quy hoặc có thể theo một thứ tự khác.

Bản quyền © 2019-2021 Sean Bradley

- 150/238 -

7.2.11 Tóm tắt

PS> Python >>> 9/3 3.0 Python phiên bản 3 cũng có tùy chọn trả về phiên bản số nguyên (tầng) của số bằng cách sử dụng các ký tự đôi // thay thế. PS> Python >>> 9 // 3 3 Xem PEP-0238: https://www.python.org/dev/peps/pep-0238/

Bản quyền © 2019-2021 Sean Bradley

- 150/238 -

7.2.11 Tóm tắt

PS> Python >>> 9/3 3.0 Python phiên bản 3 cũng có tùy chọn trả về phiên bản số nguyên (tầng) của số bằng cách sử dụng các ký tự đôi // thay thế. PS> Python >>> 9 // 3 3 Xem PEP-0238: https://www.python.org/dev/peps/pep-0238/

Chấp nhận ID video SBCode đầu vào của người dùng #675635

Bản quyền © 2019-2021 Sean Bradley

- 153/238 -

7.3.2 Thuật ngữ

Ví dụ: khi gửi tin nhắn trên mạng, máy khách nhận, có thể chậm để nhận thông điệp đầy đủ đã được gửi hoặc thậm chí hết thời gian chờ. Việc đẩy này từ phía người gửi có thể tăng số lượng móc nối mạng hoặc luồng nếu có nhiều tin nhắn vẫn đang chờ được gửi đầy đủ. Các đối tượng đang chịu trách nhiệm cho việc giao hàng. Mặt khác, nếu người quan sát yêu cầu cập nhật từ thuê bao, thì đối tượng (có thể quan sát) có thể trả về thông tin như một phần của phản hồi yêu cầu. Người quan sát cũng có thể chỉ ra như là một phần của yêu cầu, chỉ trả về dữ liệu áp dụng cho X, sau đó sẽ làm cho thông báo phản hồi nhỏ hơn để chuyển với chi phí làm cho người quan sát có thể quan sát được hơn với người quan sát. Sử dụng cơ chế đẩy từ chủ đề khi các bản cập nhật được yêu cầu hoàn toàn gần với thời gian thực từ quan điểm của người quan sát, lưu ý rằng bạn có thể cần quản lý tiềm năng của các tài nguyên chưa được giải quyết thêm xếp hàng tại người gửi. Nếu các bản cập nhật về đầu quan sát được phép chịu một số độ trễ, thì cơ chế kéo là đáng tin cậy nhất và dễ quản lý nhất vì đó là người quan sát có trách nhiệm đồng bộ hóa trạng thái của nó.

7.3.2 Thuật ngữ • Giao diện chủ thể: (Giao diện có thể quan sát) Giao diện mà đối tượng nên thực hiện. • Chủ đề cụ thể: (có thể quan sát) đối tượng là đối tượng. • Giao diện người quan sát: Giao diện mà người quan sát nên thực hiện. • Người quan sát cụ thể: Đối tượng là người quan sát. Có thể có một số lượng thay đổi các nhà quan sát có thể đăng ký/hủy đăng ký trong thời gian chạy.

7.333

IOBServer + Thông báo (Loại): Loại

Chủ đề - _observers: Set

Người quan sát

Ứng dụng máy khách + Đăng ký (Loại): Loại + Hủy đăng ký (Loại): Loại + Thông báo (Loại): Loại

Bản quyền © 2019-2021 Sean Bradley

+ Thông báo (Loại): Loại

- 154/238 -

7.3.4 Mã nguồn

7.3.4 Mã nguồn Một đối tượng (có thể quan sát) được tạo. Hai nhà quan sát được tạo ra. Họ có thể ở trên một mạng, nhưng với mục đích trình diễn nằm trong cùng một khách hàng. Các đối tượng thông báo cho các nhà quan sát. Một trong những người quan sát hủy đăng ký, chủ đề thông báo cho người quan sát còn lại.

.4 . ) "def __init __ (self): self._observers = set () def đăng ký (self, quan sát

Bản quyền © 2019-2021 Sean Bradley

- 155/238 -

7.3.5 đầu ra

self._observers.Remove (người quan sát) def thông báo (self, *args): cho người quan sát trong self._observers: observer. @staticmethod @abstractmethod def thông báo (có thể quan sát được, *args): "Nhận thông báo" Người quan sát lớp (IOBServer): "Người quan sát cụ thể" def __init __ (tự, có thể quan sát được): có thể quan sát được. args): print (f "observer id: {id (self)} đã nhận {args}") # atal ention = atmit () observer_a = observer (chủ đề) observer_b = quan sát (chủ đề) chủ đề. , [1, 2, 3]) Chủ đề.

7.3.5 Python đầu ra. ID người quan sát: 2084220160272 đã nhận ('Thông báo thứ hai', {'A': 1, 'B': 2, 'C': 3})

7.3.6 Người quan sát sử dụng trường hợp SBCode Video ID #0F7FC5

Ví dụ này bắt chước phương pháp MVC được mô tả trước đó.

Bản quyền © 2019-2021 Sean Bradley

- 156/238 -

7.3.6 Trường hợp sử dụng người quan sát

Có một quy trình bên ngoài gọi là DataContler và một quy trình khách hàng giữ một

DataModel và nhiều Dataview là biểu đồ bánh, biểu đồ thanh và chế độ xem bảng. Lưu ý rằng ví dụ này chạy trong một quy trình duy nhất, nhưng hãy tưởng tượng rằng DataControll thực sự là một quy trình bên ngoài chạy trên một máy chủ khác. Datamodel đăng ký vào DataContler và DataViews đăng ký

Mô hình dữ liệu . Máy khách thiết lập các chế độ xem khác nhau với một thuê bao cho datamodel. Sau đó, bộ dữ liệu bên ngoài giả thuyết sau đó cập nhật dữ liệu bên ngoài và dữ liệu sau đó truyền qua các lớp đến các chế độ xem. Lưu ý rằng trong thực tế, ví dụ này sẽ phức tạp hơn nhiều nếu nhiều máy chủ có liên quan. Tôi đang giữ nó ngắn gọn để chứng minh một trường hợp sử dụng có thể của mẫu quan sát viên. Cũng lưu ý rằng trong bộ dữ liệu, các tham chiếu đến các nhà quan sát được chứa trong một tập hợp, trong khi trong datamodel tôi đã sử dụng từ điển thay thế, để bạn có thể thấy một cách tiếp cận khác.

Bản quyền © 2019-2021 Sean Bradley

- 157/238 -

7.3.7 Ví dụ Sơ đồ UML

7.3.7 Ví dụ Sơ đồ UML Ứng dụng máy khách IDATAVIEW + Thông báo (Quan sát, Dữ liệu) + Draw () + Delete ()

PIEGRAPH

Thanh biểu đồ

+ init (có thể quan sát) + thông báo (có thể quan sát được, dữ liệu) + draw () + xóa ()

TableView

+ init (có thể quan sát) + thông báo (có thể quan sát được, dữ liệu) + draw () + xóa ()

+ init (có thể quan sát) + thông báo (có thể quan sát được, dữ liệu) + draw () + xóa ()

TableView

DataModel - _observers: Dict - _Count - _Data_Controll

Idatamodel

Idatamodel

+ Đăng ký (Loại): Loại + Hủy đăng ký (Loại): Loại + Thông báo (Loại): Loại

Thông tin giả thuyết bên ngoài DataSource DataControll IdataControll

Idatamodel

+ Đăng ký (Loại): Loại + Hủy đăng ký (Loại): Loại + Thông báo (Loại): Loại

Bản quyền © 2019-2021 Sean Bradley

Thông tin giả thuyết bên ngoài DataSource DataControll IdataControll

- _observers: set + đăng ký (loại): loại + hủy đăng ký (loại): loại + thông báo (loại)

7.3.8 Mã nguồn.

- 158/238 -

7.3.8 Mã nguồn

Bản quyền © 2019-2021 Sean Bradley

Từ Bar_Graph_View Nhập BargraphView từ TABE_VIEW Nhập bảng TableView # Một dữ liệu cục bộ Xem rằng bộ điều khiển bên ngoài giả thuyết cập nhật data_model = datamodel () # Thêm một số trực quan # Một bộ điều khiển dữ liệu giả thuyết chạy trong một quy trình khác DATA_CONTROLLER = dataControll () # Bộ điều khiển dữ liệu bên ngoài giả thuyết cập nhật một số dữ liệu data_controll.notify ([1, 2, 3]) Bộ điều khiển dữ liệu bên ngoài giả thuyết cập nhật dữ liệu một lần nữa Data_Controll.notify ([4, 5, 6])

- _observers: set + đăng ký (loại): loại + hủy đăng ký (loại): loại + thông báo (loại)

7.3.8 Mã nguồn.

- 158/238 -

7.3.8 Mã nguồn

Từ Bar_Graph_View Nhập BargraphView từ TABE_VIEW Nhập bảng TableView # Một dữ liệu cục bộ Xem rằng bộ điều khiển bên ngoài giả thuyết cập nhật data_model = datamodel () # Thêm một số trực quan # Một bộ điều khiển dữ liệu giả thuyết chạy trong một quy trình khác DATA_CONTROLLER = dataControll () # Bộ điều khiển dữ liệu bên ngoài giả thuyết cập nhật một số dữ liệu data_controll.notify ([1, 2, 3]) Bộ điều khiển dữ liệu bên ngoài giả thuyết cập nhật dữ liệu một lần nữa Data_Controll.notify ([4, 5, 6])

- _observers: set + đăng ký (loại): loại + hủy đăng ký (loại): loại + thông báo (loại)

7.3.8 Mã nguồn.

- 158/238 -

Bản quyền © 2019-2021 Sean Bradley

- 161/238 -

7.3.8 Mã nguồn

. Tóm tắtMethod def hủy đăng ký (Observer_id): "Phương thức hủy đăng ký" @staticmethod @abstractmethod def thông báo (dữ liệu): "Phương thức thông báo"

. .

Bản quyền © 2019-2021 Sean Bradley

- 162/238 -

7.3.9 Đầu ra

cho người quan sát trong cls._observers: observer.notify (*args)

. Tóm tắtMethod def hủy đăng ký (Observer): "Phương thức hủy đăng ký" @staticmethod @abstractmethod def thông báo (Observer): "Phương thức thông báo"

7.3.9 Python đầu ra. TableView, ID: 3 Vẽ Chế độ xem bảng Sử dụng dữ liệu: [1, 2, 3] Piegraph, ID: 1 Vẽ biểu đồ bánh bằng dữ liệu: [4, 5, 6] TableView, ID: 3 Vẽ Chế độ xem bảng bằng dữ liệu: [4, 5, 6]

7.3.10 Khái niệm mã hóa mới Python Set SBCode Video ID #C81244

Bản quyền © 2019-2021 Sean Bradley

- 163/238 -

7.3.11 Tóm tắt

Một bộ Python tương tự như một danh sách. Ngoại trừ các mục trong tập hợp được đảm bảo là duy nhất, ngay cả khi bạn cố gắng thêm một bản sao. Một bộ là một lựa chọn tốt để giữ một bộ sưu tập các vật liệu quan sát, vì vấn đề của các quan sát trùng lặp được xử lý tự động. Một tập hợp có thể được khởi tạo bằng cách sử dụng niềng răng xoăn {} hoặc set (), các câu [] cho một danh sách và () cho một tuple. Nó không giống như một từ điển, cũng sử dụng {}, vì các mục từ điển được tạo thành khóa: các cặp giá trị. tức là {"a": 1, "b": 2, "c": 3} ps> python >>> items = {"yankee", "Doodle", "Dandy", "Doodle"} >>> 'Yankee', 'Doodle', 'Dandy'} >>> items.add ("Grandy") >>> Các mặt hàng {'Grandy', 'Yankee', 'Doodle', 'Dandy'} >>> ("Doodle") >>> Các mặt hàng {'Grandy', 'Yankee', 'Dandy'}

Lưu ý nếu khởi tạo một tập trống thì hãy sử dụng my_object = set () thay vì my_object =

{} để giảm sự mơ hồ với việc tạo một từ điển trống.

7.3.11 Tóm tắt • Sử dụng khi thay đổi một đối tượng yêu cầu thay đổi người khác và bạn không biết cần thay đổi bao nhiêu đối tượng khác. • Một chủ đề có một danh sách các nhà quan sát, mỗi người phù hợp với giao diện người quan sát. Đối tượng không cần biết về lớp cụ thể của bất kỳ người quan sát nào. Nó sẽ thông báo cho người quan sát bằng phương pháp được mô tả trong giao diện. • Đối tượng và người quan sát có thể thuộc về bất kỳ lớp nào của hệ thống cho dù cực kỳ lớn hay nhỏ. • Sử dụng cơ chế đẩy hoặc kéo cho người quan sát sẽ phụ thuộc vào cách bạn muốn hệ thống của bạn quản lý dự phòng cho việc chuyển dữ liệu cụ thể. Những điều này trở nên cân nhắc hơn khi người quan sát bị tách ra khỏi một chủ đề và thông điệp cần phải đi qua nhiều lớp, quy trình và hệ thống.

Bản quyền © 2019-2021 Sean Bradley

- 164/238 -

7.4 Mô hình thiết kế phiên dịch

7.4 Mẫu thiết kế phiên dịch 7.4.1 Tổng quan về video SBCode #5B415B

Mẫu phiên dịch giúp chuyển đổi thông tin từ ngôn ngữ này sang ngôn ngữ khác. Ngôn ngữ có thể là bất cứ điều gì như từ trong câu, công thức số hoặc thậm chí mã phần mềm. Quá trình này là để chuyển đổi thông tin nguồn, thành một cây cú pháp trừu tượng (AST) của các biểu thức thiết bị đầu cuối và không thiết bị đầu cuối mà tất cả đều thực hiện phương thức diễn giải (). Một biểu thức không đầu cuối là sự kết hợp của các biểu thức không đầu cuối và/hoặc thiết bị đầu cuối khác. Thiết bị đầu cuối có nghĩa là chấm dứt, tức là, không có quá trình xử lý nào liên quan. Một gốc AST bắt đầu với một biểu thức không đầu cuối và sau đó giải quyết xuống mỗi nhánh cho đến khi tất cả các biểu thức chấm dứt. Một biểu thức ví dụ là a + b. A và B là các biểu thức thiết bị đầu cuối và + không phải là đầu cuối vì nó phụ thuộc vào hai biểu thức thiết bị đầu cuối khác. Hình ảnh bên dưới, là AST cho biểu thức 5 + 4 - 3 + 7 - 2

Bản quyền © 2019-2021 Sean Bradley

- 165/238 -

7.4.2 Thuật ngữ

không phải là đầu cuối ...

không phải là đầu cuối ...

không phải là đầu cuối ...

không phải là đầu cuối ...

phần cuối...

phần cuối...

phần cuối...

phần cuối...

phần cuối...

Mô hình phiên dịch chính thức được mô tả trong cuốn sách mẫu thiết kế GOF ban đầu không nêu cách xây dựng một cây cú pháp trừu tượng. Cách cây của bạn được xây dựng sẽ phụ thuộc vào các cấu trúc ngữ pháp của câu bạn mà bạn muốn giải thích. Cây cú pháp trừu tượng có thể được tạo bằng tay hoặc động từ tập lệnh trình phân tích cú pháp tùy chỉnh. Trong mã ví dụ đầu tiên bên dưới, tôi xây dựng AST theo cách thủ công. Khi AST được tạo, sau đó bạn có thể chọn nút gốc và sau đó chạy hoạt động diễn giải trên đó và nó sẽ diễn giải toàn bộ cây đệ quy.

7.4.2 Thuật ngữ • Biểu thức trừu tượng: Mô tả (các) phương pháp mà các biểu thức thiết bị đầu cuối và không thiết bị đầu cuối nên thực hiện. • Biểu thức không đầu cuối: Một hỗn hợp của các biểu thức thiết bị đầu cuối và/hoặc không đầu cuối. • Biểu thức đầu cuối: Một biểu thức nút lá. • Bối cảnh: Bối cảnh là trạng thái có thể được truyền qua các hoạt động diễn giải nếu cần thiết. • Khách hàng: Xây dựng hoặc được cung cấp một cây cú pháp trừu tượng để giải thích.

Bản quyền © 2019-2021 Sean Bradley

- 166/238 -

7.4.3 Sơ đồ thông dịch UML

7.4.3 Trình thông dịch Sơ đồ UML Tóm tắt Cú pháp TerminalExpression + Giá trị + diễn giải () Ứng dụng khách hàng Tóm tắt + diễn giải

7.4.4 Mã nguồn Trong ví dụ này, tôi diễn giải chuỗi 5 + 4 - 3 + 7 - 2 và sau đó tính toán kết quả. Ngữ pháp của chuỗi tuân theo một mẫu số -> toán tử -> Số -> v.v. Tôi chuyển đổi chuỗi thành một danh sách các mã thông báo mà tôi có thể đề cập đến chỉ mục trong danh sách. Sau đó tôi xây dựng AST theo cách thủ công, bằng cách thêm 1. Hàng thêm không đầu cuối chứa hai đầu cuối cho hàng 5 và 4, 2. chứa hàng không đầu cuối trước đó và 7 4. Hàng trừ không đầu cuối có chứa hàng không đầu cuối trước đó và 2 gốc AST trở thành hàng cuối cùng được thêm vào, và sau đó tôi có thể chạy phương thức diễn giải () trên đó , sẽ diễn giải toàn bộ AST đệ quy bởi vì mỗi hàng AST tham chiếu hàng trên nó.

.

- 167/238 -

7.4.4 Mã nguồn

`Phương thức` Phương thức "@StaticMethod def diễn giải ():" " = int (giá trị) def diễn giải (self): return self.value def __repr __ (self): return str (self.value) class add (Tóm tắtExpression): "Biểu thức không đầu cuối." Def __init __ (tự, trái, phải) : self.left = left self.right = right def phiên dịch (self): return self.left.interpret () + self.right.interpret () def __repr __ self.right}) "Lớp trừ (Tóm tắtExpression):" Biểu thức không đầu cuối "def __init __ (self, trái, phải): self.left = left self.right = right def giải thích (tự): return self.left.interpret . -> Số -> vv,

Bản quyền © 2019-2021 Sean Bradley

- 168/238 -

7.4.5 đầu ra

Câu = "5 + 4 - 3 + 7 - 2" in (câu) # chia câu thành các biểu thức riêng lẻ sẽ được thêm vào # một cây cú pháp trừu tượng (AST) dưới dạng các biểu thức cuối cùng và không đầu cuối "". ]))) ) AST_ROOT = AST.POP () # diễn giải đệ quy thông qua toàn bộ AST bắt đầu từ gốc. in (ast_root.Interpret ()) # in ra biểu diễn của bản in ast_root (AST_ROOT)

7.4.5 Đầu ra Python. '-', '2'] 11 ((((5 thêm 4) trừ 3) thêm 7) trừ 2)

7.4.6 Thông dịch sử dụng trường hợp ID video SBCode #EB7859

Trường hợp sử dụng ví dụ sẽ mở rộng trên ví dụ khái niệm bằng cách tự động tạo AST và chuyển đổi các chữ số La Mã thành số nguyên cũng như tính toán kết quả cuối cùng. Hình ảnh bên dưới, là AST cho biểu thức 5 + IV - 3 + VII - 2

Bản quyền © 2019-2021 Sean Bradley

- 169/238 -

7.4.6 Trường hợp sử dụng thông dịch viên

không phải là đầu cuối ...

không phải là đầu cuối ...

không phải là đầu cuối ...

không phải là đầu cuối ...

phần cuối...

phần cuối...

không phải là đầu cuối ...

phần cuối...

phần cuối...

không phải là đầu cuối ...

phần cuối...

Bản quyền © 2019-2021 Sean Bradley

- 169/238 -

7.4.6 Trường hợp sử dụng thông dịch viên

không phải là đầu cuối ...

phần cuối...

- 170/238 -

7.4.7 Ví dụ Sơ đồ UML

7.4.7 Ví dụ Sơ đồ UML Tóm tắt Ứng dụng khách hàng

Số + Giá trị

+ diễn giải () + phiên dịch ()

cộng

Trừ

cộng

Trừ

+ trái + phải

Romannumeral + roman_numeral + bối cảnh

+ diễn giải ()

+ trái + phải + phiên dịch ()

+ trái + phải + phiên dịch ()

+ trái + phải + phiên dịch ()

+ trái + phải + phiên dịch ()

cộng

cộng

cộng

cộng

Trừ

Bản quyền © 2019-2021 Sean Bradley

+ trái + phải

Romannumeral + roman_numeral + bối cảnh

+ diễn giải ()

+ trái + phải + phiên dịch ()

Romannumeral1

Romannumeral10

Romannumeral100

Romannumeral + roman_numeral + bối cảnh

+ diễn giải ()

+ trái + phải + phiên dịch ()

Romannumeral1

Bản quyền © 2019-2021 Sean Bradley

Romannumeral10

Romannumeral + roman_numeral + bối cảnh

+ diễn giải ()

Bản quyền © 2019-2021 Sean Bradley

- 174/238 -

7.4.8 Mã nguồn

One = "C" Four = "Cd" Five = "D" Nine = "CM" Multiplier = 100 Class Romannumeral1000 (Romannumeral1): "Số La Mã 1000 - 3999" One = "M" Four = "" Five = "Nine = "" Hệ số nhân = 1000

.

Số nhập số Thêm Nhập Thêm Nhập trừ Subtract Subtract Roman_Numeral Nhập Romannumeral

Trình phân tích cú pháp lớp: "Tự động tạo cây cú pháp trừu tượng" @ClassMethod def parse (CLS, câu): "Tạo AST từ câu" tokens = câu.split ("") Trong khi len (mã thông báo)> 1: left_expression = cls.decide_left_expression (cây, mã thông báo) # Nhận toán tử, hãy tạo toán tử danh sách token ngắn hơn = token.pop (0) cây.append (romannumeral (tokens [0])) nếu toán tử == '-': cây.append (trừ (left_expression, cây [-1])) nếu toán tử == '+': bản quyền © 2019-2021 Sean Bradley

- 175/238 -

7.4.9 Đầu ra

cây.append (add (left_expression, cây [-1])) , right_expression)) nếu toán tử == '+': tree.append (add (left_expression, right_expression)) == '+': Tree.Append (add (cây [-1], right_expression)) return Tree.pop () @staticmethod def dision_left_expression (cây, mã thông báo): "" Một số hoặc số La Mã. Mỗi biểu thức liên tiếp được tham chiếu đến một hàng AST hiện có "" "Left = token.pop (0) left_expression = none nếu không cây: # chỉ áp dụng nếu vòng đầu tiên nếu không rời khỏi.isdigit (): # # Nếu mã thông báo đầu tiên Một cây số La Mã.Append (romannumeral (trái)) left_expression = cây [-1]

7.4.9 Đầu ra Python. '-', '2'] 11 ((((5 thêm IV (4)) trừ 3) Thêm VII (7)) Trừ 2)

Bản quyền © 2019-2021 Sean Bradley

- 176/238 -

7.4.10 Khái niệm mã hóa mới

7.4.10 Khái niệm mã hóa mới Chuỗi cắt SBCode ID #E13190

Đôi khi bạn muốn một phần của một chuỗi. Trong mã ví dụ, khi tôi diễn giải các chữ số La Mã, tôi đang so sánh một hoặc hai ký tự đầu tiên trong ngữ cảnh với IV hoặc CM hoặc nhiều kết hợp chữ số La Mã khác. Nếu trận đấu là đúng thì tôi tiếp tục với các lệnh tiếp theo. Định dạng là Chuỗi [Bắt đầu: Kết thúc: Bước] ví dụ: Chuỗi có thể là mmmcmxcix và tôi muốn ba ký tự đầu tiên, test = "mmmcmxcix" in (test [0: 3]) đầu ra mmm hoặc tôi muốn thử nghiệm 4 ký tự cuối cùng = "Mmmcmxcix" in (test [-4:]) đầu ra xcix hoặc tôi muốn một phần trong test giữa = "mmmcmxcix" in (kiểm tra [2: 5])

Bản quyền © 2019-2021 Sean Bradley

- 177/238 -

7.4.10 Khái niệm mã hóa mới

7.4.10 Khái niệm mã hóa mới Chuỗi cắt SBCode ID #E13190

Đôi khi bạn muốn một phần của một chuỗi. Trong mã ví dụ, khi tôi diễn giải các chữ số La Mã, tôi đang so sánh một hoặc hai ký tự đầu tiên trong ngữ cảnh với IV hoặc CM hoặc nhiều kết hợp chữ số La Mã khác. Nếu trận đấu là đúng thì tôi tiếp tục với các lệnh tiếp theo. Định dạng là Chuỗi [Bắt đầu: Kết thúc: Bước] ví dụ: Chuỗi có thể là mmmcmxcix và tôi muốn ba ký tự đầu tiên, test = "mmmcmxcix" in (test [0: 3]) đầu ra mmm hoặc tôi muốn thử nghiệm 4 ký tự cuối cùng = "Mmmcmxcix" in (test [-4:]) đầu ra xcix hoặc tôi muốn một phần trong test giữa = "mmmcmxcix" in (kiểm tra [2: 5])

- 177/238 -

MCM hoặc Test bước = "mmmcmxcix" in (kiểm tra [2: 9: 2]) đầu ra mmcx hoặc thậm chí kiểm tra đảo ngược = "mmmcmxcix" in (kiểm tra [::-1]) Mã nguồn trên khắp Internet. Vì vậy, khi bạn nhìn thấy [] với các số và dấu chấm bên trong, ví dụ, [: -1:], có khả năng sẽ thực hiện với việc trích xuất một phần của cấu trúc dữ liệu. Lưu ý rằng kỹ thuật này cũng hoạt động trên danh sách và bộ dữ liệu. test = [1,2,3,4,5,6,7,8,9] in (test [0: 3]) in (test [-4:]) in (test [2: 5]) in ( Kiểm tra [2: 9: 2]) in (kiểm tra [::-1]) in (kiểm tra [:-1:]) đầu ra [1, [6, [3, [3, [9, [1,

Bản quyền © 2019-2021 Sean Bradley

2, 7, 4, 5, 8, 2,

3] 8, 5] 7, 7, 3,

9] 9] 6, 5, 4, 3, 2, 1] 4, 5, 6, 7, 8]

- 178/238 -

7.4.11 Tóm tắt

Bản quyền © 2019-2021 Sean Bradley

- 179/238 -

7.5 Mẫu thiết kế vòng lặp

7.5 Mẫu thiết kế Iterator 7.5.1 Tổng quan về video SBCode #D072B5

Trình lặp thường sẽ chứa hai phương pháp thực hiện các khái niệm sau. • Tiếp theo: Trả về đối tượng tiếp theo trong tổng hợp (bộ sưu tập, đối tượng). • HAS_NEXT: Trả về một boolean cho biết liệu có thể đi được ở cuối của lần lặp hay không. Lợi ích của việc sử dụng mẫu Iterator là máy khách có thể đi qua một tập hợp các tập hợp (đối tượng) mà không cần phải hiểu các biểu diễn nội bộ và/hoặc cấu trúc dữ liệu của họ.

7.5.2 Thuật ngữ • Giao diện vòng lặp: Giao diện cho một đối tượng thực hiện. • Trình lặp cụ thể: (có thể lặp lại) đối tượng khởi tạo thực hiện trình lặp và chứa một tập hợp các tập hợp. • Giao diện tổng hợp: Một giao diện để xác định tổng hợp (đối tượng). • Tập hợp cụ thể: Đối tượng thực hiện giao diện tổng hợp.

7.5.3 Iterator UML Sơ đồ iiterator + has_next (): bool + next (): đối tượng

Ứng dụng máy khách Iterator

Iaggregate + trường: loại + phương pháp (loại): loại

Iaggregate

+ index: int + bộ sưu tập: danh sách

+ trường: gõ

+ has_next (): bool + next (): đối tượng

+ phương pháp (loại): loại

7.5.4 Mã nguồn Trong ví dụ khái niệm này, tôi tạo 4 đối tượng được gọi là tổng hợp và nhóm chúng thành một bộ sưu tập.

Bản quyền © 2019-2021 Sean Bradley

- 180/238 -

7.5.4 Mã nguồn

Chúng là các đối tượng rất tối thiểu thực hiện một phương pháp in một dòng. Sau đó tôi tạo ra một sự khác biệt và vượt qua trong bộ sưu tập các tập hợp. Bây giờ tôi có thể đi qua các tập hợp thông qua giao diện có thể lặp lại.

. . ). . Phương thức def (): "Một phương pháp để thực hiện"

Bản quyền © 2019-2021 Sean Bradley

- 181/238 -

7.5.5 đầu ra

Lớp tổng hợp (IAGGREGATE): "Một đối tượng cụ thể" @staticmethod def (): in ("Phương thức này đã được gọi") # máy khách tổng hợp = [tổng hợp (), tổng hợp (), tổng hợp () # Tập hợp là một danh sách Python đã được lặp lại theo mặc định. # Nhưng dù sao chúng ta cũng có thể tạo trình lặp riêng trên đầu. Itable = itable (tổng hợp) trong khi itable.has_next (): itable.next (). Method ()

7.5.5 Python đầu ra.

7.5.6 ID Video sử dụng vòng lặp SBCode ID #E39A6B

Một lý do cho việc không sử dụng các cấu trúc dữ liệu Python sẵn có triển khai các trình lặp hoặc sử dụng hàm iter trực tiếp qua một bộ sưu tập hiện có, trong trường hợp bạn muốn tạo một đối tượng có thể tạo tự động các đối tượng được lặp, bạn muốn một thứ tự tùy chỉnh của đối tượng hoặc một trình lặp vô hạn. Trình lặp trong ví dụ ngắn gọn này sẽ trả về số tiếp theo trong trình lặp nhân được nhân với 2 mô đun 11. Nó tự động tạo đối tượng được trả về (số) khi chạy. Nó không có phương thức has_next () vì kết quả được điều chỉnh bởi 11, điều đó sẽ lặp lại kết quả cho dù chỉ số vòng lặp lớn đến đâu. Nó cũng sẽ xuất hiện để xen kẽ giữa một loạt các số chẵn và số lẻ. Ngoài ra, chỉ để chứng minh rằng việc thực hiện các lớp và giao diện trừu tượng không phải lúc nào cũng cần thiết, ví dụ này không sử dụng các lớp hoặc giao diện cơ sở trừu tượng.

Bản quyền © 2019-2021 Sean Bradley

- 182/238 -

7.5.7 Ví dụ Sơ đồ UML

7.5.7 Ví dụ Sơ đồ UML SốWheel + Index: Int

Ứng dụng khách hàng

+ next (): đối tượng

return self.index * 2 % 11

7.5.8 Mã nguồn ./builder/client.py "Khái niệm mẫu Iterator"

Lớp sốWheel (): # pylint: vô hiệu hóa = quá công khai " Trong bánh xe "" "self.index = self.index + 1 return self.index * 2 % 11

# Máy khách numberwheel = numberwheel () cho i trong phạm vi (22): in (numberwheel.next (), end = ",")

7.5.9 Python đầu ra. 7, 9, 0,

Bản quyền © 2019-2021 Sean Bradley

- 183/238 -

7.5.10 Khái niệm mã hóa mới

7.5.10 Khái niệm mã hóa mới Python iter () SBCode Video ID #86DB0F

Danh sách Python, từ điển, bộ và bộ dữ liệu đã có thể lặp lại, vì vậy nếu bạn muốn lặp lại cơ bản để sử dụng trong một vòng lặp, thì bạn chỉ cần thêm các đối tượng của mình vào một trong số đó và nó có thể được sử dụng ngay lập tức. Tên = ['Sean', 'Cosmo', 'Emmy'] cho tên trong Tên: In (Tên, End = ",") Tuple hoặc được đặt bằng cách sử dụng phương thức python iter () hoặc phương thức __iter __ () của chính nó, và sau đó lặp lại điều đó bằng cách sử dụng

__next __ () Phương thức. Name = ['sean', 'cosmo', 'emmy'] iterator = iter (tên) in (iterator .__ tiếp theo __ ()) in (iterator .__ tiếp theo __ ()) in (iterator .__ tiếp theo __ ()) hoặc tên = [' Sean ',' cosmo ',' emmy '] iterator = name Chấp nhận một tham số Sentinel. Tham số Sentinel rất hữu ích cho các đối tượng được tạo động được trả về từ một trình lặp và cho biết vị trí cuối cùng nằm trong trình lặp bằng cách nâng ngoại lệ dừng. Cách sử dụng: iter (đối tượng, sentinel) Khi sử dụng sentinel, đối tượng được chuyển làm đối số đầu tiên trong phương thức iter () sẽ cần phải được gọi. Lớp nhân đôi (): Đếm = 1

Bản quyền © 2019-2021 Sean Bradley

- 183/238 -

7.5.10 Khái niệm mã hóa mới

7.5.10 Khái niệm mã hóa mới Python iter () SBCode Video ID #86DB0F

Danh sách Python, từ điển, bộ và bộ dữ liệu đã có thể lặp lại, vì vậy nếu bạn muốn lặp lại cơ bản để sử dụng trong một vòng lặp, thì bạn chỉ cần thêm các đối tượng của mình vào một trong số đó và nó có thể được sử dụng ngay lập tức. Tên = ['Sean', 'Cosmo', 'Emmy'] cho tên trong Tên: In (Tên, End = ",") Tuple hoặc được đặt bằng cách sử dụng phương thức python iter () hoặc phương thức __iter __ () của chính nó, và sau đó lặp lại điều đó bằng cách sử dụng

__next __ () Phương thức. Name = ['sean', 'cosmo', 'emmy'] iterator = iter (tên) in (iterator .__ tiếp theo __ ()) in (iterator .__ tiếp theo __ ()) in (iterator .__ tiếp theo __ ()) hoặc tên = [' Sean ',' cosmo ',' emmy '] iterator = name Chấp nhận một tham số Sentinel. Tham số Sentinel rất hữu ích cho các đối tượng được tạo động được trả về từ một trình lặp và cho biết vị trí cuối cùng nằm trong trình lặp bằng cách nâng ngoại lệ dừng. Cách sử dụng: iter (đối tượng, sentinel) Khi sử dụng sentinel, đối tượng được chuyển làm đối số đầu tiên trong phương thức iter () sẽ cần phải được gọi. Lớp nhân đôi (): Đếm = 1

Bản quyền © 2019-2021 Sean Bradley

- 183/238 -

7.5.10 Khái niệm mã hóa mới

7.5.10 Khái niệm mã hóa mới Python iter () SBCode Video ID #86DB0F

Danh sách Python, từ điển, bộ và bộ dữ liệu đã có thể lặp lại, vì vậy nếu bạn muốn lặp lại cơ bản để sử dụng trong một vòng lặp, thì bạn chỉ cần thêm các đối tượng của mình vào một trong số đó và nó có thể được sử dụng ngay lập tức. Tên = ['Sean', 'Cosmo', 'Emmy'] cho tên trong Tên: In (Tên, End = ",") Tuple hoặc được đặt bằng cách sử dụng phương thức python iter () hoặc phương thức __iter __ () của chính nó, và sau đó lặp lại điều đó bằng cách sử dụng

7.6.2 Thuật ngữ • Giao diện hòa giải: Một giao diện mà hòa giải viên và đồng nghiệp thực hiện. Lưu ý rằng các đồng nghiệp khác nhau sẽ có các trường hợp sử dụng khác nhau và sẽ không cần phải thực hiện tất cả các phương pháp được mô tả trong giao diện hòa giải. • Người hòa giải cụ thể: Nguồn duy nhất của sự thật và điều phối viên truyền thông giữa các thành phần (đồng nghiệp).

Bản quyền © 2019-2021 Sean Bradley

- 186/238 -

7.6.3 Sơ đồ hòa giải UML

• Các lớp đồng nghiệp: Một trong nhiều loại thành phần cụ thể sử dụng chất hòa giải cho trường hợp sử dụng cụ thể của riêng mình.

7.6.3 Hòa giải UML Sơ đồ IMEDIATOR + Trường: Loại + Phương pháp (Loại): Loại

Đồng nghiệp1

Đồng nghiệp2

+ trường: gõ

+ trường: gõ

+ phương pháp (loại): loại

+ phương pháp (loại): loại

Hòa giải + Trường: Loại + Phương thức (Loại): Loại

7.6.4 Mã nguồn Trong khái niệm ví dụ, có hai lớp đồng nghiệp sử dụng các phương thức của nhau. Thay vì các đồng nghiệp gọi trực tiếp các phương thức của nhau, họ thực hiện giao diện hòa giải và gọi nhau thông qua hòa giải viên. Mỗi lớp hoặc quy trình đồng nghiệp được thiết kế cho một mục đích khác nhau, nhưng chúng sử dụng một số chức năng liên quan với nhau. Hệ thống sẽ hoạt động mà không cần hòa giải viên, nhưng việc thêm hòa giải viên sẽ cho phép mở rộng chức năng cho một đồng nghiệp thứ ba tiềm năng cung cấp một dịch vụ khác, chẳng hạn như phân tích hoặc giám sát AI, mà không cần thêm hỗ trợ hoặc kiến ​​thức cụ thể vào hai đồng nghiệp ban đầu.

.

Bản quyền © 2019-2021 Sean Bradley

- 187/238 -

7.6.4 Mã nguồn

@StaticMethod @abstractmethod def cleague1_method (): "Một phương pháp để thực hiện" @staticmethod @abstractmethod def cleague2_method (): " COLLEAGUE1 = COLLEAGUE1 () self.ColleAGUE2 = COLLEAGUE2 () DEF ALLEAGUE1_METHOD (self): return self.ColleaGue1.Colleague1_Method () def cleague2_method (self): return self. đồng nghiệp khác thông qua hòa giải viên "def cleague1_method (self): return" Đây là dữ liệu cụ thể của đồng nghiệp1 mà bạn đã yêu cầu "DEF COLLEAGUE2_METHOD (self):" không thực hiện "đồng nghiệp của lớp Người hòa giải "Def COLLEAGUE1_METHOD (self):" Không được triển khai "DEF CELLEAGUE2_METHOD (self): Return" Đây là dữ liệu cụ thể của đồng nghiệp2 mà bạn đã yêu cầu " # khách hàng này là CELLEAGUE1 hoặc CELLEAGUE2 # Đồng nghiệp này sẽ khởi tạo một hòa giải viên, thay vì CA lling # đồng nghiệp khác trực tiếp. Hòa giải = mediator () # Nếu tôi là đồng nghiệp1, tôi muốn một số dữ liệu từ colleage2 data = mediator.colleaGue2_method () in

Bản quyền © 2019-2021 Sean Bradley

- 188/238 -

7.6.5 đầu ra

# Nếu tôi là CELLEAGUE2, tôi muốn một số dữ liệu từ CELLEAGUE1 DATA = mediator.ColleaGue1_Method () in (f "colleage2 {data}")

7.6.5 Python đầu ra.

7.6.6 Hòa giải sử dụng trường hợp SBCode Video ID #4429BF

Đây là một công cụ trò chơi đơn giản hóa. Có thành phần chính của trò chơi động cơ, một trình lập lịch quản lý các sự kiện trò chơi và có những khách hàng trò chơi đóng vai trò là người chơi trò chơi riêng biệt gửi cược vào một vòng trò chơi. Tất cả các thành phần thực hiện giao diện trung gian. Tất cả đều thực hiện một hoặc một số phương pháp khác nhau tùy thuộc vào mục đích của họ. Mặc dù tất cả đều thực hiện các loại chức năng khác nhau, tất cả đều yêu cầu một nguồn sự thật duy nhất là công cụ trò chơi hoạt động như người hòa giải. Có hỗn hợp của ví dụ hòa giải này bằng cách sử dụng mẫu người quan sát để thông báo cho các máy khách trò chơi, cũng như các phương pháp cụ thể không nhất thiết được chia sẻ giữa trình lập lịch, công cụ trò chơi và khách hàng nhưng được hưởng lợi từ việc được quản lý thông qua hòa giải viên. Thông thường các quy trình được trung gian sẽ chạy từ các máy chủ hoặc chương trình khác nhau, nhưng trong ví dụ này, tất cả chúng đều là một phần của cùng một khách hàng để chứng minh khái niệm dễ dàng hơn.

Bản quyền © 2019-2021 Sean Bradley

- 189/238 -

7.6.7 Sơ đồ uml ví dụ

7.6.7 Ví dụ Sơ đồ UML Gameclient1

Gameclient2

Gameclient3

- _alias - _player - _game_engine

- _alias - _player - _game_engine

- _alias - _player - _game_engine

+ add_player (người chơi)

+ add_player (người chơi)

+ add_player (người chơi)

GameEngine

IgameEngine

- _Players - _game_winners - _game_result + new_game () + add_player () + list_winners () + calculate_winners ()

+ new_game () + add_player () + list_winners () + calculate_winners () + notify_winners () + game_result ()

Trình lập lịch + new_game () + calculation_winners () + notify_winners ()

7.6.8 Mã nguồn.

Game_Engine Nhập GameEngine Game_Client Nhập khẩu Gameclient Player Trình lập lịch trình lập lịch trình lập lịch trình

# Quy trình GameEngine cụ thể sẽ chạy trên máy khách máy chủ chuyên dụng GameEngine = GameEngine () # 3 Trò chơi giả thuyết, tất cả đều chạy bên ngoài trên điện thoại di động # Gọi Trò chơi GameEngine Mediator trên mạng Không

Bản quyền © 2019-2021 Sean Bradley

- 190/238 -

7.6.8 Mã nguồn

Player3 = player ("emmy", 300,) MobileClient3.Add_player (Player3) # A SceceDuler là một quy trình riêng biệt quản lý các vòng trò chơi và # kích hoạt các sự kiện trò chơi vào khoảng thời gian Khách hàng trò chơi đã nhận được thông báo về trò chơi mới, # hiện họ đặt ở đó Bets Player1.place_bets ([1, 2, 3]) người chơi2.place_bets ([5, 6, 7, 8]) người chơi3.place_bets ([10, 11] ) # Trình lập lịch đóng vòng và kích hoạt kết quả và # winnings thông báo lập lịch.

. staticmethod @abstractmethod def add_player (người chơi): "một phương thức để thực hiện" @staticmethod @abstractmethod def list_winners (): "một phương thức để triển khai" @staticmethod @abstractmethod def calculations (): " © 2019-2021 Sean Bradley

- 191/238 -

7.6.8 Mã nguồn

Player3 = player ("emmy", 300,) MobileClient3.Add_player (Player3) # A SceceDuler là một quy trình riêng biệt quản lý các vòng trò chơi và # kích hoạt các sự kiện trò chơi vào khoảng thời gian Khách hàng trò chơi đã nhận được thông báo về trò chơi mới, # hiện họ đặt ở đó Bets Player1.place_bets ([1, 2, 3]) người chơi2.place_bets ([5, 6, 7, 8]) người chơi3.place_bets ([10, 11] ) # Trình lập lịch đóng vòng và kích hoạt kết quả và # winnings thông báo lập lịch.

. staticmethod @abstractmethod def add_player (người chơi): "một phương thức để thực hiện" @staticmethod @abstractmethod def list_winners (): "một phương thức để triển khai" @staticmethod @abstractmethod def calculations (): " © 2019-2021 Sean Bradley

- 191/238 -

7.6.8 Mã nguồn

Player3 = player ("emmy", 300,) MobileClient3.Add_player (Player3) # A SceceDuler là một quy trình riêng biệt quản lý các vòng trò chơi và # kích hoạt các sự kiện trò chơi vào khoảng thời gian Khách hàng trò chơi đã nhận được thông báo về trò chơi mới, # hiện họ đặt ở đó Bets Player1.place_bets ([1, 2, 3]) người chơi2.place_bets ([5, 6, 7, 8]) người chơi3.place_bets ([10, 11] ) # Trình lập lịch đóng vòng và kích hoạt kết quả và # winnings thông báo lập lịch.

. staticmethod @abstractmethod def add_player (người chơi): "một phương thức để thực hiện" @staticmethod @abstractmethod def list_winners (): "một phương thức để triển khai" @staticmethod @abstractmethod def calculations (): " © 2019-2021 Sean Bradley

- 191/238 -

Bản quyền © 2019-2021 Sean Bradley

- 190/238 -

7.6.8 Mã nguồn

Player3 = player ("emmy", 300,) MobileClient3.Add_player (Player3) # A SceceDuler là một quy trình riêng biệt quản lý các vòng trò chơi và # kích hoạt các sự kiện trò chơi vào khoảng thời gian Khách hàng trò chơi đã nhận được thông báo về trò chơi mới, # hiện họ đặt ở đó Bets Player1.place_bets ([1, 2, 3]) người chơi2.place_bets ([5, 6, 7, 8]) người chơi3.place_bets ([10, 11] ) # Trình lập lịch đóng vòng và kích hoạt kết quả và # winnings thông báo lập lịch.

. last_winnings = 0 def place_bets (self, cược): "Khi người chơi đặt cược, số dư của nó được khấu trừ" cho _ trong cược: self.balance -= 1 self.bets = bets @staticmethod def thông báo (tin nhắn): "Người chơi là người quan sát trò chơi "in (tin nhắn)

Bản quyền © 2019-2021 Sean Bradley

- 194/238 -

7.6.9 đầu ra

7.6.9 Đầu ra Python.exe ./mediator/client.py Sean -> Trò chơi mới, đặt cược Cosmo -> Trò chơi mới, đặt cược Emmy -> Trò chơi mới, đặt cược Emmy -> Bạn là người chiến thắng với kết quả `10` . Bạn đã thắng 12. Số dư của bạn = 310

7.6.10 Khái niệm mã hóa mới Chỉ gạch dưới _ ID video SBCode biến #76BF69

Trong lớp người chơi, có một vòng lặp lặp lại danh sách đặt cược. Đối với _ trong đặt cược: self.balance -= 1 _ được sử dụng thay vì nhiều truyền thống I, x, y hoặc biến khác. Nếu sử dụng một chữ cái trong vòng lặp For, và không thực sự sử dụng nó, như trong ví dụ trên, thì pylint sẽ chỉ ra một cảnh báo về biến không sử dụng. Lưu ý rằng trình thông dịch Python vẫn sẽ chạy mã này OK nếu sử dụng chữ cái làm tên biến, nhưng việc giảm cảnh báo pylint giúp mã trông gọn gàng hơn. Ví dụ: đối với tôi trong các cược: tự.

7.6.11 Tóm tắt • Một hòa giải thay thế một cấu trúc với các tương tác nhiều đến nhiều giữa các lớp và quy trình của nó, với cấu trúc tập trung một-nhiều trong đó giao diện hỗ trợ tất cả các phương pháp của cấu trúc nhiều-đến, nhưng thông qua thành phần hòa giải thay thế. • Mẫu trung gian khuyến khích sử dụng các đối tượng được chia sẻ hiện có thể được quản lý và đồng bộ hóa tập trung.

Bản quyền © 2019-2021 Sean Bradley

- 194/238 -

7.6.9 đầu ra

7.6.9 Đầu ra Python.exe ./mediator/client.py Sean -> Trò chơi mới, đặt cược Cosmo -> Trò chơi mới, đặt cược Emmy -> Trò chơi mới, đặt cược Emmy -> Bạn là người chiến thắng với kết quả `10` . Bạn đã thắng 12. Số dư của bạn = 310

Bản quyền © 2019-2021 Sean Bradley

7.6.10 Khái niệm mã hóa mới Chỉ gạch dưới _ ID video SBCode biến #76BF69

Trong lớp người chơi, có một vòng lặp lặp lại danh sách đặt cược. Đối với _ trong đặt cược: self.balance -= 1 _ được sử dụng thay vì nhiều truyền thống I, x, y hoặc biến khác. Nếu sử dụng một chữ cái trong vòng lặp For, và không thực sự sử dụng nó, như trong ví dụ trên, thì pylint sẽ chỉ ra một cảnh báo về biến không sử dụng. Lưu ý rằng trình thông dịch Python vẫn sẽ chạy mã này OK nếu sử dụng chữ cái làm tên biến, nhưng việc giảm cảnh báo pylint giúp mã trông gọn gàng hơn. Ví dụ: đối với tôi trong các cược: tự.

7.6.11 Tóm tắt • Một hòa giải thay thế một cấu trúc với các tương tác nhiều đến nhiều giữa các lớp và quy trình của nó, với cấu trúc tập trung một-nhiều trong đó giao diện hỗ trợ tất cả các phương pháp của cấu trúc nhiều-đến, nhưng thông qua thành phần hòa giải thay thế. • Mẫu trung gian khuyến khích sử dụng các đối tượng được chia sẻ hiện có thể được quản lý và đồng bộ hóa tập trung.

- 195/238 -

7.6.11 Tóm tắt

• Mẫu trung gian tạo ra sự trừu tượng giữa hai hoặc nhiều thành phần sau đó làm cho một hệ thống dễ hiểu và quản lý hơn. • Mẫu trung gian tương tự như mẫu mặt tiền, ngoại trừ hòa giải dự kiến ​​sẽ giao dịch dữ liệu cả hai cách giữa hai hoặc nhiều lớp hoặc quy trình khác thường tương tác trực tiếp với nhau.

- 196/238 -

7,7 mẫu thiết kế Memento

7.7 Mẫu thiết kế Memento 7.7.1 Tổng quan về video SBCode #A37AE3

Trong suốt vòng đời của một ứng dụng, trạng thái đối tượng có thể thay đổi. Bạn có thể muốn lưu trữ một bản sao của trạng thái hiện tại trong trường hợp truy xuất sau này. Ví dụ: khi viết tài liệu, bạn có thể muốn tự động lưu trạng thái hiện tại cứ sau 10 phút. Hoặc bạn có một trò chơi và bạn muốn lưu vị trí hiện tại của người chơi ở cấp độ, với điểm số và hàng tồn kho hiện tại của nó. Bạn có thể sử dụng mẫu Memento để lưu một bản sao của trạng thái và để truy xuất sau này nếu cần thiết. Mẫu Memento, giống như mẫu lệnh, cũng thường được sử dụng để thực hiện chức năng hoàn tác/ làm lại trong ứng dụng của bạn. Sự khác biệt giữa lệnh và các mẫu vật lưu cho hoàn tác/làm lại, là trong mẫu lệnh, bạn thực hiện lại các lệnh theo cùng một thứ tự đã thay đổi các thuộc tính của trạng thái và với vật lưu niệm, bạn hoàn toàn thay thế trạng thái bằng cách truy xuất từ Một bộ đệm/cửa hàng.

Bản quyền © 2019-2021 Sean Bradley

7.7.2 Thuật ngữ • Người khởi tạo: Người khởi tạo là một đối tượng có trạng thái nội bộ thay đổi thỉnh thoảng. • Caretaker: (Người bảo vệ) Một lớp yêu cầu người khởi tạo tạo hoặc khôi phục các vật lưu niệm. Người chăm sóc hơn là lưu chúng vào bộ nhớ cache hoặc kho lưu trữ vật kỷ niệm. • Memento: Một bản sao trạng thái bên trong của người khởi tạo mà sau này có thể được khôi phục trở lại người khởi tạo để thay thế trạng thái hiện tại của nó.

7.7.3 Memento UML Sơ đồ người khởi tạo + trạng thái + Memento

Người chăm sóc ứng dụng khách hàng - _originator - _Mementos

Memento n

+ trạng thái

người khởi tạo lớp (): "Đối tượng trong ứng dụng có trạng thái thay đổi" def __init __ (self): self._state = "" State.Setter def State (self, state): in (f "Người khởi tạo: Đặt trạng thái thành` {state} `") self._state = state @property def memento (self): "a` getter` cho trạng thái đối tượng nhưng đóng gói như một vật kỷ niệm "

Bản quyền © 2019-2021 Sean Bradley

- 198/238 -

7.7.4 Mã nguồn

in ("Người khởi tạo: Cung cấp Memento of State cho người chăm sóc.") Trả lại Memento (self._state) @memento.setter def memento (self, memento): self._state = memento.state in (f " Memento: "f" `{self._state}` ")

class caretaker (): "Guardian. Cung cấp giao diện hẹp cho Mementos" def __init __ (self, người khởi tạo): self._originator = người khởi tạo self._mementos = [] def created (self): " trạng thái "in (" người chăm sóc: nhận bản sao của người khởi tạo trạng thái hiện tại ") memento = self._originator.memento self._mementos.append (memento) def restore (self, index):" "" Thay thế trạng thái hiện tại của người khởi tạo bằng trạng thái Được lưu trữ trong Memento đã lưu "" "in (" Người chăm sóc: Khôi phục trạng thái người khởi tạo từ Memento ")

# Trình khởi tạo khách hàng = người khởi tạo () chăm sóc = người chăm sóc (người khởi tạo) # Người khởi tạo trạng thái có thể thay đổi định kỳ do các sự kiện ứng dụng Người khởi tạo.state = "State # 1" Người khởi tạo.State = "State # 2" # cho phép sao lưu người khởi tạo. .

Bản quyền © 2019-2021 Sean Bradley

- 198/238 -

7.7.4 Mã nguồn

in ("Người khởi tạo: Cung cấp Memento of State cho người chăm sóc.") Trả lại Memento (self._state) @memento.setter def memento (self, memento): self._state = memento.state in (f " Memento: "f" `{self._state}` ")

class caretaker (): "Guardian. Cung cấp giao diện hẹp cho Mementos" def __init __ (self, người khởi tạo): self._originator = người khởi tạo self._mementos = [] def created (self): " trạng thái "in (" người chăm sóc: nhận bản sao của người khởi tạo trạng thái hiện tại ") memento = self._originator.memento self._mementos.append (memento) def restore (self, index):" "" Thay thế trạng thái hiện tại của người khởi tạo bằng trạng thái Được lưu trữ trong Memento đã lưu "" "in (" Người chăm sóc: Khôi phục trạng thái người khởi tạo từ Memento ")

# Trình khởi tạo khách hàng = người khởi tạo () chăm sóc = người chăm sóc (người khởi tạo) # Người khởi tạo trạng thái có thể thay đổi định kỳ do các sự kiện ứng dụng Người khởi tạo.state = "State # 1" Người khởi tạo.State = "State # 2" # cho phép sao lưu người khởi tạo. .

- 199/238 -

Bản quyền © 2019-2021 Sean Bradley

7,7,5 trường hợp sử dụng vật liệu

# Nhiều thay đổi hơn Người khởi tạo.State = "State # 4" Print (interforator.state) # Khôi phục từ người chăm sóc bản sao lưu đầu tiên.Restore (0) in (instrimator.state) # Khôi phục từ người chăm sóc bản sao lưu thứ hai.Restore (1) in (người khởi tạo. tiểu bang)

Đầu ra Python ./memento/memento_concept.py Người khởi tạo: Đặt trạng thái thành `Nhà xuất bản #1` Người khởi tạo: Đặt trạng thái thành` Nhà nước #2` Caretaker: Nhận bản sao của người khởi tạo người khởi tạo hiện tại Người khởi tạo: Đặt trạng thái thành `CARETAKER #3` State: Nhận một bản sao của người khởi tạo người khởi tạo hiện tại: Cung cấp vật liệu lưu trữ cho người chăm sóc. Người khởi tạo: Thiết lập trạng thái thành `Bang #4` State #4 Caretaker: Khôi phục người khởi tạo Nhà nước từ Memento Người khởi tạo: Nhà nước sau khi khôi phục từ Memento:` State #2` State #2 Caretaker: Reserving Nhà khởi tạo Nhà nước từ Memento : `State #3` State #3

7,7.5 Memento sử dụng trường hợp ID video SBCode #0A7255

Có một trò chơi, và nhân vật đang tiến triển thông qua các cấp độ. Nó đã có được một số mặt hàng mới trong kho của nó, điểm số rất tốt và bạn muốn lưu tiến độ của mình và tiếp tục sau đó. Sau đó, bạn quyết định bạn đã phạm sai lầm và cần phải quay lại một lần lưu trước đó vì bạn đã rẽ sai.

- 200/238 -

7.7.6 Sơ đồ UML ví dụ

7.7.6 Ví dụ Sơ đồ UML Gamecharacter - _Score - _Inventory - _Level - _Location + memento + scord

Bản quyền © 2019-2021 Sean Bradley

Ứng dụng khách hàng

Chăm sóc - _originator - _Mementos + save () + restore ()

Memento n

+ điểm + hàng tồn kho + cấp + vị trí

- 202/238 -

7.7.7 Mã nguồn

Def Progress_TO_Next_Level (self): "The Characer tiến tới cấp độ tiếp theo" self._Level += 1 def move_forward (self, số lượng): "Nhân vật di chuyển xung quanh môi trường" tự._location ["z"] += số lượng def __str__ . n ") @ property def memento (self):" a `getter` cho các thuộc tính ký tự như một vật kỷ niệm" trả lại memento (self._score, self._inventory.copy (), self._level, self._location.copy () ) @ memento.setter def memento (self, memento): self._score = memento.score self._inventory = memento.inventory self._level = memento.level self._location = memento.location

. Def Save (self): "

- 203/238 -

7.7.8 Đầu ra

self._mementos.Append (memento) def restore (self, index): "" ._Mementos [index] self._originator.memento = memento

. Vị trí): self.score = selce self.inventory = inventory self.level = level self.location = vị trí

7.7.8 Đầu ra Python ./memento/client.py Điểm: 200, Cấp: 0, Vị trí: {'X': 0, 'y': 0, 'Z': 2} Hàng tồn kho: {'Rifle', 'Kiếm '} Caretaker: trò chơi lưu điểm: 500, cấp: 1, vị trí: {' x ': 0,' y ': 0,' z ': 13} hàng tồn kho: {' motorbike ',' súng trường ',' kiếm '} Caretaker: Game Lưu Điểm: 600, Cấp độ: 2, Vị trí: {'X': 0, 'Y': 0, 'Z': 14} Hàng tồn kho: {'Motorbike', 'Súng trường', 'Kiếm' Khôi phục các ký tự thuộc tính từ Memento Score: 200, Cấp độ: 0, Vị trí: {'X': 0, 'Y': 0, 'Z': 2} Hàng tồn kho: {'Súng trường', 'Kiếm'}

Bản quyền © 2019-2021 Sean Bradley

- 204/238 -

7.7.9 Khái niệm mã hóa mới

7.7.9 Khái niệm mã hóa mới Python getter/setters sbcode video ID #A55E85

Thông thường khi các thuộc tính mã hóa trong các lớp, bạn có thể muốn cung cấp các phương thức để cho phép các hàm bên ngoài đọc hoặc sửa đổi các thuộc tính nội bộ của lớp. Một cách tiếp cận phổ biến sẽ là thêm hai phương thức được đặt trước với get_ và set_, lớp học tập = value example = exempleclass () in (ví dụ.get_value ()) Điều này có ý nghĩa hoàn hảo về ý định là gì, nhưng có một cách làm điều này nhiều hơn và đó là bằng cách sử dụng Python @property trang trí. LỚP SISSCLECLASS: def __init __ (self): self._value = 123 @property def value (self): return self._value @value.setter def value (self, giá trị): self._value = value example = exempleclass () Ví dụ .Value) Lưu ý rằng trong ví dụ trên, có một trình trang trí bổ sung có tên @value.setter. Điều này được sử dụng để thiết lập thuộc tính _Value. Cùng với hai phương thức Getter/Setter mới ở trên, cũng có một phương thức khác để xóa một thuộc tính có tên là Deleter.

Bản quyền © 2019-2021 Sean Bradley

- 204/238 -

7.7.9 Khái niệm mã hóa mới

7.7.9 Khái niệm mã hóa mới Python getter/setters sbcode video ID #A55E85

Thông thường khi các thuộc tính mã hóa trong các lớp, bạn có thể muốn cung cấp các phương thức để cho phép các hàm bên ngoài đọc hoặc sửa đổi các thuộc tính nội bộ của lớp. Một cách tiếp cận phổ biến sẽ là thêm hai phương thức được đặt trước với get_ và set_, lớp học tập = value example = exempleclass () in (ví dụ.get_value ()) Điều này có ý nghĩa hoàn hảo về ý định là gì, nhưng có một cách làm điều này nhiều hơn và đó là bằng cách sử dụng Python @property trang trí. LỚP SISSCLECLASS: def __init __ (self): self._value = 123 @property def value (self): return self._value @value.setter def value (self, giá trị): self._value = value example = exempleclass () Ví dụ .Value) Lưu ý rằng trong ví dụ trên, có một trình trang trí bổ sung có tên @value.setter. Điều này được sử dụng để thiết lập thuộc tính _Value. Cùng với hai phương thức Getter/Setter mới ở trên, cũng có một phương thức khác để xóa một thuộc tính có tên là Deleter.

Bản quyền © 2019-2021 Sean Bradley

- 206/238 -

7.8 Mô hình thiết kế trạng thái

7.8 Mô hình thiết kế trạng thái 7.8.1 Tổng quan về video SBCode #11B6DA

Không bị nhầm lẫn với trạng thái đối tượng, tức là, một trong những thuộc tính có thể được sao chép dưới dạng ảnh chụp nhanh, mẫu trạng thái quan tâm nhiều hơn đến việc thay đổi xử lý phương thức của một đối tượng một cách linh hoạt. Điều này làm cho một đối tượng tự động hơn và có thể làm giảm nhu cầu của nhiều tuyên bố có điều kiện. Thay vì lưu trữ một giá trị trong một thuộc tính, sau đó sử dụng các câu lệnh có điều kiện trong một phương thức đối tượng để tạo ra đầu ra khác nhau, một lớp con được gán làm tay cầm thay thế. Đối tượng/ bối cảnh không cần biết về hoạt động bên trong của lớp con được gán mà nhiệm vụ được giao. Trong mẫu trạng thái, hành vi của trạng thái đối tượng được gói gọn trong các lớp con được gán động để xử lý nó.

7.8.2 Thuật ngữ • Giao diện trạng thái: Một giao diện để gói gọn hành vi liên quan đến một trạng thái cụ thể của bối cảnh. • Các lớp con bê tông: Mỗi lớp con thực hiện một hành vi liên quan đến trạng thái cụ thể. • Bối cảnh: Đây là đối tượng mà trạng thái được xác định, nhưng việc thực hiện hành vi trạng thái được chuyển hướng đến lớp con bê tông.

7.8.3 Bối cảnh sơ đồ UML trạng thái

Tôi tuyên bố

+ Yêu cầu ()

+ phương pháp (loại): loại

state.handle ()

Concretestatea + Phương thức (loại): Loại

ConcretestateB + Phương thức (Loại): Loại

Bản quyền © 2019-2021 Sean Bradley

ConcretestateC + Phương thức (Loại): Loại

- 207/238 -

7.8.4 Mã nguồn

7.8.4 Mã nguồn Trong ví dụ khái niệm, có ba trạng thái có thể. Mỗi khi phương thức yêu cầu () được gọi, lớp con trạng thái cụ thể được chọn ngẫu nhiên bởi ngữ cảnh.

. . Giá trị của self.handle "" "self.handle = self.state_handles [Random.randint (0, 2)] return self.Handle class istate (metaclass = abcmeta):" giao diện trạng thái "@staticmethod @abstractmethod def __str __ () : "Đặt phương pháp mặc định" Lớp ConcreteStateA (ISTATE): "Một lớp con bê tông" def __str __ (self): return "Tôi là bê tông". AM ConcretestateB "Lớp Concretestatec (ISTATE):

Bản quyền © 2019-2021 Sean Bradley

- 208/238 -

7.8.5 Trường hợp sử dụng trạng thái

"Một lớp con bê tông" def __str __ (self): return "Tôi là cycretestatec" # Bối cảnh máy khách = bối cảnh () in (bối cảnh.Request ()) (Bối cảnh.Request ()) in (bối cảnh.Request ())

Đầu ra python.exe ./state/state_concept.py tôi là bê tông

7.8.5 Trường hợp sử dụng trạng thái SBCode Video ID #F5B4B7

Ví dụ này đưa ví dụ về khái niệm hơn nữa và sử dụng trình lặp thay vì chọn các lớp tiểu bang một cách ngẫu nhiên. Khi người lặp đi đến cuối, nó sẽ gây ra lỗi dừng lại và tái tạo lại trình lặp để quá trình có thể lặp lại.

7.8.6 Ví dụ trạng thái sử dụng Trường hợp Sơ đồ UML Bối cảnh

Tôi tuyên bố

+ Yêu cầu ()

+ phương pháp (loại): loại

state.handle ()

Concretestatea + Phương thức (loại): Loại

ConcretestateB + Phương thức (Loại): Loại

Bản quyền © 2019-2021 Sean Bradley

ConcretestateC + Phương thức (Loại): Loại

- 207/238 -

7.8.4 Mã nguồn

7.8.4 Mã nguồn Trong ví dụ khái niệm, có ba trạng thái có thể. Mỗi khi phương thức yêu cầu () được gọi, lớp con trạng thái cụ thể được chọn ngẫu nhiên bởi ngữ cảnh.

. . Giá trị của self.handle "" "self.handle = self.state_handles [Random.randint (0, 2)] return self.Handle class istate (metaclass = abcmeta):" giao diện trạng thái "@staticmethod @abstractmethod def __str __ () : "Đặt phương pháp mặc định" Lớp ConcreteStateA (ISTATE): "Một lớp con bê tông" def __str __ (self): return "Tôi là bê tông". AM ConcretestateB "Lớp Concretestatec (ISTATE):

- 208/238 -

7.8.5 Trường hợp sử dụng trạng thái

Bản quyền © 2019-2021 Sean Bradley

"Một lớp con bê tông" def __str __ (self): return "Tôi là cycretestatec" # Bối cảnh máy khách = bối cảnh () in (bối cảnh.Request ()) (Bối cảnh.Request ()) in (bối cảnh.Request ())

Đầu ra python.exe ./state/state_concept.py tôi là bê tông

7.8.5 Trường hợp sử dụng trạng thái SBCode Video ID #F5B4B7

lớp đã hoàn thành (ISTATE): "Một lớp con bê tông" @staticmethod def (): "một nhiệm vụ của lớp này" in ("nhiệm vụ kết thúc") __call__ = Phương thức

# Bối cảnh khách hàng = bối cảnh () bối cảnh

7.8.8 Đầu ra Python.exe.

7.8.9 Khái niệm mã hóa mới Dunder __Call__ Phương pháp ID video SBCode #E0B1F0

Bản quyền © 2019-2021 Sean Bradley

- 211/238 -

7.8.10 Tóm tắt

Quá tải phương thức __call__ tạo ra một thể hiện của một lớp có thể gọi được giống như một hàm khi theo mặc định. Bạn cần gọi trực tiếp một phương thức trong lớp. Class excleclass: @staticmethod def do_this_by_default (): in ("làm này") Ví dụ = exestClass () ví dụ.do_this_by_default () # cần được gọi rõ ràng để thực thi nếu bạn muốn một phương thức mặc định trong lớp của bạn, bạn có thể trỏ đến nó Sử dụng bằng phương pháp __call__. Classcleclass: @staticmethod def do_this_by_default (): in ("Làm điều này")

7.8.10 Tóm tắt • Làm cho một đối tượng thay đổi hành vi của nó khi trạng thái bên trong của nó thay đổi. • Khách hàng và bối cảnh không quan tâm đến các chi tiết về cách nhà nước được tạo/ lắp ráp/ tính toán. Máy khách sẽ gọi một phương thức của bối cảnh và nó sẽ được xử lý bởi một lớp con. • Mẫu trạng thái xuất hiện rất giống với mẫu chiến lược, ngoại trừ trong mẫu trạng thái, đối tượng/bối cảnh đã thay đổi thành một trạng thái khác và sẽ chạy một lớp con khác tùy thuộc vào trạng thái đó.

Bản quyền © 2019-2021 Sean Bradley

- 211/238 -

7.8.10 Tóm tắt

Quá tải phương thức __call__ tạo ra một thể hiện của một lớp có thể gọi được giống như một hàm khi theo mặc định. Bạn cần gọi trực tiếp một phương thức trong lớp. Class excleclass: @staticmethod def do_this_by_default (): in ("làm này") Ví dụ = exestClass () ví dụ.do_this_by_default () # cần được gọi rõ ràng để thực thi nếu bạn muốn một phương thức mặc định trong lớp của bạn, bạn có thể trỏ đến nó Sử dụng bằng phương pháp __call__. Classcleclass: @staticmethod def do_this_by_default (): in ("Làm điều này")

7.8.10 Tóm tắt • Làm cho một đối tượng thay đổi hành vi của nó khi trạng thái bên trong của nó thay đổi. • Khách hàng và bối cảnh không quan tâm đến các chi tiết về cách nhà nước được tạo/ lắp ráp/ tính toán. Máy khách sẽ gọi một phương thức của bối cảnh và nó sẽ được xử lý bởi một lớp con. • Mẫu trạng thái xuất hiện rất giống với mẫu chiến lược, ngoại trừ trong mẫu trạng thái, đối tượng/bối cảnh đã thay đổi thành một trạng thái khác và sẽ chạy một lớp con khác tùy thuộc vào trạng thái đó.

- 212/238 -

Bản quyền © 2019-2021 Sean Bradley

- 211/238 -

7.8.10 Tóm tắt

Quá tải phương thức __call__ tạo ra một thể hiện của một lớp có thể gọi được giống như một hàm khi theo mặc định. Bạn cần gọi trực tiếp một phương thức trong lớp. Class excleclass: @staticmethod def do_this_by_default (): in ("làm này") Ví dụ = exestClass () ví dụ.do_this_by_default () # cần được gọi rõ ràng để thực thi nếu bạn muốn một phương thức mặc định trong lớp của bạn, bạn có thể trỏ đến nó Sử dụng bằng phương pháp __call__. Classcleclass: @staticmethod def do_this_by_default (): in ("Làm điều này")

7.8.10 Tóm tắt • Làm cho một đối tượng thay đổi hành vi của nó khi trạng thái bên trong của nó thay đổi. • Khách hàng và bối cảnh không quan tâm đến các chi tiết về cách nhà nước được tạo/ lắp ráp/ tính toán. Máy khách sẽ gọi một phương thức của bối cảnh và nó sẽ được xử lý bởi một lớp con. • Mẫu trạng thái xuất hiện rất giống với mẫu chiến lược, ngoại trừ trong mẫu trạng thái, đối tượng/bối cảnh đã thay đổi thành một trạng thái khác và sẽ chạy một lớp con khác tùy thuộc vào trạng thái đó.

- 212/238 -

7.9 Mô hình thiết kế chiến lược

7.9 Mẫu thiết kế chiến lược 7.9.1 Tổng quan về video SBCode #545946

Mẫu chiến lược tương tự như mẫu trạng thái, ngoại trừ khách hàng vượt qua trong thuật toán mà bối cảnh nên chạy và việc thực hiện thuật toán không ảnh hưởng đến trạng thái của ngữ cảnh. Thuật toán nên được chứa trong một lớp thực hiện giao diện chiến lược cụ thể. Một ứng dụng sắp xếp dữ liệu là một ví dụ tốt về nơi bạn có thể kết hợp mẫu chiến lược. Có nhiều phương pháp sắp xếp một tập hợp dữ liệu. Ví dụ: Quicksort, Mergesort, Introsort, Heapsort, Bubbledort. Xem https://en.wikipedia.org/wiki/sorting_algorithm để biết thêm ví dụ. Giao diện người dùng của ứng dụng máy khách có thể cung cấp menu thả xuống để cho phép người dùng thử các thuật toán sắp xếp khác nhau. Khi lựa chọn người dùng, một tham chiếu đến thuật toán sẽ được chuyển đến ngữ cảnh và được xử lý bằng thuật toán mới này thay thế. Chiến lược và trạng thái xuất hiện rất giống nhau, một cách tốt để phân biệt chúng là xem xét liệu bối cảnh có được coi là ở trạng thái mới hay không ở nhiều thời điểm khác nhau trong vòng đời. Trong chiến lược, một đối tượng/ngữ cảnh chạy một thuật toán được chọn, nhưng trạng thái của đối tượng/ngữ cảnh không thay đổi trong trường hợp bạn muốn thử một thuật toán khác. Các plugin phần mềm có thể được triển khai bằng cách sử dụng mẫu chiến lược.

7.9.2 Thuật ngữ • Giao diện chiến lược: Một giao diện mà tất cả các lớp con/thuật toán chiến lược phải thực hiện. • Chiến lược cụ thể: Lớp con thực hiện một thuật toán thay thế. • Bối cảnh: Đây là đối tượng nhận chiến lược cụ thể để thực hiện nó.

- 213/238 -

7.9.3 Sơ đồ UML chiến lược

Bản quyền © 2019-2021 Sean Bradley

- 211/238 -

7.8.10 Tóm tắt

Quá tải phương thức __call__ tạo ra một thể hiện của một lớp có thể gọi được giống như một hàm khi theo mặc định. Bạn cần gọi trực tiếp một phương thức trong lớp. Class excleclass: @staticmethod def do_this_by_default (): in ("làm này") Ví dụ = exestClass () ví dụ.do_this_by_default () # cần được gọi rõ ràng để thực thi nếu bạn muốn một phương thức mặc định trong lớp của bạn, bạn có thể trỏ đến nó Sử dụng bằng phương pháp __call__. Classcleclass: @staticmethod def do_this_by_default (): in ("Làm điều này")

7.9.5 Đầu ra python.exe.

7.9.6 Chiến lược sử dụng trường hợp ID video SBCode #89D36A

Một nhân vật trò chơi đang di chuyển qua một môi trường. Tùy thuộc vào tình huống trong môi trường hiện tại, người dùng quyết định sử dụng một thuật toán chuyển động khác. Từ quan điểm của đối tượng/bối cảnh, nó vẫn là một động thái, nhưng việc thực hiện được gói gọn trong lớp con ở tay cầm. Trong một trò chơi thực sự, các loại điều mà một động thái cụ thể có thể ảnh hưởng là hoạt hình nào được lặp lại, cho dù các thuộc tính vật lý đã thay đổi, tốc độ chuyển động, chế độ theo dõi camera và hơn thế nữa.

Bản quyền © 2019-2021 Sean Bradley

- 215/238 -

7.9.7 Ví dụ chiến lược sử dụng Trường hợp Sơ đồ UML

7.9.7 Chiến lược Ví dụ sử dụng Trường hợp Sơ đồ UML Gamecharacter

Tôi di chuyển

+ di chuyển (chuyển động_style)

+ __call__

chuyển động_style ()

Đi dạo

Đang chạy

+ đi bộ ()

+ chạy ()

Crawling + Crawl ()

7.9.8 Mã nguồn. sẽ thay đổi "@staticmethod def di chuyển (chuyển động_style):" Thuật toán chuyển động đã được quyết định bởi máy khách "chuyển động_style () class imove (metaclass = abcmeta):" một giao diện chiến lược cụ thể "@staticmethod @abstractmethod def __call Phải chọn phương thức mặc định "Lớp đi bộ (IMOVE):" Một lớp con chiến lược cụ thể "@staticmethod def Walk ():" Thuật toán đi bộ "in (" Tôi đang đi bộ ") __call__ = Walk

Bản quyền © 2019-2021 Sean Bradley

- 215/238 -

7.9.7 Ví dụ chiến lược sử dụng Trường hợp Sơ đồ UML

7.9.7 Chiến lược Ví dụ sử dụng Trường hợp Sơ đồ UML Gamecharacter

Tôi di chuyển

+ di chuyển (chuyển động_style)

Bản quyền © 2019-2021 Sean Bradley

- 215/238 -

7.9.7 Ví dụ chiến lược sử dụng Trường hợp Sơ đồ UML

7.9.7 Chiến lược Ví dụ sử dụng Trường hợp Sơ đồ UML Gamecharacter

Tôi di chuyển

Bản quyền © 2019-2021 Sean Bradley

- 215/238 -

7.9.7 Ví dụ chiến lược sử dụng Trường hợp Sơ đồ UML

7.9.7 Chiến lược Ví dụ sử dụng Trường hợp Sơ đồ UML Gamecharacter

Tôi di chuyển

+ di chuyển (chuyển động_style)

Copyright © 2019-2021 Sean Bradley

- 219/238 -

7.10.3 Template Method UML Diagram

7.10.3 Template Method UML Diagram AbstractClass + template_method(type): type + step_one(type): type + step_two(type): type + step_three(type): type

ConcreteClassA + step_one(type): type + step_two(type): type + step_three(type): type

ConcreteClassB + step_one(type): type + step_two(type): type + step_three(type): type

ConcreteClassC + step_one(type): type + step_two(type): type + step_three(type): type

7.10.4 Source Code Note that in both the concrete classes in this concept example, the template_method() was not overridden since it was already inherited. Only the primitives (abstract or hooks) were optionally overridden. To create an empty abstract method in your abstract class, that must be overridden in a subclass, then use the ABCMeta @abstractmethod decorator.

./template/template_concept.py # pylint: disable=too-few-public-methods "The Template Method Pattern Concept" from abc import ABCMeta, abstractmethod class AbstractClass(metaclass=ABCMeta): "A template class containing a template method and primitive methods" @staticmethod def step_one(): """ Hooks are normally empty in the abstract class. The implementing class can optionally override providing a custom implementation """ @staticmethod @abstractmethod def step_two(): """

Copyright © 2019-2021 Sean Bradley

- 220/238 -

7.10.4 Source Code

An abstract method that must be overridden in the implementing class. It has been given `@abstractmethod` decorator so that pylint shows the error. """ @staticmethod def step_three(): """ Hooks can also contain default behavior and can be optionally overridden """ print("Step Three is a hook that prints this line by default.") @classmethod def template_method(cls): """ This is the template method that the subclass will call. The subclass (implementing class) doesn't need to override this method since it has would have already optionally overridden the following methods with its own implementations """ cls.step_one() cls.step_two() cls.step_three() class ConcreteClassA(AbstractClass): "A concrete class that only overrides step two" @staticmethod def step_two(): print("Class_A : Step Two (overridden)") class ConcreteClassB(AbstractClass): "A concrete class that only overrides steps one, two and three" @staticmethod def step_one(): print("Class_B : Step One (overridden)") @staticmethod def step_two(): print("Class_B : Step Two. (overridden)") @staticmethod def step_three(): print("Class_B : Step Three. (overridden)") # The Client CLASS_A = ConcreteClassA() CLASS_A.template_method()

Copyright © 2019-2021 Sean Bradley

- 221/238 -

7.10.5 Output

CLASS_B = ConcreteClassB() CLASS_B.template_method()

7.10.5 Output python ./template/template_concept.py Class_A : Step Two (overridden) Step Three is a hook that prints this line by default. Class_B : Step One (overridden) Class_B : Step Two. (overridden) Class_B : Step Three. (overridden)

7.10.6 Template Method Use Case SBCODE Video ID #313583

In the example use case, there is an AbstractDocument with several methods, some are optional and others must be overridden. The document will be written out in two different formats. Depending on the concrete class used, the text() method will wrap new lines with

\ n "document [" text "] = markup [:-1] @staticmethod def in (tài liệu):" Trong ["Tiêu đề", "Mô tả", "Tác giả"]: PRIN "") in (f "{document ['text']}") print ("") print ("")

7.10.9 Đầu ra Python ./template/client.py --------------------- Tiêu đề: Tài liệu văn bản mới Hình nền_Colour: Văn bản trắng: Một số văn bản Bản quyền © 2019-2021 Sean Bradley

Một mô hình cấu trúc hữu ích cho quản lý phân cấp.

Cấu trúc đối tượng của bạn bên trong một ứng dụng có thể phức tạp và đa dạng. Một ví dụ điển hình là những gì có thể được tạo ra bằng cấu trúc tổng hợp. Các đối tượng tạo nên hệ thống phân cấp của các đối tượng, có thể là bất cứ điều gì và rất có thể phức tạp để sửa đổi khi ứng dụng của bạn phát triển. Thay vào đó, khi thiết kế các đối tượng trong ứng dụng của bạn có thể được cấu trúc theo kiểu phân cấp, bạn có thể cho phép chúng thực hiện giao diện khách truy cập. Giao diện khách truy cập mô tả một phương thức Accept () mà một đối tượng khác, được gọi là khách truy cập, sẽ sử dụng để đi qua hệ thống phân cấp đối tượng hiện có và đọc các thuộc tính bên trong của một đối tượng. Mẫu khách truy cập rất hữu ích khi bạn muốn phân tích hoặc sao chép một hệ thống phân cấp đối tượng thay thế mà không thực hiện thêm mã trong các lớp đối tượng, ngoại trừ các yêu cầu ban đầu được đặt bằng cách triển khai giao diện khách truy cập. Tương tự như mẫu mẫu, nó có thể được sử dụng để xuất các phiên bản khác nhau của tài liệu nhưng phù hợp hơn với các đối tượng có thể là thành viên của hệ thống phân cấp.

7.11.2 Thuật ngữ • Giao diện khách truy cập: Giao diện cho khách truy cập cụ thể. • Khách truy cập cụ thể: Khách truy cập cụ thể sẽ đi qua hệ thống phân cấp của các yếu tố. • Giao diện có thể truy cập: Giao diện mà các yếu tố nên thực hiện, mô tả

Phương thức chấp nhận () sẽ cho phép họ được truy cập (đi qua). • Phần tử cụ thể: Một đối tượng sẽ được truy cập. Một ứng dụng sẽ chứa một số lượng các phần tử thay đổi có thể được cấu trúc trong bất kỳ hệ thống phân cấp cụ thể nào.

Một mô hình cấu trúc hữu ích cho quản lý phân cấp.

Tính toáneMenttotalSvisitor. Chúng được khởi tạo và đi qua hệ thống phân cấp đối tượng hiện có bằng cách sử dụng cùng một giao diện IVISIBLE.

. @AbStractMethod def Truy cập (phần tử): "Khách truy cập truy cập các phần tử/đối tượng trong ứng dụng" Lớp iVisitable (metaclass = abcmeta): "" "Một giao diện mà các đối tượng cụ thể nên thực hiện cho phép

Khách truy cập để vượt qua cấu trúc phân cấp của các đối tượng "" "@staticmethod @abstractmethod def Accept (khách truy cập):" " Một phần của bất kỳ phân cấp nào "def __init __ (tự, tên, giá trị, cha mẹ = none): self.name = name self.value = value self. Tự, khách truy cập): "Yêu cầu của khách truy cập sẽ đi qua" đối với phần tử trong self.elements: Element.accept (khách truy cập) Khách truy cập. , 101) Element_b = Element ("B", 305, Element_A) Element_c = Element ("C", 185, Element_A) Element_D = Element ("D", -30, Element_B) # # # # # # # # # #

Bây giờ thay vì thay đổi lớp phần tử để hỗ trợ các hoạt động tùy chỉnh, chúng ta có thể sử dụng phương thức chấp nhận được triển khai trong lớp phần tử vì bổ sung giao diện có thể iVise

Class printEuityNamesVisitor (ivisitor): "Tạo một khách truy cập in tên phần tử" @staticmethod def visit (phần tử): print (phần tử.name) : "Tạo một khách truy cập có tổng số các giá trị phần tử"

TOTAL_VALUE = 0 @classmethod def Truy cập (CLS, phần tử): cls.total_value += Element.value return cls.total_value # Sử dụng calculateLementTotalSvisitor để vượt qua phân cấp # đối tượng Tổng giá trị)

Trong ví dụ, khách hàng tạo ra một chiếc xe với các bộ phận. Chiếc xe và các bộ phận kế thừa một lớp phụ tùng xe hơi trừu tượng với getters và setters thuộc tính được xác định trước. Thay vì tạo các phương thức trong các lớp bộ phận xe hơi và lớp trừu tượng chạy các phương thức bespoke, tất cả các bộ phận xe hơi đều có thể thực hiện giao diện Ivisitor. Điều này cho phép tạo các đối tượng khách truy cập sau này để chạy các tác vụ cụ thể trên hệ thống phân cấp hiện tại của các đối tượng.

Một mô hình cấu trúc hữu ích cho quản lý phân cấp.

Tóm tắtCarpart - _Name - _SKU - _price + name (value) + sku (giá trị) + giá (giá trị)

7.11.8 Mã nguồn.

Từ ABC Nhập ABCMETA, Lớp IVisitor (Metaclass = ABCMeta): "Một giao diện mà khách truy cập tùy chỉnh nên triển khai" @staticmethod @abstractmethod def (phần tử): " : "" "Một giao diện mà các đối tượng cụ thể nên thực hiện cho phép khách truy cập đi qua cấu trúc phân cấp của các đối tượng" "" @staticmethod @abstractmethod Def Accept (khách truy cập): "" "Lớp Tóm tắtCarPart ():" Phần xe trừu tượng "@Property def Tên (tự):" Tên cho phần "return self._name @name.setter def name (self, value) def sku (self): "Đơn vị giữ cổ phiếu (SKU)" tự trả lại._sku @sku.setter def sku (self, value): self._sku = value @property def price (self): "giá trên mỗi đơn vị" trả lại self._price @price.setter DEF price (self, giá trị):

self._price = body class value (Tóm tắtcarpart, iVisitable): "một phần của chiếc xe" def __init __ (self, name, sku, price) Tự, khách truy cập): Khách truy cập. _price = price def Accept (self, khách truy cập): khách truy cập. ._sku = sku self._price = price def Accept (self, khách truy cập): khách truy cập. self._parts = [cơ thể ("tiện ích", "ABC-123-21", 1001), động cơ ("động cơ V8", "def-456-21", 2555), bánh xe ("frontleft", "GHI-789FL -21 ", 136), bánh xe (" Frontright "," GHI-789FR-21 ", 136), bánh xe (" Backleft "," GHI-789BL-21 ", 152) 789BR-21 ", 152),]

Def Accept (self, khách truy cập): Đối với các phần trong self._parts: parts.accept (khách truy cập) Khách truy cập. if hasattr (phần tử, 'sku'): print (f "{phần tử.name} \ t: {Element.sku}". Chiếc xe "Total_Price = 0 @ClassMethod def Truy cập (CLS, phần tử): Nếu hasattr (phần tử, 'giá'): cls.total_price += fement.price return cls.total_price # xe khách = xe (" delorean ") # In ra tên một phần và SKU bằng cách sử dụng car printpartsvisitor. Tổng giá}")

7.11.9 Đầu ra Python. GHI-789BR-21 Tổng giá = 4132

Trong các đối tượng của khách truy cập trong trường hợp sử dụng ví dụ ở trên, tôi kiểm tra xem các phần tử có thuộc tính nhất định trong hoạt động truy cập không. DEF Truy cập (CLS, phần tử): Nếu HasAttr (phần tử, 'Giá'): ... Phương thức HasAttr () có thể được sử dụng để kiểm tra xem một đối tượng khởi tạo có thuộc tính của một tên cụ thể. class classa (): name = "abc" value = 123 class_a = classa () print (hasattr (class_a, "name")) in (hasattr (class_a, "value")) in (hasattr (class_a, "ngày") ) Đầu ra đúng sự thật

Khi in các chuỗi vào bảng điều khiển, bạn có thể bao gồm các ký tự đặc biệt in một loạt các không gian bổ sung được gọi là tab. Các tab giúp trình bày văn bản đa dòng ở dạng bảng hơn dường như gọn gàng hơn để xem xét. ABC Defg Hi

Số lượng không gian được thêm vào phụ thuộc vào kích thước của từ trước ký tự \ t trong chuỗi. Theo mặc định, một tab tạo nên 8 không gian.

Bây giờ, không phải tất cả các từ được phân tách bằng một tab sẽ xếp hàng giống nhau trên dòng tiếp theo. ABCDEF 123 CDEFGHIJ GHI 789 JKLMN 1011

Vấn đề thường xảy ra khi một từ đã dài 8 ký tự trở lên. Để giúp giải quyết vấn đề khoảng cách, bạn có thể sử dụng phương thức ExpandTabs () trên một chuỗi để đặt số lượng ký tự sẽ sử dụng. in ("abcdef \ t123" .expandtabs (10)) in ("cdefghij \ t4563" .expandtabs (10)) in ("GHI \ t789" .expandtabs (10)) )) Bây giờ xuất ra abcdef cdefghij ghi jklmn

7.11.11 Tóm tắt • Sử dụng mẫu khách truy cập để xác định hoạt động được thực hiện trên các phần tử của cấu trúc đối tượng phân cấp. • Sử dụng mẫu khách truy cập để xác định hoạt động mới mà không cần thay đổi các lớp của các phần tử trên đó hoạt động. • Khi thiết kế ứng dụng của bạn, bạn có thể cung cấp cho khả năng trong tương lai cần chạy các hoạt động tùy chỉnh trên hệ thống phân cấp yếu tố, bằng cách triển khai giao diện khách truy cập trong dự đoán. • Việc sử dụng mẫu khách truy cập giúp đảm bảo rằng các lớp của bạn phù hợp với nguyên tắc trách nhiệm duy nhất do họ thực hiện hành vi khách truy cập tùy chỉnh trong một lớp riêng biệt.

8. Tóm tắt

Một lớp hoạt động như một giao diện cho một lớp hoặc đối tượng khác.

Thêm một sự trừu tượng hóa trên nhiều đối tượng liên quan khác được tạo bằng các mẫu sáng tạo khác.

Một giao diện thay thế trên một giao diện hiện có.

Mẫu cầu tương tự như mẫu bộ điều hợp ngoại trừ trong ý định mà bạn đã phát triển nó.

Một mô hình sáng tạo có ý định phân tách việc xây dựng một đối tượng phức tạp khỏi biểu diễn của nó để bạn có thể sử dụng cùng một quy trình xây dựng để tạo ra các biểu diễn khác nhau.

Vượt qua một đối tượng thông qua một chuỗi người xử lý kế nhiệm.

Một sự trừu tượng giữa một đối tượng gọi một lệnh và đối tượng thực hiện nó. Hữu ích cho việc hoàn tác/làm lại/phát lại.

Một mô hình cấu trúc hữu ích cho quản lý phân cấp.

Đính kèm các trách nhiệm bổ sung cho một đối tượng trong thời gian chạy.

Một giao diện thay thế hoặc đơn giản hóa trên các giao diện khác.

Sự trừu tượng giữa việc tạo ra một đối tượng và nơi nó được sử dụng.

Chia sẻ các đối tượng thay vì tạo hàng ngàn bản sao gần giống hệt nhau.

Chuyển đổi thông tin từ ngôn ngữ này sang ngôn ngữ khác.

Traverse một bộ sưu tập các tập hợp.

Các đối tượng giao tiếp thông qua một hòa giải viên thay vì trực tiếp với nhau.

Lưu một bản sao của tiểu bang và để truy xuất sau này. Hữu ích cho việc hoàn tác/làm lại/tải/lưu.

thay đổi.

Tốt cho khi tạo các đối tượng mới đòi hỏi nhiều tài nguyên hơn bạn cần có sẵn.

8. Tóm tắt

Một lớp hoạt động như một giao diện cho một lớp hoặc đối tượng khác.

Một lớp có thể được khởi tạo bất cứ lúc nào, nhưng sau khi nó được khởi tạo đầu tiên, bất kỳ trường hợp mới nào cũng sẽ trỏ đến trường hợp ban đầu.

Thay đổi hành vi đối tượng bằng cách thay đổi tay cầm của một trong các phương thức của nó thành một trong các lớp con của nó một cách động để phản ánh trạng thái nội bộ mới của nó.

Tương tự như mẫu trạng thái, ngoại trừ máy khách vượt qua trong thuật toán mà bối cảnh sau đó sẽ chạy.

Một lớp trừu tượng (mẫu) chứa một phương thức là một loạt các hướng dẫn là sự kết hợp của các phương thức có thể được ghi đè.

Vượt qua một đối tượng được gọi là khách truy cập vào một hệ thống phân cấp của các đối tượng và thực hiện một phương thức trên chúng.

Hãy nhớ rằng các mẫu thiết kế sẽ cung cấp cho bạn một từ vựng hữu ích và phổ biến cho khi thiết kế, ghi lại, phân tích, tái cấu trúc các dự án phát triển phần mềm mới và hiện có trong tương lai.Chúc may mắn và tôi hy vọng rằng các dự án của bạn trở nên rất thành công.Sean Bradley