标签: fluent-interface

在一个类中混合流畅和不流畅的界面

我认为流畅的界面非常便于许多任务.但是当我最终在一个类中混合流畅的方法和修改方法时,我感到不安.

只是一个例子(这有点做作,请耐心等待):

假设一个字符串实用程序类,修剪似乎适合链接:

Str & Str::Trim() { return TrimLeft().TrimRight(); }
Run Code Online (Sandbox Code Playgroud)

其他方法自然会返回一个新对象:

Str Str::GetFirstToken() const
{ 
   // result = first token;
   return result;
}
Run Code Online (Sandbox Code Playgroud)

还有第三种类型 - 它本身 - 会逻辑地改变对象返回一个新对象:

Str Str::SplitFirstToken() 
{ 
   result = GetFirstToken();
   // this = remainder
   return result;
}
Run Code Online (Sandbox Code Playgroud)

当我单独使用每个方法最明显的签名时,我最终会得到这三种类型,而且我担心这类消费不是很直观,特别是因为返回类型是mroe或更少相同.


我已经决定Str不做不可变 - 因为SplitToken提供核心功能的方法.我的主要问题是混合流畅的方法你会做什么?

  • 不要在该界面中使用流畅的方法

  • 将它们移动到子接口(见下文)

  • "如果一个人流利,所有修改方法都应该流利"?

  • 为流畅的方法使用一个seocific前缀?

  • 别担心?

  • ???

子接口的想法:

void CStr::Trim() { TrimLeft(); TrimRight(); }
CStrFluent & Str::Fluent() { return CStrFluent(*this); }
....
str.Fluent().TrimLeft().TrimRight();
Run Code Online (Sandbox Code Playgroud)

我对此犹豫不决,我真的不喜欢额外的"流畅" - 尤其是它是C++中的方法调用

你怎么看?

[编辑]我在这里使用"流利"的基本含义是在单个实例上链接方法调用,而不是在代码中创建英语句子的高级意义.

class-design fluent-interface

5
推荐指数
1
解决办法
344
查看次数

在流畅的界面中实现条件

我一直在尝试为我的系统中的一组规则实现流畅的界面.我想要完成的是这个

TicketRules
.RequireValidation()
.When(quartType => quartType == QuartType.Before).TotalMilageIs(64)
.When(quartType => quartType == QuartType.After).TotalMilageIs(128);
Run Code Online (Sandbox Code Playgroud)

但是,我无法实现当我有条件的时候.目前,我需要在此片段中调用When()两次:

rules.When(param => param.Remarque == "Test").TotalMilageIs(100);
rules.When(param => param.Remarque == "Other").TotalMilageIs(50);

var params1 = new AddTicketParameters() { Remarque = "Test" };
var params2 = new AddTicketParameters() { Remarque = "Other" };

rules.ExecuteWith(params1);

Assert.That(ticket.TotalMilage, Is.EqualTo(100));

rules.ExecuteWith(params2);

Assert.That(ticket.TotalMilage, Is.EqualTo(50));
Run Code Online (Sandbox Code Playgroud)

我的TicketRules类看起来像这样:

[EditorBrowsable(EditorBrowsableState.Never)]
public class TicketRules : ITicketRule, IHideObjectMembers
{
    private Ticket theTicket;

    public Ticket Ticket
    {
        set
        {
            theTicket = value;
        }
    }

    private List<ITicketRule> allRules = new List<ITicketRule>();

