プロトコル向けプログラミング


SWIFTのコアパワーシャフト


ついにプログラミングの複数のレベルを超え,プロトコル向けのプログラミングに移行した.個人的には、次の文章は反応型プログラミングであり、最も注目し、重点的に考慮すべき(実際には、学習し、応用すべき)例だと考えています.このパターンを理解するために、プロトコル、Extension、Genericに関する記事をSWIFTに載せて、簡単に確認すれば良いのです.

プロトコル向けのプログラミング?


オブジェクト向けプログラミングに基づく言語の多くはクラス継承を用いてタイプの共通機能を実現する.しかしながら,swiftの標準ライブラリから,タイプに関連する大部分は構造体で実現され,共通の機能を有することが分かる.どうしてそうしなければならないのですか.
オブジェクト向けプログラミングは使用機能にいくつかの欠点がある.

  • 最初はSuperClassに所属しています.これはExtensionの記事でも言及していますが、クラスの場合は垂直に拡張されています.機能を継承するにはSuperClassをよく理解する必要があります.SubClassには不要な変数、定数、関数が必要です.SuperClassを理解するには、開発者の立場だけでなく、多くの不要な継承があります.

  • 2つ目はValue typeが使えないことです.参照タイプの追跡コストが高い.しかし,機能を増やすためには,構造体や列挙形式で実現しても関係のないタイプをクラスとして実現しなければならない.参照タイプのトレースを追加する必要はありません.
  • プロトコル向けプログラミングは、これらの機能的な欠点を補う利点がある.
  • の値タイプは、
  • を使用できます.
  • 参照タイプを使用する場合、SuperClassとは別に付加機能
  • を実施することができる.
  • の値タイプを使用すると継承できないため、機能を再実装するたびの制限を克服します.
  • 機能モジュール化
  • 定義されたAPIのみをインポートできます(APIは必要ありません)
  • SWIFTはどのようにこのパターンを実現するのに役立ちますか?コアにはプロトコル、拡張、JENICがあります.

    プロトコルの初期実装


    なぜ3つの文法がプロトコル向けプログラミングの核心になるのか.すでに3つの要素を学んでいれば、たぶん感じられるだろう.JENICはすべてのタイプで流れており、Extensionはそのタイプの機能を拡張することができ、プロトコルはその機能を強制的に実現することができる.答えがある気がするこの3つの構文要素を使用してPOPを実装することができ、プロトコルの初期実装から始めましょう.

    契約の初期実施?


    POPの利点としては「値タイプを使用すると継承できず、毎回機能を再実現する限界を克服した」とある.しかし,プロトコルさえ守れば,それぞれの機能を再実装しなければならない.どうやってこの限界を克服しますか?プロトコルと拡張を組み合わせてこそ可能です.次のコードを参照してください.
    protocol Receivable {
     func receive(data: Any?, from: Sendable)
    }
    
    extension Receivable {
     func receive(data: Any?, from: Sendable) {
      print("receive!!")
     }
    }
    
    class Message: Receivable {
     var to: Receivable?
    }
    
    let message = Message()
    message.receive() // "receive!"
    プロトコルは、要求された機能を実装できません.しかし、拡張と組み合わせることで、本当にニーズを実現することができます.また,プロトコルで必要な機能のみを実装・区別する場合,POPの利点は「不要なAPIの他に定義されたAPIのみを導入し,機能をモジュール化する」ことである.
    ご存じのように、ストレージ・プロシージャはExtensionでは実装できません.それぞれのタイプに直接現れなければならない.
    プロトコル拡張で実装されている機能を使用せずに、タイプの特定の状況に応じて変更する場合は、どのように使用しますか?再定義
    class Message: Receivable {
     var to: Receivable?
     func receive(data: Any?, from: Sendable) {
      print("change Receive!!")
     }
    }
    継承のように書き換える必要はありません.クラスを再定義すればいいです.ということで.
  • は、特定のプロトコルのタイプに適合するプロトコル要件を検索し、すでに実装されている場合、この機能
  • を使用する.
  • がない場合、プロトコルを使用して初期実装される.
  • いいですね.ジェニーンリックを加えたら?リサイクル性が大幅に向上します.

    +ジェニーンリック

    protocol SelfPrintable {
     func printSelf()
    }
    
    extension SelfPrintable where Self: Container {
     func printSelf() {
      print(items)
     }
    }
    
    protocol Container: SelfPrintable {
     associatedtype: ItemType
     var items: [ItemType] { get set }
     var count: Int { get }
     mutating func append(item: ItemType)
     subscript(i: Int) -> ItemType { get }
    }
    
    extension Container {
     mutation func append(_ item: ItemType) {
      items.append(item)
     }
      var count: Int {
       return items.count
      }
      subscript(i: Int) -> ItemType {
       return items[i]
      }
    }
    Containerプロトコルは、関連タイプ(Generic)を使用してより柔軟に応答するタイプとして定義されます.また,プロトコルの初期実装により共通の機能が早期に実現されたため,実際のプロトコルのタイプに従うにはさらなる実装は必要ない.
    これによりPOPはクラスの継承よりも機能単位を強く共有することができる.swiftクラスはマルチ継承をサポートしていないため、親クラスの機能が欠けている場合はサブクラスで再実装する必要がありますが、プロトコルが初期実装されたプロトコルを採用している場合は、継承および追加の実装は必要ありません.協定を採用すればいい.

    拡張のデフォルトタイプ


    このプロトコルの初期実装は、スイッチの基本タイプを拡張できますか?基本タイプを拡張し、目的の機能を追加できます.
    protocol SelfPrintable {
     func printSelf()
    }
    
    extension SelfPrintable {
     func printSelf() {
      print(self)
     }
    }
    
    extension Int: SelfPrintable {
     // 초기구현 사용
    }
    前述したように,コードを修正できない基本タイプIntにプロトコルを採用するだけで,初期実装に伴う共通機能を定義できる.強力

    整理する


    実際,オブジェクト向けのモードをプロトコルと比較するのはでたらめである.プロトコルもオブジェクト向けであり,オブジェクト間のインタラクションも存在する.ただし、「オブジェクトのインタラクション、各オブジェクトの機能を実現するときに、より良いモードがありますか?」苦悩の中で生じるパターンなので、機能、拡張性、効率に集中して苦悩したほうがいいでしょう.これからはプログラミングで積極的に使いましょう.