Monkey patch

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ừ *[[Chiến tranh du kích|guerrilla]]* (du kích), gần âm với *[[Khỉ đột|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  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  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 ;
* 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 ).

## 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. 
```pycon
>>> 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 
*
* trong C #
*  trong Objective-C
* 

## Tham khảo