- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我阅读并喜欢这篇文章 http://blog.jooq.org/2012/01/05/the-java-fluent-api-designer-crash-course/来自 Lukas Eder,我想为一个类创建一个 Fluent Interface。
该类有四个允许设置对象属性的函数(“words”fill1 到 fill4)和四个获取这些属性的函数(“words”get1 到 get4),但前提是已设置所需的属性:
首先,我必须填写基本设置 (fill1)。之后,我要么能够获得其中一些设置(get1 到 get3),它们是字符串。或者我可以填写更多信息(fill2 到 fill4)。但只有在 every fill2 到 fill4 被调用至少一次之后,才能调用最后的 get4。我该怎么做?
第一张图(状态是黑点)显示了我想做的事情,但是正如你所看到的?标记不清楚的部分,因为如果保留在第一个图中,即使只调用了 fill2 到 fill4 中的一个,也可以调用 get4。
第二张图将强制调用每个 fill2 到 fill4,但如果我想更改,则会强制执行并限制顺序,例如fill3,我还必须重置 fill2 和 fill4。
最后一张图可以满足我的要求,但它有 13 个状态!现在,如果我想象我会再添加一个属性到 fill2 到 fill4 组,状态的数量会爆炸得更多。
编辑:此外,在进一步考虑之后,我注意到我这样做的方式(见下文)甚至无法实现最后一个图表,因为在 fill2 之后被调用时,我们可能处于不同的状态 - 取决于之前发生的事情。
我能/应该做什么?
编辑:我实现我的流畅界面有点像外观(如果我的设计模式正确的话)。我的意思是:我几乎没有触及实际的类 - 返回 this(如在方法链接中),但是将各自的状态接口(interface)作为方法签名中的返回值。状态由嵌套接口(interface)表示。示例:
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 getStuff();
}
}
public class MyMain {
pulic static void main(String[] args) {
// For explaination:
MyClass.Empty myclassEmpty = MyClass.manufactureNewInstance();
MyClass.Full myclassFull = myclassEmpty.fillStuff("Hello World 1!");
String result1 = myclassEmpty.getStuff();
// As fluent chaining:
String result2 = MyClass.manufactureNewInstance()
.fillStuff("Hello World 2!")
.getStuff();
}
}
最佳答案
Java 中的 Fluent 接口(interface) API 在一定程度上受到限制,因为您需要用不同的类型表示每个 API 状态。这是因为 Java 类型是将一组 API 约束传递给 Java 编译器以进行验证的唯一方式。
显然,在创建流畅的 API 时,这是一个不幸的限制。要克服此限制,您需要:
通过例如接口(interface)手动实现所有 API 状态。如果您的代码不太可能更改,例如,这可能是一个可行的解决方案。在一个范围相当有限、不应该存在太久的项目中。然后,单个支持类可以实现代表每个API 状态 的所有接口(interface)。只要用户不使用反射或类型转换,编译器就会验证方法是否按合法顺序调用。
自动生成代码。这是一种更雄心勃勃的方法,但如果您的 API 状态组合如您所说的那样“爆炸”,它可以为您节省大量的输入和重构工作。我写了一个名为 Byte Buddy 的代码生成库我知道用户使用该库为流畅的 API 创建接口(interface)。 (不幸的是,我在这件事上联系的两个用户没有开源他们的代码。)如果你更想创建 Java 源代码而不是 Java 字节代码,那么 Java poet可能是您的替代方案,我也看到了这个用例。
简化您的 API,使其仅验证最常见的错误,同时在运行时通过异常检查不太常见的错误。这通常是一个可行的解决方案,因为它使 API 更易于使用。
关于java - 具有 getter 和 setter 的对象的 Fluent Interface (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32740396/
因此,我需要获取在为其赋值时调用的 setter 的名称。像这样: var b = {}; var a = { set hey(value) { b[] = value; } } 我希望 se
我是 Android 编程的新手(~ 2 个月)有必要为几十个不同的变量设置 getter 吗? 例如—— //Yes I realise that this isn't 'dozens' publi
import Control.Lens import Control.Lens.TH data Foo = Foo { _bar, _baz :: Int } makeLenses ''
我有点困惑:我可以覆盖 setter/getter 但仍然使用 super setter/getter 吗?如果是 - 怎么办? 用例: class A { void set value(num
我有一个接收消息的应用程序。消息中存在可编辑的字段。当字段更改时,应将其保存到数据库中。不幸的是,setter 仅在 setter 的范围内更改给定字段的值。知道为什么会发生这种情况吗?这是 gett
C# 中有没有一种方法可以让 setter 从“某物”继承,这样每次为特定基类及其继承者调用 setter 时,我都可以运行一些代码? 我想做的是在我的基类上有一个名为 IsValid 的 bool
可能是一个我无法解决的非常简单的问题 - 我从 C# 开始,需要使用 getter/setter 方法向数组添加值,例如: public partial class Form1 : Form {
这两个属性实现有什么区别? public override string A { get { return "s"; } set { } } public override strin
是否可以使用 abc.abstractproperty 创建一个具体的 getter 但将 setter 抽象为每个继承类的不同。我为每个子类处理不同的 val 设置。 例如。 @abstractpr
我在某处看到类似下面的内容,想知道它是什么意思。我知道他们是getter和setter,但是想知道为什么字符串Type是这样定义的。谢谢你帮助我。 public string Type { get;
Public class Example { private int number; public Example(int number){ this.number =
假设我有这样的代码: public response MyMethod(Request req) { String id = req.getFirst().geId(); } 我已经模拟了主对
允许这样做: public int Age { get; set; } 但是应用程序是否为变量创建/分配空间?我经常这样做 private int age = 0; public int Age {
我有一个条件,我构造字符串 (finalValue) 的方式是基于我在输入中获得的非空值的数量。所以我想知道是否可以用一个不同的参数为字符串 (finalValue) 重载 setter 方法并根据我
例如,在这段代码中 var o = { set a(value) {this.b = value}, get a() {return this.b} } 是否有可能获得对 o.a 的 sett
我一直在努力了解 getter 和 setter,但没有深入了解。我读过 JavaScript Getters and Setters和 Defining Getters and Setters只是没
我想在我的类中添加一个 getter 和 setter。然而,setter 应该接收一个 querySelector,但 getter 返回一个新类型 pageSections。 我的问题是 gett
使用有什么好处: private var _someProp:String; public function set someProp(value:String):void { _somePr
当从域类调用它时,我想在我的 setter 中执行一些操作,而不是从 hibernate 中调用它时。此外,我正在使用 session 工厂,因此我无法使用 @PostLoad 来触发标志! 有人对此
人员类别: public class Person { private String firstName; private String lastName; public Pe
我是一名优秀的程序员,十分优秀!