我有FirstViewController,它有一些IBOutlets,函式和presenter。然后我有一個SecondViewController,它有和FirstViewController相同的功能,但有一個額外的功能,IBOutlets和presenter與FirstViewController的presenter完全相同,但有一個額外的功能。
我讀過關于OOP和POP的文章,人們建議使用POP。
但是我的問題是,在這種情況下,如果我需要第二視圖控制器具有與第一視圖控制器相同的功能和IBOutlets,繼承是不是比協議更好?
如果我想使用協議,如果我想避免重寫相同的代碼,應該怎么做?使用協議的默認實作?
使用繼承
class FirstViewController。UIViewController {
@IBOutlet weak var firstButton: UIButton!
@IBOutlet weak var secondButton: UIButton!
...!
...!
func firstFunction() {
...。
}
func secondFunction() {
...
}
}
class SecondViewController。FirstViewController {
@IBOutlet 弱化 var additionalButton: UIButton!
...!
...!
func additionalFunction() {
...。
}
使用默認實作
protocol FirstViewControllerProtocols {
func firstFunction()
func secondFunction()
}
extension FirstViewControllerProtocols {
func firstFunction() {
print("do something"/span>)
}
func secondFunction() {
print("do something")
}
}
然后
class FirstViewController。UIViewController, FirstViewControllerProtocols {
@IBOutlet 弱化 var firstButton: UIButton!
@IBOutlet weak var secondButton: UIButton!
}
protocol SecondViewControllerProtocol {
func thirdFunction()
}
extension SecondViewControllerProtocol {
func thirdFunction() {
print("do something new"/span>)
}
}
class SecondViewController。UIViewController, FirstViewControllerProtocols, SecondViewControllerProtocol{
@IBOutlet 弱化 var additionalButton: UIButton!
}
但是用協議的方法,我不能繼承iboutlets.
。uj5u.com熱心網友回復:
你的POP的例子是不正確的。重點只是將共享代碼提取到協議中,而不是不必要地重復。所以FirstViewControllerProtocols是有意義的,但絕對沒有理由要SecondViewControllerProtocol。什么第二型別符合SecondViewControllerProtocol?如果你擺脫了這一點,你會發現大多數的問題都消失了。
但不是所有的問題。你還在談論IBOutlets,這不僅僅是一個共享代碼的問題。如果SecondViewController真的是一種 FirstViewController(而不僅僅是 "碰巧共享幾個按鈕"),那么繼承可能是有意義的。如果只是有幾個相關的IBOutlets,那就復制這些IBOutlets,因為它們與型別有關。這不是繼承。
鑒于你的描述,你的想法是:"我有很多代碼剛好有點類似,所以我應該做一個東西來抽象它。" 這不是辦法;如果它們只是 "有點類似",那么問問你自己,你是否在毫無目的地創造抽象。如果FirstViewController被改變了,那么SecondViewController必然也會改變嗎?如果不是,它們其實并沒有什么關系。"DRY"(Do not Repeat Yourself)是關于概念,而不是按鍵。
這種方法是:"我有兩樣東西,它們在本質上是相似的,會隨著時間的推移發生類似的變化,并且有應該適用于這兩樣東西的演算法,所以我應該提取一個協議。"
uj5u.com熱心網友回復:
將一個視圖控制器類從另一個自定義視圖控制器中子類化(以及在協議中使用默認的實作),乍一看似乎很優雅,但十有八九是個錯誤。如果它是一個抽象的 "基礎視圖控制器",對于一些共同的行為,有時會產生一些效用(盡管取決于這種共同的行為是什么,通常有更好的模式)。
但是如果這兩個視圖控制器類被用于故事板中的不同場景(你提到的共享IBOutlets表明情況就是如此),根據我的經驗,這將成為維護的噩夢。我在一些早期專案中使用了這種模式,當時對我的代碼的優雅性相當滿意,但是當我后來修改和增強各自的視圖控制器時,我對兩個不同場景的兩個視圖控制器類如此緊密地糾纏在一起感到后悔。
如今,我們努力使視圖控制器類盡可能地細小和笨拙。(參見 Dave DeLong 的A Better MVC 帖子或視頻。這也是MVVM和相關模式背后的眾多激勵因素之一)。) 視圖控制器僅用于配置視圖并在用戶互動或其他系統事件發生時啟動行為。除此以外的任何事情一般都應該從視圖控制器中抽象出來。如果在不同的視圖控制器中存在共同的 UI 元素,我們通常會考慮將視圖控制器包含起來,將共享的 UI 抽象到第三個視圖控制器中,使其成為前兩個視圖控制器的子代。
因此,與其說是POP與OOP,不如問自己所有這些共享行為是否屬于這兩個視圖控制器中的任何一個。如果共享行為是各種 UIKit 委托方法(例如,表資料源、集合視圖委托方法等),那就需要一個解決方案。如果它們是業務邏輯,就需要一個不同的解決方案。如果它們是實用方法,又是另一種。如果它是一組普通的子視圖,同樣,又是另一種模式。這只是取決于。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/306781.html
標籤:
上一篇:我是否必須為每一個iOS新版本的發布重建我的應用程式,使其在AppStore上可用?
下一篇:MySQL如何四舍五入小數?
