2017-06-18 55 views
1

如果有两个类似的类需要相同的函数。全局编写函数还是在每个类中写入相同的函数两次更好?防爆。1全局函数或许多实例函数

选项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

我不会建议。

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

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

    ... 

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

那么你会称呼其为

somePost.upvote() 
+0

谢谢,这很有趣。将票定义为只有getVotes()方法而获得的优势是什么? –

+0

还有一个优点,这是一个类的结构? –

+0

没有'优势',但语义'投票'应该是一个属性,而不是一个函数。函数意味着某种操作(如投票),所以虽然可以使用getter函数,但使用属性更好。请注意,我只是发现了创建只读属性的更好方法,因此我更新了答案。 – Paulw11

2

我会用通用函数创建一个“父类”类,然后让类A和B继承“父类”类。像这样:

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

class A: Parent { 

    func buttonTapped() { 
     upvote(id) 
    } 

} 

class B: Parent { 

    func buttonTapped() { 
     upvote(id) 
    } 
} 
3

有人建议继承,但你应该总是考虑composition over inheritance(更多关于这个问题在这里:https://en.wikipedia.org/wiki/Composition_over_inheritance

也许有很多的类那可以从upvote方法中获益?例如,如果您正在实施yet-another-instagram-clone,则可能有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方法,请不要混淆继承或组合,只在需要的地方实现方法,然后根据产品的演变进行相应的重构。