Как разделить калькулятор logi c на собственный класс? (используя Xcode / Swift 11.3.1) - PullRequest
0 голосов
/ 01 марта 2020

Я построил простой iOS калькулятор, используя Xcode, это был один контроллер представления и один класс, Я должен поместить калькулятор logi c в отдельный класс , но я Я не уверен, как go об этом. Создать новый класс внутри исходного класса или за его пределами? Исходный класс имел @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 Ответ

0 голосов
/ 02 марта 2020

Шаг 1:

Определите, что должен делать класс бизнес-логики c, а что нет:

  • Поскольку это чистая логика c, это должно быть агности c от системы тегов. Вы должны предоставить это чисто математические модели.
  • Он должен отправлять сообщения на ваш контроллер представления, когда вычисления завершены, или экран должен быть очищен.

Шаг 2:

Определите ваши модели как необработанные перечисления:

enum Operand {
    case plus
    case minus
    case times
    case divisor
}

enum SpecialOperands {
    case dot
    case clear
    case whitespace
    case compute
}

Шаг 3 (В файле CalculatorBusinessLogi c .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):

Выполните контракт, переместите все связанные с логикой c атрибуты в класс:

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 */)
        }
        //...

    }

}

Используя Test Driven Разработка здесь может помочь вам обработать сложные случаи ошибок (неправильный операнд, деление на ноль ...)

Шаг 5: (В вашем файле ViewController.swift):

Объявить лог c класс:

var calculatorLogic: CalculatorBusinessLogic = Calculator()

Установить делегата в viewDidLoad:

calculatorLogic.delegate = self

Запустить функции калькулятора logi c всякий раз, когда вы обнаружите соответствующие входы. Реализуйте делегата для реагирования на результаты вычислений:

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

    func clearScreen() {
        lblDisplay.text = ""
    }
}

Подробнее о том, как разделить классы в приложении iOS, можно узнать, прибегая к помощи архитектуры адаптеров портов / чистой архитектуры.

...