Jam*_*son 5 .net c# design-patterns leaky-abstraction
我正在实现一个ITracker看起来像这样的接口:
public interface ITracker
{
void Track(ITrackerEvent trackerEvent);
}
Run Code Online (Sandbox Code Playgroud)
我最初创建了这个包装Mixpanel.NET的接口的实现.然后我创建了另一个包装Application Insights的程序.但是,Application Insights需要Flush()将数据发送到服务器.
我不想仅仅因为其中一个实现需要一个方法而污染ITracker接口Flush().它会感觉像是一个漏洞的抽象.
但是,我需要在某个时候调用此方法(可能在应用程序关闭时)并且不希望每次Track调用时都这样做.
当Tracker在会话结束时被垃圾收集时,是否可以调用方法?这甚至是一个好方法吗?
我觉得我在这里错过了一招!
我会ITracker使用事务相似的模式,因为可能存在您可能想要丢弃跟踪器事件,回滚或修改它们的情况:
public interface ITracker
{
void Track(ITrackerEvent trackerEvent);
void Commit();
}
Run Code Online (Sandbox Code Playgroud)
然后按照实现:
Flush在内部Commit寻求应用程序见解.List<ITrackerEvent>或者BlockingCollection<ITrackerEvent>如果涉及并发)Track,然后使用当前逻辑Mixpanel.NET在Commit方法实现中调用api Mixpanel.NET.建议: ITracker还应该实施,IDisposable因为跟踪器通常使用需要处理的资源.
在Leri的基础上,我会更多地考虑跟踪器可能需要做的事情.
我倾向于做这样的事情:
public interface ITracker {
void BeginTracking();
void Track(ITrackerEvent trackerEvent);
void EndTracking();
}
Run Code Online (Sandbox Code Playgroud)
然后所有跟踪器都会了解它们何时开始以及何时完成.这很重要,因为跟踪器可能持有的资源不应超过必要的时间.如果跟踪器不需要使用任何一个BeginTracking或者EndTracking,则实现是微不足道的.一个简单的实现不是漏洞的抽象.漏洞抽象是一种不适用于所有实现的抽象.
现在假设你完全没有在每个跟踪器中有两个额外的方法(为什么?).您可以改为使用带外的ITrackerEvents并涵盖Begin和End的语义含义.我不喜欢这个.它要求每个跟踪器都有特殊的代码来处理带外事件.
您还可以拥有一个单独的界面
public interface IDemarcatedTracker : ITracker {
void BeginTracking();
void EndTracking();
}
Run Code Online (Sandbox Code Playgroud)
这要求您在调用代码中包含特殊案例代码,以检查ITracker是否也是IDemarcatedTracker:
public void BeginTracking(ITracker tracker)
{
IDemarcatedTracker demarcatedTracker = tracker as IDemarcatedTracker;
if (demarcatedTracker != null)
demarcatedTracker.BeginTracking();
}
Run Code Online (Sandbox Code Playgroud)
而不是过度夸大事物,但我也想知道当跟踪器失败时会发生什么?只是盲目地抛出异常?而这里的抽象实际上是漏洞.跟踪器没有让您知道它无法跟踪的过程.
在您的情况下,您可能希望返回布尔值(有限信息),错误代码(更多信息)或错误类/结构.或者您可能希望获得抛出的标准异常.或者您可能希望Begin()方法包含在跟踪中发生错误时调用的委托.
| 归档时间: |
|
| 查看次数: |
405 次 |
| 最近记录: |