El objetivo final es tener una interfaz en la que cada componente esté de acuerdo.
Entonces, si, por ejemplo, estaba construyendo un sitio de JavaScript que se hacía -en su totalidad- en una implementación MVC (non-Rails/PHP) de la vieja escuela, y completamente en AJAX, me aseguraría de que cada uno los componentes implementaron la misma interfaz para la observación.
En cada modelo/vista/controlador, podría nombrar mi método de "suscripción" algo completamente diferente. O bien, podría implementar una interfaz estándar para cada uno.
De modo que puedo tener un método público ".Register (event_type, subscribing_class)" implementado en TODOS los componentes únicos de los que podría esperarse llamar.
Del mismo modo, puedo tener un método público ".Update (event_type, data)" implementado en CADA componente que podría esperarse que se llame.
The .Register y .Update son la interfaz para mi comunicación Observer. Dentro de mis clases, cada una puede tener un método ".Subscribe (publisher, event_type, self_reference)". Ese método podría ser:
Class.Subscribe = function (publisher, event_type) {
var self_reference = this;
publisher.Register(event_type, self_reference);
};
Cada podrían tener un método .Notify interna:
Class.Notify = function (type, data) {
var subscribers = this.subscribers[type],
i = 0, l = subscribers.length;
for (; i < l; i++) { subscribers[i].Update(type, data); }
};
Debido he acordado que todos los de mi interfaz de comunicación va a comportarse de esta manera, no importa cómo se vean mis internos.
Mi modelo puede seguir sin tener en cuenta mi Vista, y mi vista puede seguir siendo ajena a mi controlador.
El .Notify y .Subscribe no necesitan ser implementados de esa manera, no son parte de la interfaz de acceso público. Podrían ser lo que yo quiera.
. Suscribir podría tomar un ARRAY de editores y presionarlo a través de un bucle for, suscribirse a múltiples puntos de datos. O tome una matriz de {"pub": x, "escriba": y} literales de objeto, y llame al método .Register de cada uno, de modo que pueda obtener TODA la inicialización de esa Clase con una llamada a una función.
Lo mismo ocurre con la creación de una aplicación de reproductor de audio. No me importa qué propiedades públicas comparta MusicPlayer. Sé que usa .Play(), .Pause(), .Stop(), .Load (track).
Si me aseguro de que SÓLO uso los métodos de interfaz públicos acordados, el programa funcionará. ¿Por qué?
Porque el chico que trabaja en MusicPlayer podría cambiar las partes internas de MusicPlayer. Podría reescribirlos completamente. Tal vez haya un ._ método precacheSong (seguimiento). Pero, ¿qué pasa si se reemplaza con. _cueTrack (pista) por el camino?
Usted solo está usando el widget de algún amigo, y un día su widget se cuelga, porque lo estaba extendiendo o implementándolo en base a métodos que no son de interfaz o datos que no son de interfaz, que cambió a partir de v1.2.1
Por lo tanto, incluso en Loose Languages, la interfaz es importante. Le dan un mapa de cómo puede esperar llamar a CUALQUIER componente que se espera que tenga esa funcionalidad, e independientemente de cómo funcionan las funciones internas de ese componente, las entradas y salidas serán exactamente las mismas (aunque más tipo/error) es necesario verificar las entradas).
Le permiten "Tipo de pato" realmente fácil (tome una lista de diferentes instancias de Clase - active la misma llamada de función en cada una, esperando que cada una tenga el mismo método y tome el mismo formato de datos).
Incluso mejor con JavaScript:
Mi código .Subscribe incluso podría escribir solamente una vez, y luego ligado a todo lo que yo quiero "heredar" la misma.
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);
Y yo puedo hacer eso libremente, porque sé que todo lo que quiero para suscribirse a va a tener la misma interfaz pública.
Ver mi publicación editada. No puedo ver por qué sería "redundante" – NullUserException