1

libssh2を使用してSSHコマンドを実行するためのC++クラスを作成しています。

libssh2 SSHセッションのライフサイクルは、次の段階を経ます。

  1. 初期化(ローカルリソースを取得)
  2. ハンドシェイク/認証(リモートホストでSSHセッションを確立します)
  3. 切断(リモートホストでのSSHセッションを終了します)
  4. 無料(ローカルリソースを解放します。必要に応じて、手順3も実行します)。

ステップ1の前に、ステップ2でlibssh2に渡すソケットを開く必要があります。それ以降、libssh2はソケットへの参照を格納するため、ソケットを渡す必要はありません。手順4の後、ソケットを閉じることができます。

これをクラス(SSHSession)で公開しています。セットアップ(ステップ1と2)をctorで実行し、ティアダウン(ステップ3と4)をdtorで実行したいと思います(ステップ2は時間がかかるため、これはセッションのプールを開いたままにして、コマンドを実行するために再利用できるようにします)。

私の最初の試みはすべてのコードをに集中させSSHSession、そのctorはすぐに混乱し、「このステップが失敗した場合は、すでに行われたことを確認して元に戻す必要があります」ルーチンでした。dtorはそれほど複雑ではありませんでしたが、それでも「忙しすぎる」と感じました。

次に、作業をいくつかのクラスに分割し、取得/リリースの各ステップにRAIIを実装しました。

  • 手順1と4。
  • ステップ2および3。

SessionConnection手順2と3を実装するクラスを作成し、SessionHandle手順1と4を実装するタイプのメンバーを作成しました。また、データメンバーとしてソケットがあり、ctor/dtorへの1次依存関係が作成されましたSessionHandle。メンバーの前にソケットを破棄することはできませんでした。

デザインを検討しているときに、ステップ2と3を次のように配置できると思いました。

2.1。ハンドシェイク(リモートホストでSSHセッションを確立します)

2.2。認証

3.切断(リモートホストでのSSHセッションを終了します)

つまり、クラスをさらに単純化してSessionConnection、ステップ2.1と3でRAIIを実行する別のクラスを実装し、最終的に次のようにすることができます。

  • クラスSSHSessionにはSessionConnectionデータメンバーがあります。
  • クラスSessionConnectionはステップ2.2を実装します。
  • SessionConnectionソケットデータメンバーがあります。
  • SessionConnection手順1と4を実装するSessionHandleデータメンバーがあります。これは、ソケットの前に破棄する必要があります。
  • SessionConnectionRemoteSessionHandleステップ2.1および3を実装するデータメンバーがあります。これは、データメンバーの後に作成し、SessionHandleデータメンバーの前に破棄する必要があります。

これにより、RAIIのおかげで、私のctors/dtorsが大幅に簡素化されます。そして、私は概念的に健全だと思います。一方では、SSHセッションが通過する状態としてこれらを見ることができ、他方では、管理しているリソース(ローカル、リモート)としても見ることができます。

しかし、私は現在、厳密な建設/破壊の順序をSessionConnection持​​っており、それは改善であると信じていますが(そして、「これは悪である」と述べた私の研究では何も見つかりませんでしたが、「これは明確に文書化されるべきです」だけです)、私は興味があります他の意見では、私はこのデザインの可能な代替案についての情報/ポインターを喜んで受け入れます。

私がこれまで見てきたこと:

  • ScopeGuard、ScopeExit。これも同様のメカニズムで、デザインの改善に使用できるものは見つかりませんでした。
  • ステートマシン。それを使って設計を単純化する方法を見つけることができず、RAIIが行う1つの問題、つまり、何かが失敗した場合のクリーンアップを解決できませんでした。

御時間ありがとうございます。

4

1 に答える 1

1

このデザインには根本的な問題はないようです。

のメンバーの建設/破壊順序の制限を解除したい場合SessionConnectionは、次のようにすることができます。

  • クラスSSHSession
    • ステップ2.2を実装します
    • SSHConnectionメンバーがいます
  • クラスSSHConnection
    • ステップ2.1および3を実装します
    • LocalSessionHandleメンバーがいます
  • クラスLocalSessionHandle
    • ステップ1と4を実装します
    • Socketメンバーがいます

メンバーとその包含クラスの定義された構築/破棄順序により、手順が正しい順序で実行されることが保証されます。

于 2012-11-08T12:56:26.327 に答える