Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javabean';这是什么?_Java_Design Patterns - Fatal编程技术网

javabean';这是什么?

javabean';这是什么?,java,design-patterns,Java,Design Patterns,我可以定义setter方法来返回这个而不是void吗 比如: 然后我可以使用新的ClassA().setItem1().setItem2()是。这是一种称为方法链接的较为常见的技术,可用于创建“流畅的界面” 请参阅:,绝对没有什么可以阻止你这么做,但为什么。如果要执行此操作,请创建一个接受args的构造函数。请记住,某些使用bean的软件不会期望返回值,并且可能会产生一些意外的结果 如果您只是想简化初始化(可能是为了设置测试),您可以使用一些groovy代码。没有理由不能这样做。就个人而言,如果

我可以定义setter方法来返回这个而不是void吗

比如:


然后我可以使用新的ClassA().setItem1().setItem2()

是。这是一种称为方法链接的较为常见的技术,可用于创建“流畅的界面”


请参阅:,

绝对没有什么可以阻止你这么做,但为什么。如果要执行此操作,请创建一个接受args的构造函数。请记住,某些使用bean的软件不会期望返回值,并且可能会产生一些意外的结果


如果您只是想简化初始化(可能是为了设置测试),您可以使用一些groovy代码。

没有理由不能这样做。就个人而言,如果在对象创建过程中使用setter,我会将它们命名为item1()和item2()


使它更清楚(无论如何对我来说)这些方法的目的是什么。

关于JavaBeans规范有很多误解

它存在的主要原因是统一的Java“组件”模型。这是一种使用反射以编程方式与Java对象交互的方法。API本身被命名为。请看一下示例用法,您将比普通Java程序员了解更多

内省API可用于以统一的方式操作GUI元素。您的组件将其属性公开为一对getter和setter,以便在运行时在GUI构建器的属性表上发现和操作它们

因此,在我看来,混合使用fluentapi和JavaBeans规范是不可能的。这是两个完全不相关的概念,可以相互干扰。当方法签名不同(返回类型)时,JavaBeans内省可能不起作用

看看这个例子(摘自链接教程):

此示例创建一个非可视bean,并显示从BeanInfo对象派生的以下属性:

  • 阶级
  • 名字
  • 大小
您可能希望看到将
void
返回类型更改为其他类型时会发生什么。我这样做了,结果是一样的。那么,这是否意味着这是允许的

恐怕不行。JavaBeans规范对这些方法签名要求很严格。碰巧实现是宽容的。尽管如此,我不建议将fluent接口与JavaBeans混合使用。你不能真的相信这一点,如果这个发现现在起作用,将来也会起作用


但是,从另一方面看,您似乎没有充分使用JavaBeans。只有方法的getter/setters对。如何实现和设计API取决于您

没有什么可以阻止您提供setter方法,这些方法在接口中以约定的形式返回目标对象

但是,您还必须为setter方法使用规范签名(例如,
void setProp(Type t)
),否则bean属性将不会被其他期望该签名的软件识别为可写。

检查后,我没有找到任何明确告诉您setter需要无效的内容。然而,所有的例子都有空集方法

javaapi中的函数支持非void setter,因此我认为让setter返回它应该是非常安全的。为了安全起见,您可能应该检查您打算使用的框架是否使用反射。例如,没有。

将JavaBean描述为:

javabean是一种可重用的软件 可以操纵的组件 在生成器工具中可视化

它们需要提供内省、定制、事件和持久性以及其他属性(第2.1节:什么是bean?)

根据JavaBeans规范(第7.1节和第8.3节),使用访问器方法对普通的旧Java对象调用“JavaBean”是很常见的。事实上,这样的对象可能还远远不能满足所有的要求

如果您在此类中定义的对象实际上是一个JavaBean,那么您的方法必须根据JavaBean规范第7.1节返回void,其中访问器方法描述如下:

void setFoo(PropertyType value); // simple setter
PropertyType getFoo(); // simple getter
第8.3节“特性设计模式”指出:

默认情况下,我们使用设计模式通过查找表单的方法来定位属性:

public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);
public get();
公共无效集(a);
此外,对于布尔属性,我们允许getter方法匹配模式:

public boolean is<PropertyName>();
public boolean is();
然而,如果您的类只是一个POJO,那么使用方法链接策略没有什么错,因为您可以偏离规范,因为您实际上并没有构建JavaBean。毕竟,并不是所有定义的类都应该是JavaBeans,对吧


您可能想看看。

我想这并不违反JavaBean规范,尽管我不确定

请查看以下示例:

public class JavaBean {

    private String value;

    public String getValue() {
        return value;
    }

    public JavaBean setValue(String value) {
        this.value = value;
        return this;
    }

    public static void main(String[] args) throws Exception {
        JavaBean bean = new JavaBean();
        JavaBean.class.getMethod("setValue", String.class).invoke(bean, "test");
        System.out.println(bean.getValue());
    }
}

许多框架使用反射API访问JavaBean。如上所述,访问返回“this”的setter不受返回类型的影响(返回类型不用于通过反射定位方法)。这也是有意义的,因为在一个作用域中,除了返回类型之外,不能有两个完全相同的方法。

只需补充一点,对于使用Spring 3.1+的用户来说,这不再是一个问题


生成器模式通常用于构造不可变对象。尽管JavaBeans本质上并不是一成不变的,但我经常在JavaBeans上使用builder模式,因为它提供了一个流畅的接口,我可以在测试中使用它。这两者很容易相互兼容,而不会破坏JavaBean规范。您可以在堆栈溢出上查看它

您只需要确保包含默认构造函数和私有构建器构造函数,然后将标准getter和setter放入JavaBean对象中

Th
public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);
public boolean is<PropertyName>();
public class JavaBean {

    private String value;

    public String getValue() {
        return value;
    }

    public JavaBean setValue(String value) {
        this.value = value;
        return this;
    }

    public static void main(String[] args) throws Exception {
        JavaBean bean = new JavaBean();
        JavaBean.class.getMethod("setValue", String.class).invoke(bean, "test");
        System.out.println(bean.getValue());
    }
}