    public …
Run Code Online (Sandbox Code Playgroud)

c# oop fluent-interface .net-2.0

5
推荐指数
1
解决办法
2013
查看次数

有关C#中流畅界面的问题

我有以下课程:

public class Fluently
{
  public Fluently Is(string lhs)
  {
    return this;
  }
  public Fluently Does(string lhs)
  {
    return this;
  }
  public Fluently EqualTo(string rhs)
  {
    return this;
  }
  public Fluently LessThan(string rhs)
  {
    return this;
  }
  public Fluently GreaterThan(string rhs)
  {
    return this;
  }
}
Run Code Online (Sandbox Code Playgroud)

在英语语法中,你不能拥有"等同于某种东西"或"做出比某事更重要的东西"所以我不希望Is.EqualTo和Does.GreaterThan成为可能.有没有办法限制它?

var f = new Fluently();
f.Is("a").GreaterThan("b");
f.Is("a").EqualTo("b");        //grammatically incorrect in English
f.Does("a").GreaterThan("b");
f.Does("a").EqualTo("b");      //grammatically incorrect in English
Run Code Online (Sandbox Code Playgroud)

谢谢!

c# fluent-interface

5
推荐指数
1
解决办法
323
查看次数

在PHP中检测方法链的结束?

我找不到上面问题的一个简单例子:我如何检测方法链的结束?

我只是看了Zend_Db_Select,但是我觉得这个问题对于这个简单的问题来说太复杂了.

是否有可能在PHP中捕获方法链的"结束"?

谢谢,fabrik

php fluent-interface method-chaining

5
推荐指数
1
解决办法
1065
查看次数

EF 4.1 RC EF CF中的多对多关系

我有两个具有多对多关系的实体,如下所示:

class author
{
  public int AuthorID{get;set;}
  public string Name{get;set;}
  public virtual ICollection<book> books{get;set;}
}
class book
{
  public int BookID{get;set;}
  public string Name{get;set;}
 public virtual ICollection<author> authors{get;set;}

}
Run Code Online (Sandbox Code Playgroud)

我有一个名为Bookauthor的中间表,定义如下:

