编写计算器程序学习JS责任链模式

Posted 生命梦想

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写计算器程序学习JS责任链模式相关的知识,希望对你有一定的参考价值。

设计模式中的责任链模式能够很好的处理程序过程的逻辑判断,提高程序可读性。
责任链模式的核心在于责任链上的元素判断能够处理该数据,不能处理的话直接交给它的后继者。
计算器的基本样式:

通过div+css定义计算器的样式,并在每个按钮上绑定事件响应按钮输入。

  • 输入的元素为数字、小数点、加减乘除运算符时,都是直接显示。
  • 输入为清除所有、清除上一次时直接清除。
  • 输入为等号、百分比、开根号、乘方、分之一时,开始计算。
    同时在输入框下面显示上次运算的公式。

1.定义责任元素的基类

包括变量next指向他的后继者,方法setNext设置它的后继者,方法handleRequest处理请求。

InputHandler = function () {
    this.next = null;
    this.setNext = function(handler) {
        this.next = handler;
    };

    this.handleRequest = function(currentInput,allInput) {

    }
}

2.定义责任元素

定义每个责任链元素应该处理的范围

<!-- 处理数字键 -->
NumberHandler = function (){this.NumberKeyArray = ["0","1","2","3","4","5","6","7","8","9"];}
NumberHandler.prototype = new InputHandler();
NumberHandler.prototype.handleRequest = function(currentInput,allInput) {
    var isNumber = $.inArray(currentInput,this.NumberKeyArray);
    if(isNumber!=-1){
        var temp = allInput+currentInput;
        return temp;
    }else{
        if(this.next){
            return this.next.handleRequest(currentInput,allInput);
        }
    }
}
<!-- 定义以下责任元素分别用来处理不同的输入键 -->
<!-- 处理操作符 -->
OperatorHandler = function () {this.OperatorArray=["+","-","/","*"];}
<!-- 清空所有 -->
ClearAllHandler = function (){}
<!-- 清除最后一次输入 -->
ClearLatestKeyHandler = function (){}
<!-- 直接计算 -->
ImmediateComputeHandler = function () {this.ImmediateComputeKeyArray=["x²","¼","%","√","="];}
<!-- 小数点 -->
PointHandler = function () {}

3.组成责任链

var numberHandler = new NumberHandler();
var operatorHandler = new OperatorHandler();
var clearAllHandler = new ClearAllHandler();
var clearLatestKeyHandler = new ClearLatestKeyHandler();
var immediateComputeHandler = new ImmediateComputeHandler();
var pointHandler = new PointHandler();

numberHandler.setNext(operatorHandler);
operatorHandler.setNext(clearAllHandler);
clearAllHandler.setNext(clearLatestKeyHandler);
clearLatestKeyHandler.setNext(immediateComputeHandler);
immediateComputeHandler.setNext(pointHandler);

4. 责任链调用处理

var currentInput = this.title;
var allInput=$("#result").val();

var temp=numberHandler.handleRequest(currentInput,allInput);
$("#result").val(temp);

5.完整代码

