方法链接是返回对象本身的对象方法的实践,以便为另一个方法调用结果.像这样:
participant.addSchedule(events[1]).addSchedule(events[2]).setStatus('attending').save()
Run Code Online (Sandbox Code Playgroud)
这似乎被认为是一种很好的做法,因为它产生可读代码或"流畅的界面".但是,对我来说,它似乎打破了对象方向本身隐含的对象调用符号 - 结果代码并不表示对前一个方法的结果执行操作,这通常是预期面向对象的代码的工作方式:
participant.getSchedule('monday').saveTo('monnday.file')
Run Code Online (Sandbox Code Playgroud)
这种差异设法为"调用结果对象"的点符号创建两种不同的含义:在链接的上下文中,上面的示例将读作保存参与者对象,即使该示例实际上是为了保存时间表getSchedule收到的对象.
我知道这里的区别在于是否应该调用被调用的方法返回某些东西(在这种情况下,它会返回被调用对象本身以进行链接).但是这两种情况与符号本身无法区分,只能从被调用方法的语义中区分出来.当不使用方法链接时,我总是可以知道方法调用对与前一个调用的结果相关的操作进行操作- 使用链接,这个假设会中断,并且我必须在语义上处理整个链以了解实际的对象是什么真的叫.例如:
participant.attend(event).setNotifications('silent').getSocialStream('twitter').postStatus('Joining '+event.name).follow(event.getSocialId('twitter'))
Run Code Online (Sandbox Code Playgroud)
最后两个方法调用引用getSocialStream的结果,而之前引用的是参与者.也许在上下文发生变化的情况下实际编写链是不好的做法(是吗?),但即使这样,你也必须不断检查看起来相似的点链是否实际上保持在同一个上下文中,或者只对结果起作用.
对我来说似乎虽然表面链接表面确实产生可读代码,但重写点符号的含义只会导致更多的混淆.因为我不认为自己是编程大师,我认为错误是我的.那么:我错过了什么?我是否理解方法链以某种方式错误?在某些情况下,方法链接特别好,还是某些特别糟糕的情况?
旁注:我理解这个问题可以理解为一个被掩盖为问题的意见陈述.然而,它并非如此 - 我真的想要理解为什么链接被认为是良好的实践,以及我认为它打破固有的面向对象的符号在哪里出错.
我正在运行EF 4.2 CF并想在我的POCO对象的某些列上创建索引.
举个例子,假设我们有这个员工类:
public class Employee
{
public int EmployeeID { get; set; }
public string EmployeeCode { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime HireDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我们经常通过EmployeeCode对员工进行搜索,因为有很多员工,因为性能原因而将索引编入索引会很不错.
我们能用流利的api以某种方式做到这一点吗?或者数据注释?
我知道可以执行这样的sql命令:
context.Database.ExecuteSqlCommand("CREATE INDEX IX_NAME ON ...");
Run Code Online (Sandbox Code Playgroud)
我非常想避免那样的原始SQL.
我知道这不存在,但寻找沿着这些方向的东西:
class EmployeeConfiguration : EntityTypeConfiguration<Employee>
{
internal EmployeeConfiguration()
{
this.HasIndex(e => e.EmployeeCode)
.HasIndex(e => e.FirstName)
.HasIndex(e => e.LastName);
}
}
Run Code Online (Sandbox Code Playgroud)
或者使用System.ComponentModel.DataAnnotationsPOCO可能看起来像这样(我知道这不存在):
public class Employee
{ …Run Code Online (Sandbox Code Playgroud) c# fluent-interface entity-framework-4 data-annotations ef-code-first
我将通过示例展示一个问题.有一个具有流畅界面的基类:
class FluentPerson
{
private string _FirstName = String.Empty;
private string _LastName = String.Empty;
public FluentPerson WithFirstName(string firstName)
{
_FirstName = firstName;
return this;
}
public FluentPerson WithLastName(string lastName)
{
_LastName = lastName;
return this;
}
public override string ToString()
{
return String.Format("First name: {0} last name: {1}", _FirstName, _LastName);
}
}
Run Code Online (Sandbox Code Playgroud)
和一个儿童班:
class FluentCustomer : FluentPerson
{
private long _Id;
private string _AccountNumber = String.Empty;
public FluentCustomer WithAccountNumber(string accountNumber)
{
_AccountNumber = accountNumber;
return this;
}
public FluentCustomer WithId(long …Run Code Online (Sandbox Code Playgroud) 我想知道在对象中使用方法链接在流畅的界面中实现.When条件的最佳方法是什么?Builder
例如,我将如何实现以下示例中的.WithSkill()和.When()方法:
var level = 5;
var ninja = NinjaBuilder
.CreateNinja()
.Named("Ninja Boy")
.AtLevel(level)
.WithShurikens(10)
.WithSkill(Skill.HideInShadows)
.When(level > 3)
.Build()
Run Code Online (Sandbox Code Playgroud)
更新 - 可以在此处找到示例解决方案.
Ruby可以向Number类和其他核心类型添加方法以获得如下效果:
1.should_equal(1)
Run Code Online (Sandbox Code Playgroud)
但似乎Python无法做到这一点.这是真的?如果是这样,为什么?是否与类型无法修改的事实有关?
更新:我不想谈论猴子修补的不同定义,而是只关注上面的例子.我已经得出结论,由于你们中的一些人已经回答,所以无法做到.但我想更详细地解释为什么不能这样做,也许如果Python中有什么功能可以允许这样做.
回答你们中的一些人:我可能想要这样做的原因只是美学/可读性.
item.price.should_equal(19.99)
Run Code Online (Sandbox Code Playgroud)
这更像是英语,并清楚地表明哪个是测试值,哪个是预期值,如下所示:
should_equal(item.price, 19.99)
Run Code Online (Sandbox Code Playgroud)
这个概念就是Rspec和其他一些Ruby框架所基于的.
ruby python programming-languages fluent-interface monkeypatching
我有一个具有char属性的对象:
public class Product
{
public char Code
{
get;
set;
}
}
Run Code Online (Sandbox Code Playgroud)
实体框架似乎无法映射字符(当我从模型对象创建数据库模式时,数据库中缺少此字段).无论如何我可以使用流畅的API映射char(例如字符串)吗?我不想更改模型对象,因为它们是遗留共享库的一部分.
我正在为C#中的流畅接口提供一些好的技巧.我自己只是在学习它,但很想听到别人在我正在阅读的文章之外的想法.特别是我在追求:
如果您可以发布一个提示或思想,或每个帖子的任何内容.我想看看他们如何投票.
先感谢您.
我正在寻找关于设置nhibernate的教程.似乎很少有,但大多数是用胡言乱语写的,或者是一个非常古老的版本.
任何好的资源,甚至包括流畅或代码配置安装?
我有一个列"名称",必须是unqiue.没有外国钥匙或类似的东西.
EF 6.1最终支持通过Annotations创建此类索引.已在SO上讨论过这个问题.但它似乎只能通过类中的注释来完成.如何仅使用Fluent API执行此操作?
像这样的东西:
public class PersonConfiguration : EntityTypeConfiguration<Person>
{
public PersonConfiguration()
{
HasKey(p => p.Id);
Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
//not possible?
Index(p => p.Name).IsUnique(); //???
}
}
Run Code Online (Sandbox Code Playgroud) .net c# entity-framework fluent-interface entity-framework-6
方法链接是我知道构建流畅接口的唯一方法.
这是C#中的一个例子:
John john = new JohnBuilder()
.AddSmartCode("c#")
.WithfluentInterface("Please")
.ButHow("Dunno");
Assert.IsNotNull(john);
[Test]
public void Should_Assign_Due_Date_With_7DayTermsVia_Invoice_Builder()
{
DateTime now = DateTime.Now;
IInvoice invoice = new InvoiceBuilder()
.IssuedOn(now)
.WithInvoiceNumber(40)
.WithPaymentTerms(PaymentTerms.SevenDays)
.Generate();
Assert.IsTrue(invoice.DateDue == now.AddDays(7));
}
Run Code Online (Sandbox Code Playgroud)
那么其他人如何创建流畅的界面.你是如何创造它的?需要什么语言/平台/技术?
fluent-interface ×10
c# ×5
oop ×2
.net ×1
builder ×1
char ×1
inheritance ×1
nhibernate ×1
python ×1
ruby ×1