通常 JavaPractices.com 是一个有好主意的好网站,但这个网站让我很困扰:JavaBeans are bad .
文章列举了几个原因,主要是 JavaBean 一词的意思是“Java Bean 是一种可重用的软件组件,可以在构建工具中进行可视化操作”。不是数据存储,违反了某些模式,而且更复杂。
现在我可以同意最后一个,但在我看来,列表中的 JavaBeans 比嵌套的 Maps 更有意义。文章声称数据库映射框架应该调用构造函数,而不是 set* 方法,并且对象应该是不可变的。然而,在我看来,尝试构建对象时调用 set* 方法比 new MappedObject("column1", "column2", "yet another column", "this is stupid");
除了数据库映射之外,我还将 JavaBean 样式类用于其他用途,例如,对于 IRC 机器人,每个用户都有一个对象,可以根据各种内容进行更新。我不想每次提供新信息时都创建一个新对象,我想将它添加到现有的对象中。
所以我的问题是:使用 JavaBeans 进行数据存储是一种不好的做法并且应该避免,还是说它绝对安全?
最佳答案
看来你误读了文本。
Now I can agree with the last one, but in my eye's JavaBeans in a list makes alot more sense than nested Maps
文中从未提及嵌套映射作为替代方案 (yiack)
...should call constructors, not set* methods, and the object should be immutable
这是一个很好的做法,在处理线程时特别有用。
但我们也不能说使用 setter 是baaad,特别是当单个线程正在使用该对象时。那是绝对安全的。
I don't want to create a new object every time new information is given, I want to add it to an existing one.
没关系,只要你能控制这个对象就没有问题,其他人可能会觉得创建一个新对象更容易。
Is using JavaBeans for data storage a bad practice and should be avoided, or is it perfectly safe?
不,这不是一个坏习惯。也不是绝对安全。视情况而定。
可变对象(不是 JavaBeans 本身)的问题是使用不同的线程来访问它们。
您必须同步访问以避免一个线程修改对象而其他线程正在访问它。
不可变对象(immutable对象)没有这个问题,因为,..它们不能改变,因此,你不必同步任何东西。
要确保对象是不可变的,您必须将属性声明为 final。
class MyBean {
private final int i;
}
如果你想为 MyBean.i 分配一个合理的值,你必须在构造函数中指定它:
public MyBean( int i ) {
this.i = i;
}
因为变量是final,所以不能使用setter。你可以只提供一个 setter/getter 。
这是完全线程安全的,最好的是,你不必同步访问,因为如果两个线程试图获取 i 的值,它们都将始终看到是在实例化时分配的,您不必同步任何东西。
既不是坏习惯也不是好习惯。我们必须使用单线程工作,即使在像 servlet 这样的多线程环境中也是如此。
如果以后要处理多线程应用,可以考虑使用不可变的JavaBean ;)
顺便说一句,创建不可变 bean 并仍然提供一堆 setter 的替代方法是使用 Builders,例如:
Employee e = new EmployeeBuilder()
.setName("Oscar")
.setLastName("Reyes")
.setAge(0x1F)
.setEmployeeId("123forme")
.build();
这看起来与常规 bean 中使用的常规 setXyz 非常相似,具有使用不可变数据的好处。
如果你需要改变一个值,你可以使用类方法:
Employee e = Employee.withName( e, "Mr. Oscar");
它获取现有对象,并复制所有值,然后设置一个新值....
public static EmployeeWithName( Employee e , String newName ){
return new Employee( newName, e.lastName, e.age, e.employeeId );
}
但同样,在单线程模型中使用 getter/setter 是完全安全的。
PS 我强烈建议您购买这本书:Effective Java .您永远不会后悔,并且您将有信息来判断被引用的更好的文章。
关于java - Java Bean 作为数据存储类是糟糕的设计吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3114903/
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht