Ne parlons pas d'abord de la programmation AOP, commençons par la programmation Parlez de la programmation AOP en Javascript punch.
Si vous recherchez Parlez de la programmation AOP en Javascript punch sur Wikipédia, l'entrée que vous devriez trouver est Monkey Patch. Selon l'explication, le mot singe patch vient de guerrilla patch, ce qui signifie changer tranquillement le code pendant le fonctionnement. Le mot guerrilla a la même prononciation que gorille, et ce dernier signifie similaire à singe (le premier signifie « gorille »), et a finalement évolué vers For Monkey Patch.
Si vous n'avez pas entendu parler du punch au canard, vous avez peut-être entendu parler du typage au canard. Pour donner un exemple populaire, comment identifier un canard :
Quand je vois un oiseau qui marche comme un canard et nage comme un canard et cancane comme un canard, j'appelle cet oiseau un canard.
Oui, si je trouve un animal qui cancane comme un canard et qui nage comme un canard, alors ce serait un canard !
Ce test peut paraître un peu naturel et absurde, mais il est très pratique. Et il peut être utilisé pour résoudre un type de problème en programmation - pour Javascript ou des langages dynamiques similaires, comment implémenter « interface » ou « classe de base » ? Nous n'avons pas du tout besoin de nous soucier de leur passé. Nous nous soucions seulement de savoir si le type ou les paramètres de la méthode sont ce dont nous avons besoin lorsque nous les utilisons :
var quack = someObject.quack; if (typeof quack == "function" && quck.length == arguLength) { // This thing can quack }
Je vais trop loin. en fait, ce que je veux exprimer, c'est le canard. Punch a en fait évolué à partir du typage du canard :
s'il marche comme un canard et parle comme un canard, c'est un canard, non ? en vous donnant le bruit que vous voulez, vous n'avez qu'à frapper ce canard jusqu'à ce qu'il renvoie ce que vous attendez... Au fait, cela me rappelle une blague très vivante :
Dans. Afin de tester la force de la police aux États-Unis, à Hong Kong et en Chine continentale, les Nations Unies ont placé trois lapins dans trois forêts. Quel policier local trouvera le lapin en premier ? Tâche : trouver le lapin. (Le milieu est omis...) Finalement, il n'y avait que quatre policiers d'un certain pays. Ils jouèrent au mahjong pendant une journée, chacun d'eux prit une matraque et entra dans la forêt. Au bout de cinq minutes, ils entendirent les cris. d'animaux venant de la forêt. Il est sorti en parlant et en riant en fumant une cigarette, et derrière lui se trouvait un ours avec le nez meurtri et le visage enflé et il a dit : « Ne me frappe plus, je le suis. juste un lapin..."
Bien que le punch au canard Un peu violent, mais toujours une méthode efficace. Lorsqu'il s'agit d'implémentation de code, cela signifie rendre le code original compatible avec les fonctions dont nous avons besoin. Par exemple, cet exemple sur le blog de Paul Irish :
En même temps, le mode Parlez de la programmation AOP en Javascript punch peut être annulé, mais c'est juste comme ça :
/** 我们都知道jQuery的`$.css`方法可以通过使用颜色的名称给元素进行颜色赋值。 但jQuery内置的颜色并非是那么丰富,如果我们想添加我们自定义的颜色名称应该怎么办?比如我们想添加`Burnt Sienna`这个颜色 */ (function($){ // 把原方法暂存起来: var _oldcss = $.fn.css; // 重写原方法: $.fn.css = function(prop,value){ // 把自定义的颜色写进分支判断里,特殊情况特殊处理 if (/^background-?color$/i.test(prop) && value.toLowerCase() === 'burnt sienna') { return _oldcss.call(this,prop,'#EA7E5D'); // 一般情况一般处理,调用原方法 } else { return _oldcss.apply(this,arguments); } }; })(jQuery); // 使用方法: jQuery(document.body).css('backgroundColor','burnt sienna')
Mais là Il y a un problème avec ceci : la méthode d'origine doit être modifiée. Cela viole le principe « ouvert-fermé », qui doit être ouvert à l'expansion et fermé à la modification. Comment résoudre ce problème ? Utilisez la programmation AOP.
(function($){ var _old = $.fn.method; $.fn.method = function(arg1,arg2){ if ( ... condition ... ) { return .... } else { // do the default return _old.apply(this,arguments); } }; })(jQuery);
Mais la situation réelle est généralement plus compliquée. Par exemple, nous devons ajouter une détection d'autorisation au mode de paiement, ou envoyer des journaux pour des statistiques, ou même un code tolérant aux pannes. Le code deviendra donc comme ceci :
Class Person { private int money; public void pay(int price) { this.money = this.money - price; } }
Ce qui est encore plus effrayant, c'est qu'un code similaire doit être ajouté à d'autres méthodes. De cette façon, la maintenabilité et la lisibilité du code sont devenues un gros problème. Nous espérons collecter ces codes non commerciaux dispersés mais courants et les utiliser et les gérer de manière plus conviviale. Il s'agit d'une programmation d'aspect. La programmation d'aspect permet la réutilisation du code en évitant la modification du code distant. C'est comme couper différents objets horizontalement et se concentrer sur la transformation des méthodes internes. La programmation orientée objet accorde plus d'attention à la conception architecturale globale.
Class Person { private int money public void pay(price) { try { if (checkAuthorize() == true) { this.money = this.money - price; sendLog(); } } catch (Exception e) { } } }
AOP中有一些概念需要介绍一下,虽然我们不一定要严格执行
joint-point:原业务方法;
advice:拦截方式
point-cut:拦截方法
关于这三个概念我们可以串起来可以这么理解:
当我们使用AOP改造一个原业务方法(joint-point)时,比如加入日志发送功能(point-cut),我们要考虑在什么情况下(advice)发送日志,是在业务方法触发之前还是之后;还是在抛出异常的时候,还是由日志发送是否成功再决定是否执行业务方法。
比如gihub上的meld这个开源项目,就是一个很典型的AOP类库,我们看看它的API:
// 假设我们有一个对象myObject, 并且该对象有一个doSomething方法: var myObject = { doSomething: function(a, b) { return a + b; } }; // 现在我们想拓展它,在执行那个方法之后打印出刚刚执行的结果: var remover = meld.after(myObject, 'doSomething', function(result) { console.log('myObject.doSomething returned: ' + result); }); // 试试执行看: myObject.doSomething(1, 2); // Logs: "myObject.doSomething returned: 3" // 这个时候我们想移除刚刚的修改: remover.remove();
由此可以看出,AOP接口通常需要三个参数,被修改的对象,被修改对象的方法(joint-point),以及触发的时机(apce),还有触发的动作(point-cut)。上面说了那么多的概念,现在可能要让各位失望了,Javascript的实现原理其实非常简单
function doAfter(target, method, afterFunc){ var func = target[method]; return function(){ var res = func.apply(this, arguments); afterFunc.apply(this, arguments); return res; }; }
当然,如果想看到更完备的解决方案和代码可以参考上面所说的meld项目
这一篇一定让你失望了,代码简单又寥寥无几。本篇主要在于介绍有关Parlez de la programmation AOP en Javascript和AOP的这几类思想,我想编程的乐趣不仅仅在于落实在编码上,更在于整个架构的设计。提高代码的可维护性和可拓展性会比高深莫测的代码更重要。
以上就是聊Javascript中的AOP编程的内容,更多相关内容请关注PHP中文网(www.php.cn)!