使用模板模式(继承)为类注入依赖项有什么优缺点。
假设我正在创建一堆业务服务类,例如,ISecurityService实现为SecurityService。
而且,如果我知道所有业务服务(包括ISecurityService)将/应该依赖于IBusinessContext来获取服务上下文信息,我可以使用模板模式(使用继承)来实现/强制执行吗?
方法#1:
public interface IBusinessContext
{
public int Property { get; }
}
public interface IService
{
public IBusinessContext Context { get; }
}
public abstract class ServiceBase : IService
{
public IBusinessContext Context { get; }
public ServiceBase(IBusinessContext context) { _context = context; }
}
public interface IBusinessServiceN : IService
{
public void DoSomething();
}
public class BusinessServiceN : ServiceBase, IBusinessServiceN
{
public SecurityService(IBusinessCnotext context)
: base(context) { }
public void DoSomething() { }
}
方法#2:
public interface IBusinessContext
{
public int Property { get; }
}
public interface IBusinessServiceN
{
public void DoSomething();
}
public class BusinessServiceN : IBusinessServiceN
{
private IBusinessContext _context;
public SecurityService(IBusinessCnotext context) { _context = context; }
public void DoSomething() { }
}
哪种方法更受欢迎?为什么?
答案 0 :(得分:0)
数字2,因为为什么服务将IBusinessContext
公开为公共财产是有意义的?它没有。这是它的一个依赖项,它不需要通过接口或甚至具体类来公开。
消费IService
的合同不是/不应包括创建具体类来履行IService
的合同。如果我可以在没有IService
实例的情况下实现IBusinessContext
这是一件好事,特别是在编写单元测试和模拟IService
时。或者,如果我的IService
实现需要ICompleteContext
而不是包含IBusinessContext
,那么应该不会像在#1中那样人为地使用某些界面进行约束。
答案 1 :(得分:0)
这一切都取决于您的要求。除非您的抽象类中有可重用的代码,否则方法#1不会增加任何好处。
当您拥有一个共同的工作流程并且您确定此工作流程不会更改时,模板方法模式真的很闪亮;虽然子实现可能会更改某些步骤,但它们可能不会更改工作流程结构。
假设您的DoSomething方法中有一个“严格”的工作流程,并且有一些常用的继承类的步骤:
public virtual void DoSomething() {
DoSomethingFirst(); // -> common to all classes
DoSomethingAfter(); //-> each class has unique implementation
}
您的基类可以采用以下形式:
public abstract class ServiceBase : IService
{
public IBusinessContext Context { get; }
public ServiceBase(IBusinessContext context) { Context = context; }
public void DoSomethingFirst() {
// common implementation here
}
public abstract void DoSomethingAfter();
public virtual void DoSomething() {
DoSomethingFirst();
DoSomethingAfter();
}
}
你的具体课程:
public class BusinessServiceN : ServiceBase, IBusinessServiceN
{
public BusinessServiceN(IBusinessContext context)
: base(context) { }
public override void DoSomethingAfter()
{
//Your custom implementation here
}
}
如您所见,您的DoSomething()
方法和共享/可重复使用的DoSomethingFirst()
方法具有强制结构。