如何将计算器逻辑拆分为自己的类?(使用Xcode/Swift 11.3.1)



我使用Xcode构建了一个简单的iOS计算器,它是一个视图控制器和一个类,我必须将计算器逻辑放入一个单独的类中,但我不知道该如何进行。我是在原始类内部还是外部创建一个新类?原始类具有@IBAction func numberPressed@IBAction func operandPressed

如何将输入传递到需要创建的新Calculator类中?

import UIKit
class ViewController: UIViewController {
@IBOutlet weak var lblDisplay: UILabel!
var numberOnDisplay: Double = 0
var previousNumber: Double = 0
var operand = 0
var isPerformingOperand = false

override func viewDidLoad() {
super.viewDidLoad()
lblDisplay.text = ""
}
// Inputs whatever number is pressed 0-9
@IBAction func numberPressed(_ sender: Any) {
let tag = (sender as! UIButton).tag
if isPerformingOperand == true {
isPerformingOperand = false
lblDisplay.text = String(tag)
numberOnDisplay = Double(lblDisplay.text!)!
} else {
lblDisplay.text = lblDisplay.text! + String(tag)
numberOnDisplay = Double(lblDisplay.text!)!
}
}
// Performs the operands including decimal, clear and backspace
@IBAction func operandPressed(_ sender: Any) {
let tag = (sender as! UIButton).tag

/* Operands:  = (99), . (10) X (12), ÷ (13), - (14), + (15) */
if tag == 10 {
if lblDisplay.text?.range(of: ".") == nil {
lblDisplay.text! += "."
}
}
if tag == 12 {
isPerformingOperand = true
previousNumber = Double(lblDisplay.text!)!
lblDisplay.text = "*"
operand = tag
} else if tag == 13 {
isPerformingOperand = true
previousNumber = Double(lblDisplay.text!)!
lblDisplay.text = "÷"
operand = tag
} else if tag == 14 {
isPerformingOperand = true
previousNumber = Double(lblDisplay.text!)!
lblDisplay.text = "-"
operand = tag
} else if tag == 15 {
isPerformingOperand = true
previousNumber = Double(lblDisplay.text!)!
lblDisplay.text = "+"
operand = tag
}
else if tag == 16 {
if lblDisplay.text != "" {
lblDisplay.text?.removeLast();
}
}
/* clear button tab17 */
else if tag == 17 {
lblDisplay.text = ""
previousNumber = 0
numberOnDisplay = 0
operand = 0
}


else if tag == 99 {
/*   = / + -   */
// operand tag
if operand == 12 {
lblDisplay.text = String(previousNumber * numberOnDisplay)
} else if operand == 13 {
lblDisplay.text = String(previousNumber / numberOnDisplay)
} else if operand == 14 {
lblDisplay.text = String(previousNumber - numberOnDisplay)
} else if operand == 15 {
lblDisplay.text = String(previousNumber + numberOnDisplay)
}
} 
} 
}

步骤1:

定义业务逻辑类应该做什么和不应该做什么:

  • 因为这是纯逻辑,所以它应该是标签系统的不可知论者。你必须为它提供纯粹的数学模型
  • 当计算完成时,它应该向视图控制器发送消息,或者屏幕应该被清除

步骤2:

将您的模型定义为原始枚举:

enum Operand {
case plus
case minus
case times
case divisor
}
enum SpecialOperands {
case dot
case clear
case whitespace
case compute
}

步骤3(在CalculatorBusinessLogic.swift文件中(:

通过提供一个必须满足的合同来定义业务类应该做什么:

protocol CalculatorBusinessLogic {
var delegate: CalculatorBusinessLogicDelegate? { get set }
func provideNumberInput(number: Int)
func provideOperandInput(operand: Operand)
func provideSpecialOperandInput(operand: SpecialOperands)
}

它应该将什么结果发送回您的视图控制器:

protocol CalculatorBusinessLogicDelegate: class {
func onComputationDone(previousNumber: Int, currentNumber: Int, operand: Operand, result: Int)
func clearScreen()
}

步骤4:(在Calculator.swift文件中(:

实现契约,将所有与逻辑相关的属性移动到类:

class Calculator: CalculatorBusinessLogic {
weak var delegate: CalculatorBusinessLogicDelegate?
var numberOnDisplay: Double = 0
var previousNumber: Double?
var currentNumber: Double?
var currentOperand: Operand?
var operand = 0
var isPerformingOperand = false
// TODO: handle inputs here, fire delegate when needed to notify View Controller
func provideNumberInput(number: Int) {
//...
}
func provideOperandInput(operand: Operand) {
//...
}
func provideSpecialCharacterInput(operand: SpecialOperands) {
//...
if operand == .clear {
delegate?.clearScreen()
}
if operand == .compute, let previousNumber = self.previousNumber, let currentOperand = self.currentOperand, let currentNumber = self.currentNumber {
delegate?.onComputationDone(previousNumber: previousNumber, currentNumber: currentNumber, operand: currentOperand, result: /* compute result here */)
}
//...
}
}

在这里使用测试驱动开发可以帮助您处理复杂的错误情况(错误的操作数、除以零…(

步骤5:(在ViewController.swift文件中(:

声明逻辑类:

var calculatorLogic: CalculatorBusinessLogic = Calculator()

在视图中设置代理DidLoad:

calculatorLogic.delegate = self

只要检测到相关输入,就启动计算器逻辑功能。实现委托对计算结果作出反应:

extension ViewController: CalculatorBusinessLogicDelegate {
func onComputationDone(previousNumber: Int, currentNumber: Int, operand: Operand, result: Int) {
lblDisplay.text = "(result)"
}
func clearScreen() {
lblDisplay.text = ""
}
}

您可以通过谷歌搜索端口适配器体系结构/Clean体系结构来阅读有关如何在iOS应用程序中分离类的更多信息。

最新更新