也不知道何時冒出了面向協議編程,很多文章都開始大談面向協議編程,拋棄了之前都還暢談面向對象編。也許一個技術用久了,就會漸漸表現出其不足之處,當這種不足讓人無法忍受,就會去尋找新的解決方法,來彌補現在的不足,一個新的事物也就因此而誕生。
面向對象,從開始接觸編程開始就要求用面向對象的思想去設計代碼,當類之間的關系變得越來復雜,類之間的繼承層級越來越深,就會出現類似樹形結構,當我們想重用樹形末端的代碼時,不得不把上層直至樹根的代碼一起添加,也不管有用沒用的代碼。面向協議編程,我的理解就是解除這種情況的出現,把功能分散開來,通過組合的方式來創建出一個類,讓這個類擁有它應該有的功能,分散出來的功能也可以在其他地方復用,不會引入過多的不必要的的代碼,當然這個取決于功能的粒度大小。
swift恰好支持面向協議編程特性,自己還需要從面向對象中走出了,認真理解,學習面向協議,更重要的是在實踐中去應用。下面就是對面向協議的一個簡單窺探吧,體驗它的好處
初體驗
這是一個簡單的demo。先看圖:
當點擊登錄按鈕,兩個輸入框及按鈕都會左右抖動,然后一行提示文字漸漸顯示,最后在慢慢消失。可能最開始拿到這個需求,要么在點擊按鈕的時候分別對控件進行動畫控制或者自定義控件中添加動畫功能,這樣要么在控制器會有很多代碼,要么同樣一個抖動動畫代碼會出現在自定義的輸入框代碼中,也會出現在自定義按鈕的代碼中。本著不要重復造輪子的原則,面向協議就會很好解決這些問題。
1.自定義這三種控件的類,以此來添加動畫特效
// 自定義的輸入框類,遵守抖動協議
class SP_TextField: UITextField, SharkAnimation {
}
// 自定義的按鈕類,遵守抖動協議
class SP_Button: UIButton,SharkAnimation {
}
// 自定義label類,遵守漸變協議
class SP_Label: UILabel, FlashAnimation {
}
2.定義兩個協議
// 左右抖動協議
protocol ShakeAnimation {
}
// 由于動畫是加在view上的,所以要保證遵守的協議類必須是繼承自UIView,所以使用where限制
extension ShakeAnimation where Self : UIView {
//抖動的方法的默認實現
func shake() {
let shakeAni = CAKeyframeAnimation(keyPath: "transform.translation.x")
shakeAni.values = [-8,0,8,0]
shakeAni.duration = 0.25
shakeAni.repeatCount = 5
self.layer.add(shakeAni, forKey: nil)
}
}
// 漸變的協議
protocol FlashAnimation {
}
// 同樣需要遵守的類是繼承自UIView的類
extension FlashAnimation where Self : UIView {
// 漸變方法的默認實現
func flash() {
UIView.animate(withDuration: 0.25, animations: {
self.alpha = 1.0
}) { (isFinished) in
UIView.animateKeyframes(withDuration: 0.25, delay: 2.0, options: [], animations: {
self.alpha = 0.0
}, completion: nil)
}
}
}
3.在控制器中使用
class ViewController: UIViewController {
@IBOutlet weak var nameTextField: SP_TextField!
@IBOutlet weak var passwordTextField: SP_TextField!
@IBOutlet weak var tipLabel: SP_Label!
@IBOutlet weak var loginButton: SP_Button!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 按鈕點擊事件
@IBAction func buttonClick(_ sender: SP_Button) {
// 點擊時直接調用就可以了
nameTextField.shake()
passwordTextField.shake()
tipLabel.flash()
loginButton.shake()
}
}
4.如果以后還有其他控件,直接遵守協議,就擁有了抖動或者漸變的功能,是不是感覺很爽,很方便,復用性也強。當然這個功能的粒度需要自己掌控
這個是在學習中看到的一個示例,自己實現了一遍,是不是感覺很爽,擁抱面向協議吧。
獨立思考,不屈從世界,安靜內心,瘋子一樣行動,不理會周遭的嘈雜,有節奏的行走在coding~