2017-06-18 30 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方法,請不要混淆繼承或組合,只在需要的地方實現方法,然後根據產品的演變進行相應的重構。