1个全局函数或许多实例函数

时间:2017-06-18 21:22:28

标签: ios swift

如果有两个类似的类需要相同的功能。最好是全局编写函数,或者在每个类中编写两次相同的函数。实施例

选项1:两个实例函数

class A {

    func buttonTapped() {
        upvote(id)
    }

    func upvote(postID:String) {
        // upvote the post
    }
}

class B {

    func buttonTapped() {
        upvote(id)
    }

    func upvote(postID:String) {
        // upvote the post
    }
}

选项2:一个全局函数

class A {
    func buttonTapped() {
        upvote(id)
    }
}

class B {
    func buttonTapped() {
        upvote(id)
    }
}

func upvote(postID:string) {
        // upvote the post
}

或者有更好的选择吗?

3 个答案:

答案 0 :(得分:3)

我不建议。

您应该有一个数据模型类,upvote函数应该是该类的一部分。

class Post {
    var postID: String
    public private(set) var votes: Int

    ...

    func upvote() {
        self.votes += 1
    }
}

然后你会把它称为

 somePost.upvote()

答案 1 :(得分:3)

有人建议继承,但您应该始终考虑composition over inheritance(有关此主题的更多内容:https://en.wikipedia.org/wiki/Composition_over_inheritance

也许有很多课程可以从upvote方法中获益? 例如,如果你正在实现另一个Instagram克隆,你可以让StoriesPosts具有相同的upvoting接口,但是从同一个父级继承它们是不明智的

在这种情况下,我们可以实现类似的东西:

protocol Votable {
  func upvote()
}

extension Votable {
  func upvote() {
    // do upvoting
  }
}

然后您可以将此trait添加到您的课程中:

class A: Votable {
    func buttonTapped() {
        upvote(id)
    }
}

class B: Votable {
    func buttonTapped() {
        upvote(id)
    }
}

然后你去了:两个类的相同函数实现(如果你想实现对同一协议的其他扩展,甚至是具有相同接口的不同类),没有类继承。

编辑:正如@Paulw11指出的那样,你应该总是在开始时采用更简单的解决方案。如果只有Posts需要一个upvote方法,不要乱用继承或组合,只在他们需要的地方实施这些方法,然后根据产品的演变进行相应的重构。

答案 2 :(得分:2)

我将使用常用函数创建一个" parent" -class,然后让A和B类继承自" parent" -class。像这样:

class Parent {
   func upvote(postID:String) {
        // upvote the post
    }
}

class A: Parent {

    func buttonTapped() {
        upvote(id)
    }

}

class B: Parent {

    func buttonTapped() {
        upvote(id)
    }
}