編寫計算器程式學習JS責任鏈模式
阿新 • • 發佈:2018-11-15
設計模式中的責任鏈模式能夠很好的處理程式過程的邏輯判斷,提高程式可讀性。
責任鏈模式的核心在於責任鏈上的元素判斷能夠處理該資料,不能處理的話直接交給它的後繼者。
計算器的基本樣式:
通過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>