  BookAuthor: int
  int AuthorID
  int BookID
Run Code Online (Sandbox Code Playgroud)

如何使用FluentAPI进行映射

谢谢!!

mapping many-to-many entity-framework fluent-interface entity-framework-4.1

5
推荐指数
1
解决办法
1638
查看次数

EF 4.1 RC Code First - 映射到现有数据库并指定外键名称

我有两节课.公司有一个县反对它:

public class Company
{
    public int Id { get; set; }
    public string CompanyName { get; set; }
    public Country HomeCountry { get; set; }
}

public class Country
{
    public int Id { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我试图映射到现有数据库,其中Company表包含Country记录的外键.所以我可能需要首先告诉代码外键列的名称.

下面是完整的代码示例.基于我尝试的不同的事情,它目前失败了不同的例外.到目前为止,似乎还缺乏有关此问题的有凝聚力的文档.

因此,使用Code First Fluent API如何定义外键列的名称?

测试应用:

按如下方式创建数据库:CREATE DATABASE CodeFirst; 走

Use CodeFirst

create table Companies
(
    Id int identity(1,1) not null,
    HomeCountryId int not null,
    Name …
Run Code Online (Sandbox Code Playgroud)

fluent-interface ef-code-first entity-framework-4.1

5
推荐指数
1
解决办法
5712
查看次数

实体框架 - Code First Fluent API:ErrorMessage?

我想在数据注释中使用Fluent API的本地化验证:

[Required(ErrorMessageResourceName = "Domain_Address_AddressTypeRequired", ErrorMessageResourceType = typeof(Resources))]
public virtual  AddressType  AddressType  { get; set; }
Run Code Online (Sandbox Code Playgroud)

不幸的是.IsRequied()没有重载版本来给出如下错误信息:

.IsRequied("That was your last mistake! :D");
Run Code Online (Sandbox Code Playgroud)

那可能吗?怎么样?

谢谢

PumpeR1

entity-framework fluent-interface code-first data-annotations

5
推荐指数
1
解决办法
1309
查看次数

javascript流畅的api vs选项对象

一个javascripter我尊重谈论你应该如何避免大型选项对象,以支持流畅的api.

为什么?优缺点都有什么?

避免大型选项对象

如果组件真正只需要几个选项,并且在事后不太可能改变,那么选项对象可能是合适的.我强烈建议考虑一个流畅的API,即使你提供了一个选项对象.这使代码更加清晰,因为流畅的API可以支持选项对象中的每个键,否则会提升极大的插件.记住建立一个用户友好的API,不要从那里开始.

https://github.com/component/component/wiki/Building-better-components

javascript fluent-interface

5
推荐指数
1
解决办法
349
查看次数

在Delphi中具有继承性的流畅接口

我有以下流利的接口声明和实现该接口的类:

type
  IDocWriter = interface
    ['{8CB5799A-14B1-4287-92FD-41561B237560}']
    function Open: IDocWriter;
    function Close: IDocWriter;
    function Add(const s: string): IDocWriter;
    function SaveToStream(Stream: TStream): IDocWriter;
  end;

  TDocWriter = class(TInterfacedObject, IDocWriter)
  public
    function Open: IDocWriter;
    function Close: IDocWriter;
    function Add(const s: string): IDocWriter;
    function SaveToStream(Stream: TStream): IDocWriter;
  end;

{ TDocWriter }

function TDocWriter.Open: IDocWriter;
begin
  Result := Self;
  // DoOpen
end;

function TDocWriter.Close: IDocWriter;
begin
  Result := Self;
  // DoClose
end;

function TDocWriter.Add(const s: string): IDocWriter;
begin
  Result := Self;
  // DoAdd
end;

function TDocWriter.SaveToStream(Stream: …
Run Code Online (Sandbox Code Playgroud)

delphi fluent-interface delphi-xe4

5
推荐指数
0
解决办法
537
查看次数

具有getter和setter的对象的Fluent Interface(Java)

我阅读并欣赏了来自Lukas Eder 的文章http://blog.jooq.org/2012/01/05/the-java-fluent-api-designer-crash-course/,我想创建一个流畅的界面类.

该类有四个函数("words"fill1到fill4),它们允许设置对象属性和四个函数("words"get1 to get4)获取这些属性,但只有在设置了所需的属性时:

首先,我必须填写基本设置(fill1).之后我或者能够获得一些这些设置(get1到get3),这些是Strings.或者我可以填写更多信息(fill2到fill4).但是只有在每次 fill2到fill4被调用至少一次之后,才能调用最终的get4.我该怎么做呢?

第一个图(状态是黑点)显示我想要做什么,但你可以看到?标记不清楚的部分,因为如果保留在第一个图形中,即使只调用了fill2到fill4中的一个,它也会允许调用get4.

第二个图表会强制每个fill2到fill4已被调用但强制执行顺序并限制如果我想更改例如fill3,我也必须重置fill2和fill4.

最后一个图表会做我想要的,但它有13个状态!现在,如果我想象我只会在fill2到fill4的组中再添加一个属性,那么状态的数量会更多.

在此输入图像描述

编辑:此外,在考虑了一些之后,我注意到我这样做的方式(见下文)甚至无法实现最后一个图,因为在调用fill2之后,我们可能处于不同的状态 -取决于之前发生的事情.

我能做什么/应该做什么?

编辑:我实现我的流畅的界面有点像一个立面(如果我有正确的设计模式).我的意思是:我让实际的类几乎不受影响 - 返回它(如方法链接),但是在方法签名中将相应的状态接口作为返回值.状态由嵌套接口表示.例:

public class MyClass implements MyInterface.Empty, MyInterface.Full {

    String stuff;

    private MyClass(){};

    public static MyInterface.Empty manufactureNewInstance(){
        return new MyClass();
    }

    public MyInterface.Full fillStuff(String stuff){
        this.stuff = stuff;
        return this;
    }

    public String getStuff(){
        return stuff;
    }

}

public interface MyInterface {

    public interface Empty {
        public MyInterface.Full fillStuff();
    }

    public interface Full {
        public String …
Run Code Online (Sandbox Code Playgroud)

java fluent-interface

5
推荐指数
1
解决办法
1007
查看次数