Một **monkey patch** (dịch: đắp vá kiểu khỉ) là một cách để một chương trình mở rộng hoặc sửa đổi phần mềm hệ thống một cách cục bộ (chỉ ảnh hưởng đến instance đang chạy của chương trình).

Từ nguyên
---------

Thuật ngữ *monkey patch* dường như xuất phát từ một thuật ngữ trước đó, *guerrilla patch* (đắp vá du kích), đề cập đến việc thay đổi mã một cách lén lút – và có thể không tương thích với các bản vá khác như vậy – trong runtime. Từ *guerrilla* (du kích), gần âm với *gorilla* (khỉ đột), rồi đã trở thành *monkey* (khỉ), có lẽ là để làm cho bản vá nghe đỡ đáng sợ hơn. Một cách lý giải từ nguyên khác là về nghĩa động từ của *monkey* trong Tiếng Anh là "lục lọi, xáo trộn", tức là làm xáo trộn mã code (tiếng Anh: monkeying with the code).

Định nghĩa
----------

Định nghĩa của thuật ngữ khác nhau tùy thuộc vào cộng đồng sử dụng nó. Trong Ruby, Python, và nhiều ngôn ngữ lập trình động (en) khác, thuật ngữ *monkey patch* chỉ nói đến sự sửa đổi động (dynamic modification) lên một lớp (class) hoặc mô-đun trong runtime, động cơ thúc đẩy là từ ý định vá 'mã bên thứ ba hiện có' như một con đường vòng để sửa lỗi hoặc tính năng không hoạt động như mong muốn. Các hình thức khác để sửa đổi lớp trong runtime thì có tên khác nhau, dựa trên ý định khác nhau của chúng. Ví dụ, trong phần mềm Zope và Plone, các bản vá bảo mật hay được phân phối bằng cách sửa đổi lớp động (dynamic class modification), nhưng chúng lại được gọi là các *bản sửa lỗi nóng* (hot fix).

Ứng dụng
--------

Monkey patch được sử dụng để:

* Thay thế phương thức / lớp / thuộc tính / hàm trong runtime, thí dụ để tạo phương thức stub (en) khi đang kiểm thử;
* Sửa đổi/mở rộng hành vi của một sản phẩm bên thứ ba mà không bảo trì một bản sao riêng tư của mã nguồn;
* Áp dụng kết quả của một bản vá trong runtime vào trạng thái trong bộ nhớ, thay vì mã nguồn trên đĩa cứng (en);
* Phân phối các bản sửa lỗi bảo mật hoặc bản sửa lỗi hành vi ở ngay bên với mã nguồn gốc (một ví dụ là người ta phân phối plugin sửa lỗi cho nền tảng Ruby on Rails (en)).

Cạm bẫy
-------

Bất cẩn trong việc viết hoặc yếu kém trong việc soạn tài liệu cho các bản monkey patch thì có thể dẫn đến các vấn đề:

* Chúng có thể dẫn đến các 'vấn đề nâng cấp' khi sự giả định của bản patch về đối tượng được patch không còn đúng nữa; một bản phát hành mới rất có thể sẽ phá vỡ các bản vá. Vì lý do này, các bản monkey patch thường được thực hiện theo điều kiện, và chỉ được áp dụng nếu thích hợp.
* Nếu hai mô-đun cùng cố gắng monkey patch vào cùng một phương thức, một trong số chúng (cái mà chạy cuối cùng) sẽ "thắng" và bản vá kia sẽ không có hiệu lực, trừ khi các bản monkey patch được viết với một mô thức như `alias_method_chain`.
* Chúng tạo ra sự sai khác giữa mã nguồn gốc trên đĩa cứng và 'hành vi được quan sát', điều này có thể gây rất bối rối cho bất kỳ ai không biết về sự tồn tại của các bản vá.

Ví dụ
-----

Ví dụ monkey patch bằng ngôn ngữ Python sau đây đắp vá giá trị của số Pi từ thư viện toán học tiêu chuẩn. 

```
>>> import math
>>> math.pi
3.141592653589793
>>> math.pi = 3
>>> math.pi
3
================================ KHỞI ĐỘNG LẠI ================================
>>> import math
>>> math.pi
3.141592653589793
>>>

```

Xem thêm
--------

* Lập trình hướng khía cạnh
* Mã tự sửa đổi (en)
* Phương thức mở rộng (en) trong C #
* Thể loại trong Objective-C
* Tải động (en)

Tham khảo
---------

1. ↑  Limi, Alexander; Shane Hathaway (23 tháng 12 năm 2005). "Monkey patch". Plone Foundation. Bản gốc lưu trữ ngày 4 tháng 6 năm 2008. Truy cập ngày 3 tháng 7 năm 2008.
2. ↑  "Refining Ruby". 27 tháng 2 năm 2013.
3. ↑  Biswal, Bimal. "Monkey Patching in Python". *Software Technology Tips*. Mindfire Solutions. Bản gốc lưu trữ ngày 22 tháng 8 năm 2012. Truy cập ngày 9 tháng 12 năm 2013.
4. ↑  "Maintainable JavaScript: Don't modify objects you don't own". 2 tháng 3 năm 2010.
5. ↑  "New in Rails: Module#alias\_method\_chain". 26 tháng 4 năm 2006.