Trong 1 source code, có rất nhiều class/ func có khả năng được sử dụng lại, đồng nghĩa với việc nhiều member khác động chạm vào. Một khi đã nhúng tay vào rất dễ làm thay đổi code gốc. Nhưng cũng không thể đi viết lại 1 đoạn code mà đã có sẵn hay được hoàn thiện rồi. Do đó nếu đụng thì nên tuân thủ theo quy tắc Open-Closed Principle (OCP – chữ O))
a. Nguyên tắc và nguyên nhân sử dụng
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
a.1. Open for extension:
Người khác có khả năng sử dụng lại class, module, function của bạn. Đồng thời có thể thêm các tính năng mà họ muốn
a.2 Close for modification:
Không cho người khác sửa đổi (update, delete) class, module, func của mình.
a.3 Sử dụng:
Nguyên nhân dùng thì mình đã nói ở trên. Tư duy là trước khi viết một class, module, func, bạn muốn người khác sử dụng cái gì trong cái mà bạn tạo ra, và đương nhiên là không cho họ edit đoạn nào.
Ví dụ các third party library, hoặc các plugin khác, bạn hoàn toàn có thể sử dụng, thậm chí có thể custom lại. Đây là ví dụ tiêu biểu và điển hình của việc Open-Closed một module.
b. Áp dụng
b.1. Ví dụ thực tế trong Swift
Nếu các bạn đã từng extension 1 tính năng nào đó của Swift, như String, UIView, UIColor, v..v thì bạn đang tương tác với chúng theo nguyên tắc OCP rồi đó. Tức là implement thêm những tính năng mà mình mong muốn mà không đụng chạm gì đến những thứ bên trong. Phần này mình không đi sâu, mình sẽ đi sâu với một ví dụ tự tạo.
b.2. Áp dụng
Mọi người tập trung phần `arsenal.forEach`. Bây giờ, mỗi lần bạn có một class mới, bạn đều phải vào lại bên trong Players, gọi class đó và forEach tiếp, ví dụ mình tạo class MU tương tự như class Arsenal. Như sau:
Cách giải quyết như sau:
Ta tạo một protocol, làm những phần việc mà ta cần, sau đó class nào tạo thêm mà muốn dùng func của mình phải conform (thoả mãn yêu cầu ta đặt ra). Tổng quát như sau:
Như ở trên, các bạn có thể thấy rằng, việc thay đổi, thêm bớt không ảnh hưởng đến công việc của ta - forEach, đó là gọi ra các tên.
Để mình khai thác tiếp phần Open-Closed ở đoạn này.
c. Giải thích - làm rõ vấn đề
Các bước mà code sẽ run như sau:
1. listPlayers array sẽ nhận các Object (class) mà conform cái mà nó quy định (protocol). Cụ thể ở đây là NamePlayers. Ví dụ như Arsenal, MU.
2. listPlayer sẽ lôi ra từng object trong array này, và kiểu như: "Đây, tôi có giao công việc là callName()" ông nào đem callName() về làm riêng thì ở đoạn này gọi nó ra. Bản thân nó không quan tâm ai làm callName() như thế nào. Vì listPlayers có các phần tử là 1 protocol với func là callName(), nên nó cứ thế mà lấy ra dùng. Sorry nếu chỗ này mình giải thích hơi lủng củng. Nhưng các bạn đọc chậm lại sẽ thấy rất hay.
3. Đến đoạn này Object nào lấy thì callName() thực hiện func callName() tương ứng đó thôi.
Như vậy đã kết thúc part 2, tiếp theo chúng ta sẽ qua nguyên lý L.