c# - 从基抽象类和 IDisposable 的正确位置继承接口
问题描述
我有以下结构。
问题:
- 是否需要 IStrategy 接口?因为我见过人们做和我一样的事情——有一个 Start 方法,它
abstract
在基类中被定义为 an ,并且他们用一个定义它的接口来公开它。但是,其他人认为Start
只在基类中指定方法就足够了,根本不需要接口,因为代码变得更加复杂。你怎么看? - 我正在定义
IBinanceClient
和IBinanceSocketClient
在基类中,它们都必须在某个时候被处理。在下面的代码中,我在派生类中实现了 IDisposable,但是,我认为将它移到基类中是一个更好的决定,因为 BinanceClient 是在那里定义的。你怎么看?
public interface IStrategy
{
public void Start(Bot bot, CancellationToken token);
}
public abstract class StrategyBase : IStrategy
{
public IBinanceClient Client { get; }
public IBinanceSocketClient SocketClient { get; }
protected StrategyBase(string apiKey, string secretKey)
{
Client = new BinanceClient(new BinanceClientOptions()
{
ApiCredentials = new ApiCredentials(apiKey, secretKey),
AutoTimestamp = true,
AutoTimestampRecalculationInterval = TimeSpan.FromMinutes(30)
});
SocketClient = new BinanceSocketClient(new BinanceSocketClientOptions()
{
ApiCredentials = new ApiCredentials(apiKey, secretKey),
AutoReconnect = true,
ReconnectInterval = TimeSpan.FromMinutes(1)
});
}
public List<BinanceStreamTick> Tickers { get; set; }
// Methods that all strategies use
public void GetTickers()
{
... implementation
}
public abstract void Start(Bot bot, CancellationToken token); // ???
}
public class CompositeStrategy : StrategyBase, IDisposable
{
public CompositeStrategy(string apiKey, string secretKey) : base(apiKey, secretKey)
{
}
public override void Start(Bot bot, CancellationToken token)
{
... implementation
}
private bool _disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
if (Client != null)
Client.Dispose();
if (SocketClient != null)
{
SocketClient.UnsubscribeAll();
SocketClient.Dispose();
}
}
_disposed = true;
}
}
编辑:
其他方式,基于@Wiktor Zychla 的评论。
public interface IStrategy
{
public void Start(Bot bot, CancellationToken token);
}
public abstract class StrategyBase : IStrategy, IDisposable
{
public IBinanceClient Client { get; }
public IBinanceSocketClient SocketClient { get; }
protected StrategyBase(string apiKey, string secretKey)
{
Client = new BinanceClient(new BinanceClientOptions()
{
ApiCredentials = new ApiCredentials(apiKey, secretKey),
AutoTimestamp = true,
AutoTimestampRecalculationInterval = TimeSpan.FromMinutes(30)
});
SocketClient = new BinanceSocketClient(new BinanceSocketClientOptions()
{
ApiCredentials = new ApiCredentials(apiKey, secretKey),
AutoReconnect = true,
ReconnectInterval = TimeSpan.FromMinutes(1)
});
}
public List<BinanceStreamTick> Tickers { get; set; }
public void GetTickers()
{
... implementation
}
public abstract void Start(Bot bot, CancellationToken token);
private bool _disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
if (Client != null)
Client.Dispose();
if (SocketClient != null)
{
SocketClient.UnsubscribeAll();
SocketClient.Dispose();
}
}
_disposed = true;
}
}
public class CompositeStrategy : StrategyBase
{
public CompositeStrategy(string apiKey, string secretKey) : base(apiKey, secretKey)
{
}
public override void Start(Bot bot, CancellationToken token)
{
... implementation
}
}
解决方案
您是否需要该IStrategy
接口取决于您使用它的上下文,因此不清楚。但是,IStrategy
使用Start ()
方法和StrategyBase
使用abstract
Start()
方法似乎是重复的,这表明您只需要基类。
关于将 放在哪里Dispose()
,一般规则是对象应该放置在创建它们的同一个类中。(如果可能,使用相同的方法,但这仅适用于非常短暂的对象,而不是这里的情况。)
您没有显示在哪里创建SocketClient
和Client
创建,但它们在 中声明StrategyBase
,这表明它们应该被放置在哪里。
推荐阅读
- python - 模拟移动浏览器
- python-3.x - 如何爬取一些数据+链接的列表并获取这些链接数据
- qt - QLineEdit 应该接受范围为 [0 - FFFFF] 的十六进制值
- laravel - 使用查询生成器获取类别和 Sub_subcategories 列表
- rest - 根据codeigniter中的id将多行数据分组
- spring-boot - Spring Boot 完全反应式 Kafka 处理
- python - 如何获取图像中物体的直径?
- css - 推荐滑块 - 推荐文本不换行
- reactjs - 如何将输入值从子表单组件传递到其父组件的状态以使用反应挂钩提交?
- r - 修复动画地图