我今天刚学到了一些关于构图而不是继承的知识。我想知道我是否应该将这个概念应用到我最近写的东西上。
我们之前有两个几乎相同的类,除了一些小的差异。它们包含一些基本的数据库访问功能,但是在不同(但相关)的对象类型上运行。所以我们之前的课程结构如下:
class BallMillDBHandler{
public BallMillDBHandler(){ ... }
public void InsertTool(BallMill tool) { ... }
public BallMill QueryTool(string toolID) { ... }
public void UpdateTool(BallMill tool) { ... }
public void DeleteTool(string toolID) { ... }
}
class DiamondToolDBHandler{
public DiamondToolDBHandler(){ ... }
public void InsertTool(DiamondTool tool) { ... }
public DiamondTool QueryTool(string toolID) { ... }
public void UpdateTool(DiamondTool tool) { ... }
public void DeleteTool(string toolID) { ... }
}
我采用了大多数近似重复的方法并将它们重构为BaseToolDBHandler()
类,并从其他两个方法继承它,提供了一些抽象方法和属性来处理访问数据库参数本身的差异。
将BaseToolDBHandler
替换为包含在数据库访问器中的辅助类是否有意义,并为它们提供以前抽象的属性/方法的通用接口?或者我应该把它留作继承的情况?
答案 0 :(得分:3)
继承确实过度使用,但这似乎是一个合适的案例。在许多情况下,人们只看到重复的代码,并认为“我将使用继承通过基类删除重复的代码。”实际上,大多数重复代码都可以重构为另一个完全在几个地方使用的类。通常使用它的类不是“相关的”它们正在完成两个完全不同的事情,而恰好分享了做一些(或一些系列)小任务的需要。
当你真的可以说类类“是”基类的一个实例时,应该使用继承,而不仅仅是需要访问其他地方定义的一堆方法的类。在您的特定情况下,很明显两个类都是数据库处理程序。在他们的关键时刻,他们都服务于同一个目标,但他们是这个目标的两种不同的可能实现。我在这里可以看到的唯一问题(假设您没有显示任何方法的内容)是您可以将两个类组合成一个类,但我们需要了解更多关于细节的信息。知道这是可能还是更可取。
答案 1 :(得分:3)
这看起来像是一个通过基类/接口使泛型和继承都受益的场景。
class DBHandler<TTool> where TTool : ToolBase // or ITool
{
public DBHandler(){ ... }
public void InsertTool(TTool tool) { ... }
public TTool QueryTool(string toolID) { ... }
public void UpdateTool(TTool tool) { ... }
public void DeleteTool(string toolID) { ... }
}
如果需要,可以创建一个基类(可选的抽象)类,或者一个接口用作类型约束,以保证某些成员需要工具在方法体内。
<强>示例:强>
var handler = new DBHandler<BallMill>();
BallMill value = handler.QueryTool("xyz");
value.SomeProperty = "New Value";
handler.UpdateTool(value);
答案 2 :(得分:0)
我会说这绝对是继承的任务......但是让我们先做一件事。组合是一种设计模式,可以并且应该在类的多重继承不是给定语言的特征的情况下使用(例如C#)
组合意味着您的Composite类实例化类,通常它们将被继承。在这种情况下,您通过接口向实现提供合同。
为了给出一个关于如何将继承应用于代码的粗略示例,请考虑以下事项:(这不是使用合成)
public interface IHandler
{
void InsertTool(ITool tool);
void UpdateTool(ITool tool);
void DeleteTool(string toolID);
//void DeleteTool(ITool tool) - seems more consistent if possible!?
ITool QueryTool(string toolID);
}
public interface ITool
{
}
class BallMill : ITool
{
}
class DiamondTool : ITool
{
}
class BallMillDBHandler : IHandler
{
public BallMillDBHandler(){ ... }
public void InsertTool(ITool tool) { ... }
public BallMill QueryTool(string toolID) { ... }
public void UpdateTool(ITool tool) { ... }
public void DeleteTool(string toolID) { ... }
}
class DiamondToolDBHandler : IHandler
{
public DiamondToolDBHandler(){ ... }
public void InsertTool(ITool tool) { ... }
public DiamondTool QueryTool(string toolID) { ... }
public void UpdateTool(ITool tool) { ... }
public void DeleteTool(string toolID) { ... }
}
答案 3 :(得分:0)
使用泛型,而不是继承。您希望对不同类型的对象执行相同的操作,这正是泛型最擅长的。