<html>
<head>
	<title>Web版本计算器</title>
	<link rel="stylesheet" href="./css/bootstrap.css"/>
	<script type="text/javascript" src="./js/jquery-3.3.1.js"></script>
	<style type="text/css">
		body {
			background-color:LightGrey;
			Color:black;
		}
		.display-border {
			border-style:solid;
			border-width:1px;
			border-color:Orange
		}
		
		.calculator-row {
			margin-top:5px;
		}
		
		.calculator-btn {
			width:100%;
		}
		
	</style>
	<script type="text/javascript">
		$(function(){
			var numberHandler = new NumberHandler();
			var operatorHandler = new OperatorHandler();
			var clearAllHandler = new ClearAllHandler();
			var clearLatestKeyHandler = new ClearLatestKeyHandler();
			var immediateComputeHandler = new ImmediateComputeHandler();
			var pointHandler = new PointHandler();
			
			numberHandler.setNext(operatorHandler);
			operatorHandler.setNext(clearAllHandler);
			clearAllHandler.setNext(clearLatestKeyHandler);
			clearLatestKeyHandler.setNext(immediateComputeHandler);
			immediateComputeHandler.setNext(pointHandler);
		
			$(".calculator-btn").click(function(){
				var currentInput = this.title;
				var allInput=$("#result").val();
				
				var temp=numberHandler.handleRequest(currentInput,allInput);
				$("#result").val(temp);
				var index1=temp.indexOf("+");
				var index2=temp.indexOf("-");
				var index3=temp.indexOf("*");
				var index4=temp.indexOf("/");
				if(index1==-1&index2==-1&index3==-1&index4==-1){
					$("#computeItem").val(allInput);
				}
				
			});
		});
		
		InputHandler = function () {
			this.next = null;
			this.setNext = function(handler) {
				this.next = handler;
			};

			this.handleRequest = function(currentInput,allInput) {

			}
		}
		
		<!-- 处理数字键 -->
		NumberHandler = function (){this.NumberKeyArray = ["0","1","2","3","4","5","6","7","8","9"];}
		NumberHandler.prototype = new InputHandler();
		NumberHandler.prototype.handleRequest = function(currentInput,allInput) {
			var isNumber = $.inArray(currentInput,this.NumberKeyArray);
			if(isNumber!=-1){
				var temp = allInput+currentInput;
				return temp;
			}else{
				if(this.next){
					return this.next.handleRequest(currentInput,allInput);
				}
			}
		}
		
		<!-- 处理操作符 -->
		OperatorHandler = function () {this.OperatorArray=["+","-","/","*"];}
		OperatorHandler.prototype = new InputHandler();
		OperatorHandler.prototype.handleRequest = function(currentInput,allInput) {
			var isOperator=$.inArray(currentInput,this.OperatorArray);
			if(isOperator!=-1){
				var temp="";
				if(allInput.length!=0){
					var lastChar = allInput.substr(allInput.length-1,1);
					var tempIsOperator = $.inArray(lastChar,this.OperatorArray);
					if(tempIsOperator==-1){
						temp=allInput+currentInput;
					}else{
						temp=allInput;
					}
				}
				return temp;
			}else{
				if(this.next){
					return this.next.handleRequest(currentInput,allInput);
				}
			}
		}
		
		<!-- 清空所有 -->
		ClearAllHandler = function (){}
		ClearAllHandler.prototype = new InputHandler();
		ClearAllHandler.prototype.handleRequest = function(currentInput,allInput) {
			if(currentInput=="C"){
				var temp = "";
				return temp;
			}else{
				if(this.next){
					return this.next.handleRequest(currentInput,allInput);
				}
			}
		}
		
		<!-- 清除最后一次输入 -->
		ClearLatestKeyHandler = function (){}
		ClearLatestKeyHandler.prototype = new InputHandler();
		ClearLatestKeyHandler.prototype.handleRequest = function(currentInput,allInput) {
			if(currentInput=="<-"){
				var temp="";
				if(allInput.length > 0){
					temp=allInput.substr(0,allInput.length-1);
				}
				return temp;
			}else{
				if(this.next){
					return this.next.handleRequest(currentInput,allInput);
				}
			}
		}
		
		<!-- 直接计算 -->
		ImmediateComputeHandler = function () {this.ImmediateComputeKeyArray=["x²","¼","%","√","="];}
		ImmediateComputeHandler.prototype = new InputHandler();
		ImmediateComputeHandler.prototype.handleRequest = function(currentInput,allInput) {
			if(allInput.length<=1){
				return allInput;
			}
			var isCompute=$.inArray(currentInput,this.ImmediateComputeKeyArray);
			if(isCompute!=-1){
				var result=computeResult(allInput)
				switch(isCompute){
					case 0:
						result=result*result;
						break;
					case 1:
						if(result!=0){
							result=1/result;
						}
						break;
					case 2:
						result=readonly/100;
						break;
					case 3:
						if(result<0){
							result=0;
						}else{
							result=Math.sqrt(result);
						}
						break;
				}
				return result+"";
			}else{
				if(this.next){
					return this.next.handleRequest(currentInput,allInput);
				}
			}
		}
		
		<!-- 小数点 -->
		PointHandler = function () {}
		PointHandler.prototype = new InputHandler();
		PointHandler.prototype.handleRequest = function(currentInput,allInput) {
			if(currentInput=="."){
				var temp=allInput;
				if(allInput.length!=0){
					var containPoint = allInput.indexOf(".");
					if(containPoint==-1){
						temp=allInput+currentInput;
					}
				}
				return temp;
			}else{
				if(this.next){
					return this.next.handleRequest(currentInput,allInput);
				}
			}
		}
		
		function computeResult(allInput){
			var computeItemArray=getComputeItemArray(allInput);
			computeItemArray =computeCore(computeItemArray,"*");
			if(computeItemArray.length!=1){
				computeItemArray =computeCore(computeItemArray,"/");
			} 
			if(computeItemArray.length!=1){
				computeItemArray =computeCore(computeItemArray,"+");
			}
			if(computeItemArray.length!=1){
				computeItemArray =computeCore(computeItemArray,"-");
			}
			return parseFloat(computeItemArray[0]);
		}
		
		function computeCore(computeItemArray,operator){
			var opIndex=$.inArray(operator,computeItemArray);
			while(opIndex!=-1){
				var num1 = parseFloat(computeItemArray[opIndex-1]);
				var num2 = parseFloat(computeItemArray[opIndex+1]);
				var result;
				switch(operator){
					case "+":
						result=num1+num2;
						break;
					case "-":
						result=num1-num2;
						break;
					case "*":
						result=num1*num2;
						result=Math.round(result*100)/100;
						break;
					case "/":
						result=num1/num2;
						result=Math.round(result*100)/100;
						break;
				}
				computeItemArray.splice(opIndex-1,3,result+"");
				opIndex=$.inArray(operator,computeItemArray);
			}
			return computeItemArray;
		}
		
		function getComputeItemArray(allInput){
			var computeItemArray =[];
			var totalLength=allInput.length;
			var operatorArray=["+","-","/","*"];
			var i=0;
			while(i<totalLength){
				var j=i;
				for(;j<totalLength;j++){
					var tempChar=allInput[j];
					var isOperator=$.inArray(tempChar,operatorArray);
					if(isOperator!=-1){
						break;
					}
				}
				var tempStr="";
				if(i==j){
					tempStr= allInput.substr(i,1);
					i=j+1;
				}else{
					tempStr= allInput.substring(i,j);
					i=j;
				}
				computeItemArray.push(tempStr);
			}
			var lastItem=computeItemArray[computeItemArray.length-1];
			var isOperator=$.inArray(lastItem,operatorArray);
			if(isOperator!=-1){
				computeItemArray.pop();
			}
			return computeItemArray;
		}
	</script>
