ios - 如何使用面向协议(protocol)的编程来改进我的 Swift 代码?

标签 ios swift protocol-oriented

我有一个以这种格式构建的相当大的项目:

class One : FirstThree {

    fileprivate var integers: [Int] {
        return [1, 2, 3, 101, 102]
    }

    override func allIntegers() -> [Int] {
        return integers
    }

    func doStuffForOne() {
        //does stuff unrelated to the other classes
    }
}

class Two : FirstThree {

    fileprivate var integers: [Int] {
        return [1, 2, 3, 201]
    }

    override func allIntegers() -> [Int] {
        return integers
    }

    func doStuffForTwo() {
        //does stuff unrelated to the other classes
    }
}

class Three : Numbers {

    fileprivate var integers: [Int] {
        return [301, 302, 303]
    }

    override func allIntegers() -> [Int] {
        return integers
    }

    func doStuffForThree() {
        //does stuff unrelated to the other classes
    }
}

class FirstThree : Numbers {

    fileprivate var integers: [Int] {
        return [1, 2, 3]
    }

    override func allIntegers() -> [Int] {
        return integers
    }

    func doStuffForFirstThree() {
        //does stuff unrelated to the other classes
    }
}

class Numbers {

    func allIntegers() -> [Int] {
        fatalError("subclass this")
    }

    func printMe() {
        allIntegers().forEach({ print($0) })
    }
}

Numbers 有许多方法,例如 printMe(),我希望我所有子类的任何实例都能够调用这些方法。

Numbers 还有一个 allIntegers() 函数,我希望这些子类的任何实例都能够调用该函数。作为变量,哪个可能更好?但是我不能覆盖子类中的变量。因此,我在每个子类中使用相同的私有(private)变量 integers,它由 allIntegers() 读取和返回。

另请注意,Numbers 的实例本身不应调用 allIntegers(),它只应在子类上调用。

最后,请注意一些子类包含相同的对象 1、2、3,然后每个子类都有一些自定义整数。但不是所有的子类。如果我后来决定所有这些子类都需要一个 4 整数,我必须手动遍历每个类并将 4 打入数组,这显然容易出错。

我已经阅读了面向协议(protocol)的编程,感觉其中可能有一个解决方案,或者我会很感激任何其他建议和创造性方法来构建更好的项目。

谢谢!

编辑

所有子类都是不同的,因为它们也有自己的功能要执行。我更新了代码以反射(reflect)这一点。

想象一下,像One 这样的给定类在整个代码库中被多次初始化,并且总是使用完全相同的整数 进行初始化。放置:

let one = One(integers: [1, 2, 3, 101, 102])

整个代码库都容易出错。

希望这能解决我提出的人为示例的一些问题。

解决方案

谢谢大家的帮助。这是我想出的解决方案(请假设所有类都有自己独特的方法)。

class One : FirstThree {

    override init() {
        super.init()
        self.integers = super.integers + [101, 102]
    }
}

class Two : FirstThree {

    override init() {
        super.init()
        self.integers = super.integers + [201]
    }
}

class Three : Numbers {
    var integers  = [301, 302, 303]
}

class FirstThree : Numbers {
    let integers = [1, 2, 3]
}

protocol Numbers {
    var integers: [Int] { get }
    func printMe()
}

extension Numbers {
    func printMe() {
        integers.forEach({ print($0) })
    }
}

最佳答案

更新

鉴于您添加到问题中的新信息,这是一种可能的方法

我实在忍不住所以稍微重构了一下命名:D

现在你有了协议(protocol)

protocol HasIntegers {
    var integers: [Int] { get }
    func printMe()
}

和一个添加了 printMe 功能的协议(protocol)扩展。

extension HasIntegers {
    func printMe() {
        integers.forEach { print($0) }
    }
}

最后你有 2 个类(代码中有 4 个类,但想法没有改变)。

类 A 总是包含 [1, 2, 3, 101, 102] 并且有自己的一组方法 (doSomething())

class A: HasIntegers {
    fileprivate (set) var integers: [Int] = [1, 2, 3, 101, 102]
    func doSomething() { }
}

B 总是包含 [1, 2, 3, 201] 并且有一组不同的方法 (doSomethingElse())

class B: HasIntegers {
    fileprivate (set) var integers: [Int] = [1, 2, 3, 201]
    func doSomethingElse() { }
}

A和B都符合HasInteger,然后自动接收printMe()方法。


OLD ANSWER

你不需要那个

我在你的代码中看到了很多东西:

  • 继承
  • protocols(确实没有协议(protocol) :D)
  • 计算属性
  • 职能
  • 类(class)(很多!)

但是没有明显的理由使用所有这些东西:)

你可以简单地写

class Box {
    fileprivate (set) var integers: [Int]

    init(integers:[Int]) {
        self.integers = integers
    }

    func printMe() {
        integers.forEach { print($0) }
    }
}

let one = Box(integers: [1, 2, 3, 101, 102])
let two = Box(integers: [1, 2, 3, 201])
let three = Box(integers: [1, 2, 3, 301, 302, 303])
let four = Box(integers: [401, 402])

关于ios - 如何使用面向协议(protocol)的编程来改进我的 Swift 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41771288/

相关文章:

swift - 带有解码器的 swift 中的 RLMArray : Ambiguous reference to member error

ios - 自定义底部栏不在自定义分段控件的正确位置

ios - 如何正确裁剪个人资料照片?

objective-c - 使用 NSString 进行 UTF8 解码

ios - 在没有 NavigationController 的情况下展开到特定的 ViewController

ios - 如何将 VNDetectRectanglesRequest 改进为 VNDetectCarRequest?

ios - 如何从选定的 UICollectionView 单元格中获取数据?

ios swift类符合协议(protocol)

swift - 无法对不可变值 : 'self' is immutable 使用变异成员