Object-Oriented Programming: Beyond the Basics

Oct 17 2023 · Swift 5.9, iOS 17, Xcode 15

Lesson 04: Single Responsibility & Open-Closed Principles

Demo 1

Episode complete

Play next episode

Next

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Heads up... You’re accessing parts of this content for free, with some sections shown as obfuscated text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Open the starter playground. You’ll find the system method already implemented. It uses two types from the sources folder for demo purposes: SimulatedFile and SimulatedView. You won’t need to make any changes to those two types. Build and run. It writes our log file.

class System {
  var currentFileNameNumber = 5
  var activeView = SimulatedView()
  func doMainOperation(num1: Int, num2: Int) {
    let sum = num1 + num2 // 1
    let stringSum = "\(sum)" // 2
    let formatter = NumberFormatter() // 3
    formatter.locale = Locale(identifier: "ar")
    let localizedSum = formatter.string(from: NSNumber(integerLiteral: sum))!
    let attributes: [NSAttributedString.Key : Any] = [ // 4
      NSAttributedString.Key.foregroundColor: UIColor.blue,
      NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 16),
      NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue
    ]
    let styledString = NSAttributedString(string: localizedSum, attributes: attributes)
    activeView.labelText = localizedSum // 5
    let activeFileName = "logFile\(currentFileNameNumber).log" // 6
    var logFileHandler = SimulatedFile(fileName: activeFileName)
    logFileHandler.openFile()
    if logFileHandler.numberOfLines >= 100 { // 7
      currentFileNameNumber += 1
      let newActiveFileName = "logFile\(currentFileNameNumber).log"
      logFileHandler.closeFile()
      logFileHandler = SimulatedFile(fileName: activeFileName)
      logFileHandler.openFile()
    }
    let logEntry = "\(num1) + \(num2) = \(sum). Presented: \(localizedSum)" // 8
    logFileHandler.writeData(logEntry) // 9
    logFileHandler.closeFile() // 10
  }
}
class Calculator {
}
class Calculator {
  class func add(num1: Int, num2: Int) -> Int { 
    num1 + num2
  }
}
func doMainOperation(num1: Int, num2: Int) {
  let sum = Calculator.add(num1: num1, num2: num2) 
  ...
class StringManager {
  class func toLocalizedValue(num: Int) -> String {
    let formatter = NumberFormatter()
    formatter.locale = Locale(identifier: "ar")
    let localizedSum = formatter.string(from: NSNumber(integerLiteral: num))!
    print(localizedSum)
    return localizedSum
  }
}
func doMainOperation(num1: Int, num2: Int) {
  let sum = Calculator.add(num1: num1, num2: num2)
  let stringSum = "\(sum)" 
  let localizedSum = StringManager.toLocalizedValue(num: sum) // new code
class ViewPresenter {
  class func showValueOnView(value: String, view: SimulatedView) {
    let attributes: [NSAttributedString.Key : Any] = [
      NSAttributedString.Key.foregroundColor: UIColor.blue,
      NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 16),
      NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue
    ]
    let styledString = NSAttributedString(string: value, attributes: attributes)

    view.labelText = styledString
  }
}
func doMainOperation(num1: Int, num2: Int) {
  let sum = Calculator.add(num1: num1, num2: num2)
  let stringSum = "\(sum)"
  let localizedSum = StringManager.toLocalizedValue(num: sum)

  ViewPresenter.showValueOnView(value: localizedSum, view: activeView) // new code

  let logEntry = "\(num1) + \(num2) = \(sum). Presented: \(localizedSum)"
  ...
class LogManager {
  public func addLogEntry(_ entry: String) {
  }
}
class LogManager {
 private static var currentInstance: LogManager?

 private init() {
 }

 class func singleton() -> LogManager {
  if currentInstance == nil {
    currentInstance = .init()
  }
  return currentInstance!
  }
  ...
}
class LogManager {
  private static var currentInstance: LogManager?
  private static let maxLogSize = 100 // new code
  private var currentFileNameNumber = 5 
  private var logFileHandler: SimulatedFile! 

  private init() {
    let activeFileName = fileName(numbered: currentFileNameNumber) 
    logFileHandler = SimulatedFile(fileName: activeFileName) 
    logFileHandler.openFile() 
  }

  class func singleton() -> LogManager {
    if currentInstance == nil {
      currentInstance = .init()
    }
    return currentInstance!
  }

  public func addLogEntry(_ entry: String) {
    verifyLogSize() 
    print("\(entry) | Log entry saved.")
  }

  private func fileName(numbered: Int) -> String { // new code
    "logFile\(numbered).log"
  }

 private func verifyLogSize() { // new code
  if logFileHandler.numberOfLines >= LogManager.maxLogSize_const {
    currentFileNameNumber += 1
    logFileHandler.closeFile()
    let newFileName = fileName(numbered: currentFileNameNumber)
    logFileHandler = SimulatedFile(fileName: newFileName)
    logFileHandler.openFile()
    }
  }
}
func doMainOperation(num1: Int, num2: Int) {
  ...
  let logEntry = "\(num1) + \(num2) = \(sum). Presented: \(localizedSum)"
  LogManager.singleton().addLogEntry(logEntry) // new code
See forum comments
Cinema mode Download course materials from Github
Previous: Instruction 2 Next: Instruction 3