所以我们在我们的项目中有这个巨大的(11000行巨大的?)mainmodule.cpp源文件,每次我都要触摸它时我都会感到畏缩.
由于这个文件是如此中心和大,它不断累积越来越多的代码,我想不出一个让它真正开始缩小的好方法.
该文件在我们产品的几个(> 10)维护版本中使用并主动更改,因此很难重构它.如果我"简单地"把它分开,比如说开始,分成3个文件,那么合并来自维护版本的变化将成为一场噩梦.而且,如果你拆分了一个历史悠久且历史悠久的文件,跟踪和检查历史中的旧变化SCC突然变得更加困难.
该文件基本上包含我们程序的"主类"(主要内部工作调度和协调),因此每次添加一个功能时,它也会影响该文件,并且每次增长时都会影响该文件.:-(
在这个情况下,你会怎么做?有关如何将新功能移动到单独的源文件而不会弄乱SCC工作流程的任何想法?
(关于工具的注意事项:我们使用C++ Visual Studio;我们使用AccuRevas SCC但我认为这里的类型SCC并不重要;我们Araxis Merge用来做实际比较和合并文件)
我们所有使用关系数据库的人都已经学习(或正在学习)SQL是不同的.引出期望的结果,并且有效地进行,涉及一个繁琐的过程,其部分特征是学习不熟悉的范例,并发现我们最熟悉的一些编程模式在这里不起作用.您见过(或自己承诺)的常见反模式有哪些?
反模式:必须至少有两个关键元素来正式区分实际的反模式与简单的坏习惯,不良做法或坏主意:
投票给你在"野外"看过一次太多的TDD反模式.
詹姆斯卡尔的博客文章和 关于testdrivendevelopment yahoogroup的相关讨论
如果你发现了一个'未命名的',那么也可以发布它们.每个反模式一个帖子请投票计算一些东西.
我的既得利益是找到前n个子集,以便我可以在不久的将来在午餐盒中讨论他们.
我正在研究模式和反模式.我对模式有一个清晰的认识,但我没有反模式.网络和维基百科的定义让我很困惑.
任何人都可以用简单的词语向我解释反模式是什么?什么目的?他们在做什么?这是坏事还是好事?
我正在阅读维基百科上的Singleton文章,我遇到了这个例子:
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
Run Code Online (Sandbox Code Playgroud)
虽然我非常喜欢这个Singleton的行为方式,但我看不出如何调整它以将参数合并到构造函数中.在Java中执行此操作的首选方法是什么?我必须这样做吗?
public class Singleton
{
private static Singleton singleton = null;
private final int x;
private Singleton(int x) {
this.x …Run Code Online (Sandbox Code Playgroud) 最近我读过Mark Seemann关于Service Locator反模式的文章.
作者指出ServiceLocator为反模式的两个主要原因:
API使用问题(我完全可以使用)
当类使用服务定位器时,很难看到它的依赖关系,因为在大多数情况下,类只有一个PARAMETERLESS构造函数.与ServiceLocator相比,DI方法通过构造函数的参数显式地暴露依赖关系,因此在IntelliSense中很容易看到依赖关系.
维护问题(让我感到困惑)
请考虑以下示例
我们有一个使用服务定位器方法的类'MyType':
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们要为类'MyType'添加另一个依赖项
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我的误解开始的地方.作者说:
要判断你是否引入了一个重大改变,要变得更加困难.您需要了解使用Service Locator的整个应用程序,并且编译器不会帮助您.
但是等一下,如果我们使用DI方法,我们将在构造函数中引入与另一个参数的依赖关系(在构造函数注入的情况下).问题仍然存在.如果我们忘记设置ServiceLocator,那么我们可能忘记在IoC容器中添加新的映射,并且DI方法将具有相同的运行时问题.
此外,作者还提到了单元测试的难点.但是,我们不会有DI方法的问题吗?我们不需要更新所有实例化该类的测试吗?我们将更新它们以传递一个新的模拟依赖项,以使我们的测试可编译.我没有看到更新和时间花费带来任何好处.
我不是想捍卫Service Locator方法.但这种误解让我觉得我失去了一些非常重要的东西.有人可以消除我的怀疑吗?
更新(摘要):
我的问题"服务定位器是反模式"的答案实际上取决于具体情况.我绝对不会建议你从工具列表中删除它.当您开始处理遗留代码时,它可能会变得非常方便.如果你很幸运能够处于项目的最初阶段,那么DI方法可能是更好的选择,因为它比Service Locator有一些优势.
以下是主要的不同之处,这些差异使我不相信我的新项目使用Service Locator:
有关详细信息,请阅读下面给出的优秀答案.
design-patterns dependency-injection anti-patterns service-locator
我最近听到人们说数据传输对象(DTO)是一种反模式.
为什么?有哪些替代方案?
Python中常见的反模式是+在循环中连接一系列字符串.这很糟糕,因为Python解释器必须为每次迭代创建一个新的字符串对象,并最终获得二次时间.(在某些情况下,CPython的最新版本显然可以优化它,但是其他实现不能,因此不鼓励程序员依赖它.)''.join是正确的方法.
不过,我听人说(这里包括对堆栈溢出),你应该永远不会使用+字符串连接,而是始终使用''.join或格式字符串.我不明白为什么如果你只是连接两个字符串就是这种情况.如果我的理解是正确的,它不应该花费二次时间,我认为a + b比任何一个''.join((a, b))或更清晰,更可读'%s%s' % (a, b).
+用于连接两个字符串是一种好习惯吗?还是有一个我不知道的问题?
许多人似乎都同意,Singleton模式有许多缺点,有些甚至建议完全避免这种模式.这里有一个很好的讨论.请将有关Singleton模式的任何评论指向该问题.
我的问题:是否有其他设计模式,应该避免或小心使用?
您在公司的生产环境中见过的最邪恶或最危险的代码片段是什么?我从来没有遇到过我认为故意恶意和邪恶的生产代码,所以我很好奇看到其他人发现了什么.
我见过的最危险的代码是存储过程,两个链接服务器远离我们的核心生产数据库服务器.存储过程接受任何NVARCHAR(8000)参数,并通过双跳sp_executeSQL命令在目标生产服务器上执行该参数.也就是说,sp_executeSQL命令执行另一个sp_executeSQL命令以跳转两个链接的服务器.哦,链接的服务器帐户在目标生产服务器上具有sysadmin权限.
anti-patterns ×10
java ×2
c++ ×1
dto ×1
ejb ×1
maintenance ×1
ooad ×1
oop ×1
python ×1
singleton ×1
sql ×1
tdd ×1
terminology ×1
unit-testing ×1