- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
背景故事:
因此,在过去的几个晚上里,我一直在研究架构问题,一直在尝试重构。没什么重要的,但它一直困扰着我。这实际上是 DRY 中的一个练习,并试图将其发挥到极致,因为 DAL 架构完全 DRY。这是一个完全哲学/理论的练习。
该代码部分基于 @JohnMacIntyre 之一我最近说服他在 http://whileicompile.wordpress.com/2010/08/24/my-clean-code-experience-no-1/ 上写博客的重构。 .我稍微修改了代码,就像我倾向于的那样,以便将代码更进一步——通常,只是为了看看我能从一个概念中得到什么额外的里程……无论如何,我的理由在很大程度上是无关紧要的。
我的部分数据访问层基于以下架构:
abstract public class AppCommandBase : IDisposable { }
这包含基本内容,例如命令对象的创建和 AppCommand 处理后的清理。我所有的命令基础对象都源自于此。
abstract public class ReadCommandBase<T, ResultT> : AppCommandBase
这包含影响所有读取命令的基本内容 - 特别是在这种情况下,从表和 View 中读取数据。无需编辑、无需更新、无需保存。
abstract public class ReadItemCommandBase<T, FilterT> : ReadCommandBase<T, T> { }
这包含一些更基本的通用内容——比如从数据库中的表中读取单个项目所需的方法定义,其中表名、关键字段名和字段列表名被定义为必需的抽象属性(由派生类定义。
public class MyTableReadItemCommand : ReadItemCommandBase<MyTableClass, Int?> { }
这包含定义我的表名的特定属性、表或 View 中的字段列表、关键字段的名称、将数据从 IDataReader 行解析到我的业务对象的方法以及启动的方法整个过程。
现在,我的 ReadList 也有这个结构......
abstract public ReadListCommandBase<T> : ReadCommandBase<T, IEnumerable<T>> { }
public class MyTableReadListCommand : ReadListCommandBase<MyTableClass> { }
区别在于 List 类包含与列表生成相关的属性(即 PageStart、PageSize、Sort 并返回一个 IEnumerable)与返回单个 DataObject(只需要一个过滤器来标识唯一记录)。
问题:
我讨厌我的 MyTableReadListCommand 类中有一堆属性,这些属性在我的 MyTableReadItemCommand 类中是相同的。我考虑过将它们移动到辅助类,但虽然这可能会将成员内容集中在一个地方,但我仍然会在每个类中拥有相同的成员,而是指向我仍然不喜欢的辅助类。
我的第一个想法是双重继承会很好地解决这个问题,尽管我同意双重继承通常是一种代码味道——但它会非常优雅地解决这个问题。那么,鉴于 .NET 不支持双重继承,我该何去何从?
也许不同的重构会更合适......但我无法思考如何回避这个问题。
如果有人需要完整的代码库来了解我在喋喋不休的内容,我的 DropBox 上有一个原型(prototype)解决方案 http://dl.dropbox.com/u/3029830/Prototypes/Prototype%20-%20DAL%20Refactor.zip .有问题的代码在 DataAccessLayer 项目中。
附言这不是正在进行的事件项目的一部分,它更像是我自己娱乐的重构难题。
在此先感谢大家,我很感激。
最佳答案
将结果处理与数据检索分开。您的继承层次结构在 ReadCommandBase 中已经足够深了。
定义一个接口(interface)IDatabaseResultParser。实现 ItemDatabaseResultParser 和 ListDatabaseResultParser,它们都带有 ReadCommandBase 类型的构造函数参数(也可能将其转换为接口(interface))。
当您调用 IDatabaseResultParser.Value() 时,它会执行命令、解析结果并返回 T 类型的结果。
您的命令专注于从数据库中检索数据并将它们作为某种描述的元组返回(实际元组或数组数组等),您的解析器专注于将元组转换为您需要的任何类型的对象。请参阅 NHibernates IResultTransformer 以了解其工作原理(它的名称可能也比 IDatabaseResultParser 更好)。
比继承更喜欢组合。
看过示例后,我会走得更远...
现在你有了 IDatabaseQuery/IDatabaseCommand/IResultTransformer 并且几乎没有继承 =)
关于c# - .NET 重构,DRY。双重继承、数据访问和关注点分离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3580872/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!