Sco*_*zie 43 c# design-patterns fluent-interface
我正在为C#中的流畅接口提供一些好的技巧.我自己只是在学习它,但很想听到别人在我正在阅读的文章之外的想法.特别是我在追求:
如果您可以发布一个提示或思想,或每个帖子的任何内容.我想看看他们如何投票.
先感谢您.
sbo*_*len 27
我作为流畅界面的消费者所经历的最大挑战是,它们中的大多数并不是真正流畅的界面 - 相反,它们实际上是我倾向于称为"易读界面"的实例.
流畅的界面意味着它的主要目标是使其易于使用,而清晰的界面意味着其主要目标是易于阅读.大多数流畅的界面往往只是非常难以编码,但相反之后其他人则非常容易阅读.
Assert().That().This(actual).Is().Equal().To(expected).
Except().If(x => x.GreaterThan(10));
Run Code Online (Sandbox Code Playgroud)
......以后比在代码中实际编写更容易阅读!
Men*_*elt 18
在你的第四点;
是的我认为复杂的流畅界面仍然可以流畅.
我认为流畅的界面有点妥协.(虽然是一个很好的!)关于使用自然语言进行编程的研究很多,而且通常自然语言不够精确,无法表达程序.
构造流畅的接口使得它们像编程语言一样编写,只允许用自然语言表达的一小部分,但它们读起来就像一种自然语言.
例如,如果你看一下犀牛嘲笑,那么与普通的图书馆相比,写作部分很复杂.由于流畅的界面,我花了更长时间才学习,但它使代码更容易阅读.因为程序通常只写一次并且读取的次数不止一次,所以这是一个很好的权衡.
所以要点一点我的观点.一个流畅的界面,编写复杂但易于阅读仍然可以流畅.
小智 11
当使用继承和流畅的接口时,你会碰到一块砖,因为使用多态方法会破坏你的调用链,你绝对不希望通过在不需要它们的情况下使用丑陋的强制转换和paranthesis来使你的接口不流畅.我写了一篇关于模式的文章,该模式为您提供了使用通用构建器和具有通用约束的通用扩展方法的解决方法:http: //liviutrifoi.wordpress.com/2009/02/16/fluent-interfaces-constraints-at-编译时/
在你的第2和第3个问题上;
我注意到了三种流畅的模式
第一个使用using语句(C#2.0)在某个上下文中运行代码,例如:
using(var transaction = new Transaction())
{
// ..
// ..
}
Run Code Online (Sandbox Code Playgroud)
这使用Transaction的构造函数和处理程序来设置事务,然后在此上下文中运行代码.
第二个几乎相同但是使用lambda,例如在Rhino Mocks中使用了很多.
(new Transaction()).Run( () => mycode(); );
Run Code Online (Sandbox Code Playgroud)
最着名的流畅接口是使用返回类型来链接方法调用.大多数方法返回此方法,因此您可以在同一对象上链接调用.但您也可以根据调用的方法返回不同的对象来更改上下文.如果你有一个只能在事务中运行的对象(抱歉不能想到一个不同的例子)你可以给它一个StartTransaction方法,它返回一个初始化的事务,你可以在伪代码中运行call run和stoptransaction:
class Runner
{
Transaction StartTransaction()
{
return new Transaction(this);
}
}
class Transaction
{
Transaction Run()
Transaction StopTransaction()
}
Run Code Online (Sandbox Code Playgroud)
通话的样子
var runner = new Runner();
runner
.StartTransaction()
.Run()
.StopTransaction();
Run Code Online (Sandbox Code Playgroud)
当然你需要添加各种错误处理等.
我也正在学习如何为工作中的小应用程序编写流畅的界面.我已经四处询问并进行了一些研究,发现编写流畅界面的好方法是使用"Builder模式",在这里阅读更多相关信息.
从本质上讲,这就是我开始的方式:
public class Coffee
{
private bool _cream;
private int _ounces;
public Coffee Make { get new Coffee(); }
public Coffee WithCream()
{
_cream = true;
return this;
}
public Coffee WithOuncesToServe(int ounces)
{
_ounces = ounces;
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个关于在流畅的界面中实现闭包的类似问题的交叉帖子.