Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement the Policy pattern in JavaScript

2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces the relevant knowledge of JavaScript how to achieve the strategic pattern, the content is detailed and easy to understand, the operation is simple and quick, and has a certain reference value. I believe you will gain something after reading this JavaScript article on how to achieve the strategic pattern. Let's take a look at it.

Strategy mode: a series of family algorithms are defined, and each algorithm is encapsulated separately, so that the algorithms can replace each other, independent of the customers who use the algorithm.

Usually I don't remember the details of Newton's Law, so I can't guarantee how long I will remember this definition. Give an example of what you often see in FE:

$("div"). Animation ({left: '50px'}, 1000 animation easein'); $("div"). Animation ({left: '50px'}, 1000 div); $("div"). Animation ({left:' 50px'}, 1000 charge swinging`) / / see * three parameters about animation effects / / Jquery documents always mention easing (the third parameter): the name of the erasure effect to be used (plug-in support is required). The default jQuery provides "linear" and "swing".

The ease effect we are animating the element is actually an implementation of the strategy mode. This kind of ease algorithm is not directly related to those of us who use Jquery. If one of the animations in my project needs a new algorithm effect, then we should just develop a plug-in. On the other hand, if Jquery does not provide such a plug-in mechanism, is it necessary to change the source code of Jquery in response to changes in requirements?

Let me first simulate the basic code form of the policy pattern:

Document function ConcreteStrategyA () {this.AlgorithmInterface = function () {console.log ("algorithm A");} function ConcreteStrategyB () {this.AlgorithmInterface = function () {console.log ("algorithm B") }} function ConcreteStrategyC () {this.AlgorithmInterface = function () {console.log ("algorithm C");}} / / Context, configured with a createStrategy, maintains a reference to the Strategy object function Context (strategy) {this.strategy = strategy This.ContextInterface = function () {strategy.AlgorithmInterface ();} / / Application var context1 = new Context (new ConcreteStrategyA ()); context1.ContextInterface (); var context2 = new Context (new ConcreteStrategyB ()); context2.ContextInterface (); var context3 = new Context (new ConcreteStrategyC ()); context3.ContextInterface ()

Generally speaking, a specific algorithm must ensure that it implements some interfaces or inherits some abstract classes in order to avoid type errors, and it will take some time to implement interfaces, abstract classes, inheritance and other features in javascript, so my example is not rigorous and only starts with the simplest implementation.

Specific implementation of a shopping mall cashier system: including a separate js file, and a specific implementation html file

/ / because numerical verification is needed, so. Here we use isNum function isNum (obj) {return obj-parseFloat (obj) > = 0;} / algorithm An in jquery2.1. There is no activity. Normal charge function ConcreteStrategyA () {this.AlgorithmInterface = function (money) {return money;}} / / algorithm B, full 300 minus 100 function ConcreteStrategyB (MoneyCondition,MoneyReturn) {this.MoneyCondition = MoneyCondition, this.MoneyReturn = MoneyReturn; this.AlgorithmInterface = function (money) {var result=money If (money > = MoneyCondition) {result = money-Math.floor (money/MoneyCondition) * MoneyReturn;} return result;}} / / algorithm C, discount function ConcreteStrategyC (moneyRebate) {this.moneyRebate = moneyRebate; this.AlgorithmInterface = function (money) {return money*this.moneyRebate }} / / Context, configured with a createStrategy, maintains a reference to the Strategy object / / here strips algorithm-related from the client, simple factory pattern function Context (type) {this.strategy = null; switch (type) {case "a": this.strategy = new ConcreteStrategyA (); break Case "b": this.strategy = new ConcreteStrategyB; break; case "c": this.strategy = new ConcreteStrategyC ("0.8"); break;} this.ContextInterface = function (money) {if (! isNum (money)) {money = 0 } return this.strategy.AlgorithmInterface (money);}}

HTML section:

Document .block {padding:5px 0; border-bottom:1px solid # ccc;} .menu {margin:10px auto;text-align: center } Unit price (RMB): quantity: calculation method: normal charge over 300 minus 100% discount total: total price: var tPrice = document.getElementsByClassName ("tPrice"), tNum = document.getElementsByClassName ("tNum"), tAlg = document.getElementsByClassName ("tAlg") TMoney = document.getElementsByClassName ("tMoney"), total = document.querySelector ("# total") Var addBtn = document.querySelector ("# addBtn"); addBtn.addEventListener ("click", function () {var html = 'unit price (RMB): quantity: calculation method: normal charge over 300 minus 100% discount:'; var div = document.createElement ("div"); div.className= "block"; div [XSS _ clean] = html Function calculate [XSS _ clean] [xss_clean] .insertBefore (div, This [XSS _ clean]);}) insert (e) {/ / judge the event source according to the event object and get the position var num = 0className = e.target.className in the same kind of elements Switch (className) {case "tPrice": for (var itemtPrice.Qingthmuri 1 political I > = 0 politic iMub -) {if (tPrice [I] = = e.target) {num = I;} break Case "tNum": for (var ibettNum.futhMurray 1 break > = 0poliimuri -) {if (tNum [I] = = e.target) {num = I;}} break Case "tAlg": for (var iTuntAlg.inherthmurl break) {if (tAlg [I] = = e.target) {num = I;}} Default: return;} var context = new Context (tAlg [num] .value); var money = 0; var totalValue = 0; money = context.ContextInterface (tPrice [num]. Value* tNum [num] .value); tMoney.value = money For (var index=0,len=tMoney.length;index= 0; I murmur -) {if (this.observerss [I] = = observer) {flag=true;}}; if (! flag) {this.observers.push (observer);} return this } Publisher.prototype.removeOb=function (observer) {var observers = this.observers; for (var I = 0; I

< observers.length; i++) { if(observers[i]===observer){ observers.splice(i,1); } }; return this; } Publisher.prototype.notice=function(){ var observers = this.observers; for (var i = 0; i < observers.length; i++) { observers[i].update(this.getState()); }; } //订阅者 function Subscribe(obj){ this.obj = obj; this.update = function(data){ this.obj.value = data; }; } //实际应用 var tPrice = document.getElementsByClassName("tPrice"), tNum = document.getElementsByClassName("tNum"), tAlg = document.getElementsByClassName("tAlg"); var pba = new Publisher(document); var oba = new Subscribe(document.getElementsByClassName("tMoney")); var obb = new Subscribe(document.querySelector("#total")); pba.addOb(oba).addOb(obb); oba.update = function(num){ var context = new Context(tAlg[num].value); var money = 0; money = context.ContextInterface(tPrice[num].value*tNum[num].value); this.obj[num].value = money; } obb.update = function(num){ var totalValue = 0, tMoney = document.getElementsByClassName("tMoney"); for(var index=0,len=tMoney.length;index=0;i--){ if(tPrice[i]==e.target){ num = i; } } break; case "tNum": for(var i=tNum.length-1;i>

) {if (tNum [I] = = e.target) {num = I;}} break; case "tAlg": for (var itimalg. ) {if (tAlg [I] = = e.target) {num = I;} break; default: return;} pba.setState (num) } document.addEventListener ('keyup',calculate,false); document.addEventListener (' change',calculate,false)

