3

このようなサーバーのインターフェイスがある場合...

interface IServer
{
    void Login();
    void Post();
    void Get();
}

...どこでPost、最初にGetやらない限り機能しませんLogin。インターフェイスの使用が実装に暗黙的に依存するため、カプセル化のセマンティック違反ですか?どのように修正しますか?

4

2 に答える 2

10

私の考え:

interface IServer 
{
    ISession Authenticate();
}

interface ISession 
{
    IServer Server{get;}
    void Post();
    void Get();
}

あなたが「泥」にアクセスできるなら、それを無視してください:

[泥]

これを明確にするために:私はあなたが製品を作成するのと同じようにソフトウェア設計について考えなければなりません...あなたは最初にコードを入力する代わりにボタンを「開く」を押すことができるあなたのすべての価値のあるもののための安全を本当に望んでいますか?これは、ユースケースの例えにすぎません...

実装者は、postに電話して、検証する前に取得できます...

もう1つの広く使用されているアプローチは、アクセストークンと、次のように使用することです。

interface IServer {//必要なトークン文字列を返しますAuthenticate(); void Post(文字列トークン); void Get(string token); }

でもそれも間違っていると思います...

ログイン前に表示/呼び出すことを許可されていないメソッドを表示したり、呼び出したりすることができます...実装者が「トークン」が正しいかどうかをチェックしない場合、ここにセキュリティリスクがあります...

ロジックをいくつかのレイヤー(ゲスト/非認証、認証/セッション、および(たとえば)管理)に分割すると、ロジックが明確に分離され、セマンティックの有用性が大幅に向上します。

私は個人的にこれまでにない方法でコードを記述します。優れたフレームワークビルダーがコードを記述します...何年経っても再利用可能で、非常に簡単で明確です。

[/泥]

于 2012-08-27T16:34:45.193 に答える
6

C#のインターフェイスは、特定のプロパティ(メソッドの存在)を保証する正式なコントラクトです。開発者が念頭に置いていた完全なセマンティックコントラクトをキャプチャしていません。その意味で、インターフェイスを使用しても、呼び出し元が必要なメソッドを呼び出すことができるとは限りません

同じことが、などのどの方法にも当てはまりFile.WriteAllText(path, text)ます。正式なインターフェースで許可されていても、パスとしてnullを渡すことはできません。文書化され、強制されたランタイムコントラクトにより、それを行うことができなくなります。

コードに戻る:呼び出し元は、インターフェースの実装に依存しません。彼はその契約に依存しています(C#には記載されていません)。

于 2012-08-27T16:35:17.317 に答える