</head>
<body>
	<div class="container">
		<div class="row">
			<div class="col-4 offset-4 display-border" style="margin-top:50px;">
				<div class="row">
					<h3>计算器</h3>
				</div>
				<div class="row calculator-row">
					<input id="result" type="text" class="w-100" readonly="readonly"></input>
				</div>
				<div class="row calculator-row">
					<input id="computeItem" type="text" class="w-100" readonly="readonly"></input>
				</div>
				<div class="row calculator-row">
					<div class="col">
						<button id="percent" type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="%" >%</button>
					</div>
					<div class="col">
						<button id="" type="button" class="btn btn-info calculator-btn"  data-toggle="tooltip" data-placement="top" title="√">√</button>
					</div>
					<div class="col">
						<button type="button" class="btn btn-info calculator-btn"  data-toggle="tooltip" data-placement="top" title="x²">x²</button>
					</div>
					<div class="col">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="¼">¼</button>
					</div>
				</div>
				<div class="row calculator-row">
					<div class="col-6">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="C">Clear</button>						
					</div>
					<div class="col-3">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="<-"><-</button>
					</div>
					<div class="col-3">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="/">÷</button>
					</div>
				</div>
				<div class="row calculator-row">
					<div class="col">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="7">7</button>
					</div>                                                                                    
					<div class="col">                                                                         
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="8">8</button>
					</div>                                                                                    
					<div class="col">                                                                         
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="9">9</button>
					</div>                                                                                    
					<div class="col">                                                                         
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="*">×</button>
					</div>
				</div>
				<div class="row calculator-row">
					<div class="col">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="4">4</button>
					</div>                                                                                    
					<div class="col">                                                                         
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="5">5</button>
					</div>                                                                                    
					<div class="col">                                                                         
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="6">6</button>
					</div>
					<div class="col">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="-">-</button>
					</div>
				</div>
				<div class="row calculator-row">
					<div class="col">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="1">1</button>
					</div>                                                                                    
					<div class="col">                                                                         
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="2">2</button>
					</div>                                                                                    
					<div class="col">                                                                         
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="3">3</button>
					</div>
					<div class="col">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="+">+</button>
					</div>
				</div>
				<div class="row calculator-row">
					<div class="col-6">
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="0">0</button>
					</div>                                                                                    
					<div class="col-3">                                                                         
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title=".">.</button>
					</div>                                                                                    
					<div class="col-3">                                                                         
						<button type="button" class="btn btn-info calculator-btn" data-toggle="tooltip" data-placement="top" title="=">=</button>
					</div>
				</div>
			</div>
		</div>
	</div>
</body>
</html>

以上是关于编写计算器程序学习JS责任链模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式——责任链

一文带你玩转设计模式之「责任链」

工厂模式策略者模式责任链模式综合应用

一天学习一个设计模式之责任链模式

设计模式学习-责任链模式

学习设计模式之责任链模式