Summary:

When I learned the Observer pattern before, I only distinguished the DOM element between the publisher and the subscriber, but I didn't know or thought about the difference between the publisher and the subscriber in the structure of data, view, and controller, so I still need to look at different cases. After learning this article, I followed suit on my "cashier system", but I haven't learned the "combination mode" after all, so I'm not going to write another Controller, just adding the observer mode between Model and View. The result of * * is as follows:

Document .block {padding:5px 0; border-bottom:1px solid # ccc;} .menu {margin:10px auto;text-align: center } Unit price (RMB): quantity: calculation method: normal charge over 300 minus 100% discount total: total price: / / Event class function Event (pub) {this._pub = pub; this._listener = [] } Event.prototype = {attach: function (listener) {this._listener.push (listener);}, notify: function (num) {for (var items0 for -) {if (elements [I] = = target) {a = I }} switch (className) {case "tPrice": B = 0; break; case "tNum": B = 1; break Case "tMoney": B = 3; break;} if (! isNum (a)) {a = 0;} if (! isNum (b)) {b = 0 } that._model.itemChange ([target.value b], target.value); this._ele.eTarget.addEventListener ('change',function (e) {var target = e.target, className = target.className) If (target.nodeName.toLowerCase ()! = = "select") {return;} var elements = document.getElementsByClassName (className), a; for (var ionomelements. That._model.itemChange -) {if (elements [I] = target) {a = I;}} that._model.itemChange ([a Magi 2], target.value);}) This._ele.addBtn.addEventListener ('click',function () {var html =' unit price (RMB): quantity: calculation method: normal charge over 300 minus 100% discount:'; var div = document.createElement ("div"); div.className= "block"; div [XSS _ clean] = html That._model.itemAdd [XSS _ clean] [xss_clean] .insertBefore (div, This [XSS _ clean]); insertBefore ([0d0, "a", 0]);}) } View.prototype.getTotal= function (pub,num) {var price = this._model._ data [num] [0], number = this._model._ data [num] [1], alg = this._model._ data [num] [2], money = this._model._ data [num] [3] Var context = new Context (alg); money = context.ContextInterface (price*number); this._model._ data [num] [3] = money; var total = 0; for (var item0)

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report