对我来说,翻译模式听起来非常像一个被称为格林普森第十条规则的反模式:
任何足够复杂的C或Fortran程序都包含一个特殊的,非正式指定的,错误缠身的,一半Common Lisp的缓慢实现.
也就是说,如果你需要使用Interpreter,你可能会创建一些缓慢,临时和指定不当的东西.正确的解决方案是从一开始就使用正确的语言.
或者,或者,在您的应用程序中嵌入一个众所周知且语言清晰的语言,例如Guile(GNU可嵌入方案).或者使用Haskell作为嵌入式域特定语言.
但我在实践中没有看到这一点 - 您在构建自己的嵌入式语言方面有哪些经验?这是个好主意吗?它比嵌入已有的语言更好吗?
(我不是特别喜欢lisp的粉丝.这很好,但是C和Haskell以及python和很多其他语言都是如此.)
lisp design-patterns anti-patterns greenspunning interpreter-pattern
我有一个相对复杂的泛型类型(比如说Map<Long,Map<Integer,String>>),我在课堂内部使用它.(没有外部可见性;它只是一个实现细节.)我想在typedef中隐藏它,但Java没有这样的功能.
昨天我重新发现了以下成语,并且对于被认为是反模式感到失望.
class MyClass
{
/* "Pseudo typedef" */
private static class FooBarMap extends HashMap<Long,Map<Integer,String>> { };
FooBarMap[] maps;
public FooBarMap getMapForType(int type)
{
// Actual code might be more complicated than this
return maps[type];
}
public String getDescription(int type, long fooId, int barId)
{
FooBarMap map = getMapForType(type);
return map.get(fooId).get(barId);
}
/* rest of code */
}
Run Code Online (Sandbox Code Playgroud)
当类型被隐藏并且不构成库API的一部分时(在我看来,Goetz对使用它的主要反对意见),是否有任何理由可以解决这个问题?
可能重复:
在设计模式上:何时使用Singleton?
这个问题不是关于单身人士是否"被视为有害".我只是想知道,从你的经验,都有些什么具体情况,其中单身似乎运作良好.
编辑: 请,如果你想讨论单身的恰当性和/或邪恶一般,有已位于exising问题:137975,11831
哎呀!我刚刚发现我的问题已在这里被问到:关于设计模式:何时使用Singleton?
我有两个特殊情况,我不同意同事,是否应该使用常数.
我们使用一个大致类似Symfony 1.x的自制框架.
初始代码是路由PHP配置文件中的路由,如下所示:
$router->map('/some_url', array('module' => 'some_module', 'action' => 'some_action'));
$router->map('/some_other_url', array('module' => 'some_module', 'action' => 'some_action'));
// etc.
Run Code Online (Sandbox Code Playgroud)
同事将其改为:
$router->map('/some_url', array(MODULE => 'some_module', ACTION => 'some_action'));
$router->map('/some_other_url', array(MODULE => 'some_module', ACTION => 'some_action'));
// + in constants.php file:
define('MODULE', 'module');
define('ACTION', 'action');
Run Code Online (Sandbox Code Playgroud)
IMO这是不断过度使用:如果"模块"或"动作"的概念被重命名,则必须在整个代码中重命名,或者写成字符串或常量.另外,上面定义的常量名称没有非常具体的含义,有利于命名冲突/混淆.
初始代码示例:
if (isset($_SESSION['unid']) && isset($_SESSION['login'])) { ... }
Run Code Online (Sandbox Code Playgroud)
由同事修改:
if (isset($_SESSION[UNID]) && isset($_SESSION[LOGIN])) { ... }
// + in a constants.php file:
define('UNID', 'unid');
define('LOGIN', 'login');
Run Code Online (Sandbox Code Playgroud)
在我们的应用程序中,那些会话变量名称unid并且login显然不太可能发生变化.尽管如此,如果声明常量在这里真的是一个很好的做法,我建议至少更准确的名称,例如FIELDNAME_UNID和FIELDNAME_LOGIN... …
我有一个模块适用于表示为列表的路径.大多数函数都执行典型的递归列表处理,但现在我需要一个有时会改变路径的函数.所以,我写了这个replace函数:
module List =
let replace f sub xs =
let rec finish acc = function
| [] -> acc
| x::xs -> finish (x::acc) xs
let rec search acc = function
| [] -> None
| x::xs ->
if f x then Some(finish ((sub x)::xs) acc)
else search (x::acc) xs
search [] xs
Run Code Online (Sandbox Code Playgroud)
其工作方式如下:
let xs = List.init 10 id
let res = List.replace ((=) 5) (fun _ -> -1) xs
//Some [0; 1; 2; 3; 4; …Run Code Online (Sandbox Code Playgroud) 所以我在另一篇文章中看到了以下"糟糕"的片段,但我见过的唯一选择是修补Python.
for i in xrange(len(something)):
workwith = something[i]
# do things with workwith...
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能避免这种"反模式"?
根据这篇文章,要求rubygems是一个反模式.
require 'rubygems'
Run Code Online (Sandbox Code Playgroud)
这个论点似乎归结为:
当我使用你的库,部署你的应用程序,或运行你的测试我可能不想使用rubygems.当您在代码中需要"rubygems"时,您将无法做出决定.我不能不要求rubygems,但你不能首先要求它.
但是,当您与其他人一起创建和共享代码库时,您所要求的任何Ruby库都无法进行相同的论证吗?
考虑一个匹配客户端和服务的模型.客户可能在不同时间成为服务的提供者和消费者.客户可以是个人或团体(公司),后者具有多个联系人.联系人可能有多个地址,电话,电子邮件.这些关系中的一些将是一对一的(例如,对提供商的服务),但大多数将是一对多或多对多(公司的多个联系人将具有相同的地址).
在该模型中,通常存在若干关联表,例如,client_contact,contract_addr,contact_phone,contact_email,service_provider,service_consumer等.
假设您为给定服务的使用者发出简单查询联系信息.除了包含数据的六个实体表之外,连接还将引用五个关联表.关于这种查询,当然没有什么特别有趣的 - 我们每天都这样做.
但是我想到了:为什么不能拥有一个包含所有关联的"主"关联表?除了两个PK之外,还需要这个主表具有"关联类型",并且所有PK都需要具有相同的类型(整数,GUID等).
一方面,查询会变得更复杂,因为每个连接都需要指定类型和PK.另一方面,所有联接都将访问同一个表,并且具有适当的indexng和缓存性能可以显着提高.
我假设可能有一种模式(或反模式)描述这种方法,但没有找到任何在线.有人试过吗?如果是这样,它会扩展吗?
您可以提供的任何参考资料将不胜感激.
database-design design-patterns anti-patterns associative-table
所以这样的事情
public void MyMethod(object parameter)
//....
BuildSomething(parameter);
BuildLayers(parameter);
BuildOtherStuff(parameter);
}
public void BuildSomething(object parameter)
{
//...
parameter.SomeProperty = "sadsd";
//...
}
Run Code Online (Sandbox Code Playgroud)
如果这是反模式,它叫什么?问题(可能)是您隐式更改参数并使用更改的值.
我只是想知道这种反模式知道的是什么
谢谢
编辑:修复了几个语法和一致性问题,使代码更加明显,接近我实际做的事情.
我有一些看起来像这样的代码:
SomeClass someClass;
var finalResult =
DoSomething(() =>
{
var result = SomeThingHappensHere();
someClass = result.Data;
return result;
})
.DoSomething(() => return SomeOtherThingHappensHere(someClass))
.DoSomething(() => return AndYetAnotherThing())
.DoSomething(() => return AndOneMoreThing(someClass))
.Result;
HandleTheFinalResultHere(finalResult);
Run Code Online (Sandbox Code Playgroud)
其中DoSomething方法是扩展方法,并且它期望传递给它的Func.因此,每个DoSomething => lambda中的每个方法调用都返回一个Result类型.
这类似于一个可能的monad.除了检查空值,我检查Result类的状态,并调用传递给DoSomething的Func或返回前一个Result而不调用Func
我面临的问题是希望在我的代码中使用这种组合,但我还需要能够将一个组合调用结果中的数据传递给另一个调用结果,正如您可以看到的那样someClass.
我的问题不是这在技术上是否正确......我知道这是有效的,因为我现在正在这样做.我的问题是这是否是滥用闭包,命令查询分离或任何其他原则......然后询问有什么更好的模式来处理这种情况,因为我很确定我是现在,这种类型的代码陷入了"闪亮的新锤子"模式.
c# closures anti-patterns principles command-query-separation