- 指向プログラミング・プロトコル(POPと呼ばれるプロトコル指向プログラミング)
- スウィフトは、プログラミングパラダイムで、Appleは2015年WWDCから追い出さ
スウィフトの標準ライブラリでは、POPの多数の影を見ることができます
- 一方、スウィフトは(OBJEC指向プログラミング、OOPをいう)オブジェクト指向プログラミング言語であります
OOPの開発にスウィフト、およびPOPは相補的であり、かつ、他のパーティーのためではない代替
P-OPは、設計OOPにおけるいくつかの欠陥を補うことができます
レビューOOP
- OOPの3つの機能:カプセル化、継承、ポリモーフィズム
- 古典的な使用を継承:
- クラス(例えば、クラスDのような)共通の親クラスに引き込むことができる多くの共通点を有している(例えばA、B、Cクラス)、複数のは、最後にA、B、Cのクラスは、クラスDを継承する場合
OOPの不備
- しかし、いくつかの問題は、次のような、OOPを使用して解決することはできません。
- 不足して抽出する方法をBVC、DVCパブリックメソッド?
class BVC: UIViewController {
func run() {
print("run")
}
}
class DVC: UITableViewController {
func run() {
print("run")
}
}
- OOPに基づくいくつかの解決策はないでしょうか?
- メソッドのターンは、別のオブジェクトAを実行し、BVCは、DVCオブジェクトAが特性を有している(いくつかのより多くの追加の依存関係)
- UIViewControllerのカテゴリを実行するメソッドを追加します(のUIViewControllerはますます肥大化になり、それが他のすべてのサブカテゴリーに影響します)
runメソッドは、親クラスの給与、多重継承の使用を抽出するには?(C ++は多重継承をサポートしています)(ダイヤモンド継承やその他の問題を生成するために、設計プロセスの複雑さを増大させ、必要が追加の開発者に対処するため)
POPソリューション
protocol Runnable {
func run()
}
extension Runnable {
func run() {
print("run")
}
}
class BVC: UIViewController, Runnable {}
class DVC: UIViewController, Runnable {}
もう一つの例
注目のPOPポイント
- プロトコルを作成するために優先権を与えるのではなく、親クラス(基底クラス)
- 優先順位の値型(構造体、列挙型)、よりもむしろ参照型(クラス)
- 延長契約を使用します
プロトコルの合意のために使用してはなりません
プロトコルプレフィックスの効果を使用しました
struct My {
var string: String
init(_ string: String) {
self.string = string
}
var numberCount: Int {
var count = 0
for c in string where("0"..."9").contains(c) {
count += 1
}
return count
}
}
extension String {
var my: My { return My(self) }
}
print("123kkk".my.numberCount) // 3
- 一般的な最適化 - N個の記憶特性の異なる複数種類の添加なし
struct My<Base> {
var base: Base
init(_ base: Base) {
self.base = base
}
}
- 最適化の拡張 - 拡張されたインスタンスとインスタンスの属性の特定のタイプに
extension My where Base == String {
var numberCount: Int {
var count = 0
for c in base where("0"..."9").contains(c) {
count += 1
}
return count
}
}
- 拡張型のメソッドとプロパティ
class Person {}
extension Person {
var my: My<Person> { My(self) }
static var my: My<Person>.Type { My(Person).self }
}
extension My where Base == Person { // 需要给对应子类扩充的话使用冒号,例如:Base: Person
func run() {
print("run")
}
static func test() {
print("test")
}
}
Person().my.run()
Person.my.test()
- プロトコル最適化 - ではない、各タイプの拡張にprefix属性
protocol MyCompatible {}
extension MyCompatible {
var my: My<Self> { My(self) }
static my: My<Self>.Type { My<Self>.self }
}
class String {}
extension String: MyCompatible {}
- 最終版
/// 前缀类型
struct My<Base> {
var base: Base
init(_ base: Base) {
self.base = base;
}
}
/// 利用协议扩展前缀属性
protocol MyCompatible {}
extension MyCompatible {
var my: My<Self> {
set {} // *** 为了扩充mutating方法,所以不能写只读属性
get { My(self) }
}
static var my: My<Self>.Type {
set {} // *** 为了扩充mutating方法,所以不能写只读属性
get { My<Self>.self }
}
}
/// 给字符串扩展功能
// 让String拥有my前缀属性
extension String : MyCompatible {}
// 给String前缀扩展功能
extension My where Base == String {
var numberCount: Int {
var count = 0
for c in base where("0"..."9").contains(c) {
count += 1
}
return count
}
mutating func run() {}
static func test() {}
}
var str = "666"
str.my.run()
String.my.test()
ベースサプリメント
- 拡張機能は、クラスのサブクラスを拡張することができます
class Person {}
class Student: Person {}
extension Person: MyCompatible {}
extension My where Base: Person {
func run() {}
static func test() {}
}
Person.my.test()
Student.my.test()
let p = Person()
p.my.run()
let s = Student()
s.my.run()
- 拡張機能は、一般的な合意を順守することができます
- 文字列、NSStringのとNSMutableString拡張を与えながら、
extension String: MyCompatible {}
extension NSString: MyCompatible {}
extension My where Base: ExpressibleByStringLiteral {
var numberCount: Int {
var count = 0
for c in (base as! String) where("0"..."9").contains(c) {
count += 1
}
return count
}
mutating func run() {}
static func test() {}
}
var str1 = "123xxx"
var str2: NSString = "123xxx"
var str3: NSMutableString = "123xxx"
print(str1.my.numbserCount)
print(str2.my.numbserCount)
print(str3.my.numbserCount)
プロトコルタイプ判別を使用します
func isArray(_ value: Any) -> Bool {
// value is Array<Any>
value is [Any]
}
print(isArray([1, 2])) // true
print(isArray(["1", 2])) // true
print(isArray(NSArray())) // true
print(isArray(NSMutableArray())) // true
print(isArray("12312421")) // false
protocol ArrayType {}
extension Array: ArrayType {}
extension NSArray: ArrayType {}
func isArrayType(_ type: AnyType) -> Bool { type is ArrayType.Type }
isArrayType([Int].self)
isArrayType([Any].self)
isArrayType(NSArray.self)
isArrayType(NSMuatbleArray.self)