1

私は実装ではなくインターフェースにコーディングする習慣を身につけようとしていますが、ほとんどの場合、私が苦労している理由がいくつかあることがわかります。

この本当に単純な例を見てください:

public interface IAuditLog
{
    void AddLog(string log);
}

public class AuditLog : IAuditLog
{
    public void AddLog(string log)
    {
        //implementation
    }
}

監査ログクラスを呼び出すには:

public partial class AuditLogPage : System.Web.UI.Page
{
    protected void btnAddLog_Click(object sender, EventArgs e)
    {
        IAuditLog objAuditLog = new AuditLog();
        objAuditLog.AddLog("test log");
    }
}

インスタンス化するときにまだAuditLogを使用する必要があるので、ポイントは何ですか?AddLogメソッドの署名が変更された場合でも、それを使用するすべてのページを調べてコードを修正する必要があります。私はポイントを逃していますか?

ウィルキー、事前に助けてくれてありがとう。

4

4 に答える 4

5

この例では、で切り替えた場合FileAuditLogger()DatabaseAuditLogger()またはEventLogAuditLogger()コードを書き直さなくても実装を切り替えることができます。

通常、IoCコンテナ(Autofac、StructureMap、Unityなど)を使用して、オブジェクトのインスタンス化を自動的に接続します。だから、電話する代わりにnew AuditLog()あなたは電話するでしょうIoC.Container.Resolve<IAuditLog>()

さらに詳しい情報が必要な場合はお知らせください。

于 2012-06-29T11:06:42.573 に答える
4

2つのAuditLogクラスがあると想像してみてください

class AuditLogToDatabase : IAuditLog // writes to database

そしてもう一つは

class AuditLogToFile : IAuditLog // writes to file

お気に入り

protected void btnAddLog_Click(object sender, EventArgs e)
{
    IAuditLog objAuditLog = AuditLogFactory.GetAuditLog();
    objAuditLog.AddLog("test log");
}

これで、実際の実装を変更せずに、実行時にいくつかの構成に基づいて任意のクラスを注入できます。

于 2012-06-29T11:06:19.437 に答える
3

これは、必ずしも実際にC#を使用する必要があることを意味するわけではありませんinterface。OOP用語でのインターフェースは、APIの公に見えるファサードです。これは契約であり、外部から見える操作の結果を指定する必要があります。いつでも実装を交換できるように、表面下でどの程度正確に機能するかは関係ありません。

もちろん、その点で、aninterfaceはさまざまな実装を使用できるメソッドですが、抽象基本クラスや、他のクラスから派生できる非抽象クラスも同様です。

しかし、あなたの質問の正確なポイントにもっと:もちろん、クラスをインスタンス化するとき、そのタイプは知られている必要がありますが、必ずしもそこにクラスインスタンスを作成する必要はありません。外部から設定することもIAuditLog、ファクトリクラスなどを介して取得することもできます。コード内のその正確なポイントで、取得する正確なタイプはわかりません(と互換性がある場合を除くIAuditLog)。

于 2012-06-29T11:06:08.513 に答える
1

AuditLogこれは、メソッドのようにメソッドからインスタンスを作成し、インターフェイスからFactory複数のAuditLogXXXクラスを派生させる場合に実際に役立ちIAuditLogます。

したがって、このコードを使用する代わりに:

IAuditLog objAuditLog = new AuditLog();

インターフェイスにプログラムするときは、実際にこのコードを使用します。

IAuditLog objAuditLog = LogFactory.GetAuditLog(); //This call is programmed to an interface

ここで、は次のようにクラスでGetAuditLog()定義されたインターフェイス型のメソッドです。LogFactory

class LogFactory
{    
    public IAuditLog GetAuditLog() // This method is programmed to an interface
    {
        //Some logic to make a choice to return appropriate AuditLogXXX instance from the factory
    }    
}
于 2012-06-29T11:16:16.643 に答える