Mục tiêu cuối cùng là có giao diện mà mỗi thành phần đồng ý. Vì vậy, nếu, ví dụ, tôi đã xây dựng một trang web JavaScript đã được thực hiện -entirely- trong một MVC cũ (non-Rails/PHP) thực hiện, và hoàn toàn trong AJAX, tôi sẽ đảm bảo rằng mỗi các thành phần thực hiện cùng một giao diện để quan sát.
Trong mỗi mô hình/chế độ xem/bộ điều khiển, tôi có thể đặt tên cho phương thức "đăng ký" của mình hoàn toàn khác. Hoặc, tôi có thể triển khai giao diện chuẩn cho từng giao diện.
Vì vậy, tôi có thể có phương thức ".Register (event_type, subscriptioning_class)" công khai được triển khai trong MỌI thành phần đơn lẻ có thể được mong đợi sẽ được gọi.
Tương tự như vậy, tôi có thể có phương thức công khai ". Cập nhật (event_type, dữ liệu)" được thực hiện trong MỌI thành phần đơn lẻ có thể được mong đợi sẽ được gọi.
.Register và .Update là giao diện cho giao tiếp Observer của tôi. Bên trong các lớp học của tôi, mỗi lớp có thể có phương thức ".Subscribe (publisher, event_type, self_reference)". Đó là phương pháp chỉ có thể là:
Class.Subscribe = function (publisher, event_type) {
var self_reference = this;
publisher.Register(event_type, self_reference);
};
Mỗi có thể có một phương pháp .Notify nội bộ:
Class.Notify = function (type, data) {
var subscribers = this.subscribers[type],
i = 0, l = subscribers.length;
for (; i < l; i++) { subscribers[i].Update(type, data); }
};
Vì tôi đã đồng ý rằng tất cả các giao diện truyền thông của tôi sẽ cư xử theo cách này, nó không quan trọng những gì tôi trông như thế nào.
Mô hình của tôi có thể tiếp tục bị lãng quên với Chế độ xem của tôi và Chế độ xem của tôi có thể tiếp tục bị lãng quên với Bộ điều khiển của tôi.
Thông báo .Notify và .Subscribe không cần phải được triển khai theo cách đó - chúng không phải là một phần của giao diện có thể truy cập công khai. Họ có thể là bất cứ điều gì tôi muốn.
. Đăng ký có thể mất một ARRAY nhà xuất bản và đẩy nó qua vòng lặp for, để đăng ký nhiều điểm dữ liệu. Hoặc lấy một mảng {"pub": x, "type": y} đối tượng literals, và gọi phương thức .Register của mỗi một, để bạn có thể nhận được TẤT CẢ bootstrapping của lớp đó ra khỏi con đường với một cuộc gọi chức năng.
Điều tương tự cũng xảy ra khi tạo ứng dụng trình phát âm thanh. Tôi không quan tâm đến những tài sản công khai mà MusicPlayer chia sẻ. Tôi biết rằng nó sử dụng .Play(), .Pause(), .Stop(), .Load (track).
Nếu tôi đảm bảo rằng tôi CHỈ sử dụng các phương thức giao diện công cộng đã thỏa thuận, chương trình sẽ hoạt động. Tại sao?
Vì người làm việc trên MusicPlayer có thể thay đổi nội bộ của MusicPlayer. Anh ấy có thể viết lại chúng hoàn toàn. Có thể có phương thức ._ precacheSong (theo dõi). Nhưng nếu nó được thay thế bằng. _cueTrack (theo dõi) xuống đường?
Bạn chỉ sử dụng một số tiện ích con và một ngày tiện ích của bạn gặp sự cố, vì bạn đã mở rộng hoặc triển khai tiện ích dựa trên phương pháp không giao diện hoặc dữ liệu không giao diện, đã xảy ra thay đổi như v1.2.1
Vì vậy, ngay cả trong Ngôn ngữ Loose, Giao diện cũng quan trọng. Chúng cung cấp cho bạn một bản đồ về cách bạn có thể mong đợi để gọi bất kỳ thành phần nào được mong đợi có chức năng đó - và bất kể các thành phần của thành phần đó hoạt động như thế nào, các đầu vào và đầu ra sẽ giống nhau (mặc dù có nhiều kiểu/lỗi hơn) kiểm tra là cần thiết trên đầu vào).
Chúng cho phép bạn "Duck-Type" thực sự dễ dàng (lấy danh sách các phiên bản Class khác nhau - kích hoạt cùng một cuộc gọi hàm trên mỗi trường hợp, mong đợi từng có cùng một phương thức và có cùng định dạng dữ liệu).
Thậm chí tốt hơn với JavaScript:
tôi đang .Subscribe thậm chí có thể được viết chỉ một lần, và sau đó bị ràng buộc vào bất cứ điều gì mà tôi muốn "thừa hưởng" nó.
Interface.Subscribe = function (publisher, evt_type) {
var self_ref = this;
publisher.Register(evt_type, self_ref);
};
Class_1.Subscribe = Interface.Subscribe.bind(Class_1);
Class_2.Subscribe = Interface.Subscribe.bind(Class_2);
Class_3.Subscribe = Some_Other_Interface.Subscribe.bind(Class_3);
Và tôi có thể làm điều đó một cách tự do, bởi vì tôi biết rằng mọi thứ tôi muốn đăng ký sẽ có cùng giao diện công khai.
Xem bài đăng đã chỉnh sửa của tôi. Tôi không thể thấy tại sao nó sẽ là "dư thừa" – NullUserException