Maison > interface Web > js tutoriel > le corps du texte

Parlez de la programmation AOP en Javascript

黄舟
Libérer: 2017-02-25 13:39:06
original
1265 Les gens l'ont consulté


Duck punch

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 !

Parlez de la programmation AOP en Javascript

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
}
Copier après la connexion

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')
Copier après la connexion

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);
Copier après la connexion
AOP

Prise en main

AOP signifie Programmation orientée aspect, qui est évidemment relative à la programmation orientée objet. Aspect peut être traduit par « aspect » ou « côté », donc AOP est une programmation orientée aspect.

Comment comprendre les aspects ?

Dans la programmation orientée objet, les classes que nous définissons sont généralement des modèles de domaine, et les méthodes dont elles disposent sont généralement liées à une logique métier pure. Par exemple :

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;   
    }
}
Copier après la connexion

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)
        {

        }   
    }
}
Copier après la connexion
Implémentation

Le Parlez de la programmation AOP en Javascript punch introduit dans la section précédente est similaire à la programmation d'aspect, qui assurent tous deux le fonctionnement de la méthode originale tout en la transformant. Mais comme mentionné à la fin, le modèle consistant à modifier directement la méthode originale va à l’encontre des principes des meilleures pratiques orientées objet.

Javascript peut utiliser le modèle décorateur (en ajoutant des responsabilités supplémentaires à l'objet d'origine mais en évitant de modifier l'objet d'origine) pour implémenter la programmation AOP. Notez que l'accent est mis ici sur la mise en œuvre. Ce que je tiens en outre à souligner, c'est que la programmation des aspects n'est qu'une idée et que le modèle de décorateur n'est qu'un moyen de mettre en pratique cette idée. Par exemple, en Java, vous pouvez utiliser le modèle de proxy, etc. . La programmation Aspect a plus de place pour jouer en Java et est plus standard. Je voulais présenter le modèle d'implémentation de Java dans cet article, mais mon niveau Java est limité et je ne comprends pas très bien l'implémentation de Java. Seule l'implémentation Javascript est présentée ici.

  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();
Copier après la connexion

  由此可以看出,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;   
    };
}
Copier après la connexion

  当然,如果想看到更完备的解决方案和代码可以参考上面所说的meld项目

 结束语

  这一篇一定让你失望了,代码简单又寥寥无几。本篇主要在于介绍有关Parlez de la programmation AOP en Javascript和AOP的这几类思想,我想编程的乐趣不仅仅在于落实在编码上,更在于整个架构的设计。提高代码的可维护性和可拓展性会比高深莫测的代码更重要。

 以上就是聊Javascript中的AOP编程的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!