没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
原创|其它|编辑:郝浩|2009-04-30 11:57:12.000|阅读 376 次
概述:Java类的选择是真的只用一个typesafe解决方案,而其通过改进风格,这些类可以更好的代替structs,而且有他们自己的一些优势。
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
Java类的选择是真的只用一个typesafe解决方案,而其通过改进风格,这些类可以更好的代替structs,而且有他们自己的一些优势。
举个带有两个arguments的一个返回类——一个name和一个 date of birth:
public class PersonNameDOB {
private String name;
private Date dob;
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
显然这是一个编造的例子,有机会你可以有一个已经定义的可返回的Person 类。用一个方法返回两个不同的对象,但是不要有已经为他们定义的一个类,或者也许你最终返回到一个类,这个类带有更多的信息为了只从中得到一对条目。根据不同的可能更糟糕的情况。例如,如果有人调用你的方法开始在返回的对象中使用或是修改值时你会打算让这样的事情发生?
以上是代码而不是所必须的。这意味着要变成返回一些值的一个轻便的方法,所以我们来做些改变:
public class PersonNameDOB {
public final String name;
public final Date dob;
public PersonNameDOB(String name, Date dob) {
this.name = name;
this.dob = dob;
}
}
结果很短,但更适合这个任务。值被返回,setters也没有必要了,我们只要在返回对象被创建时建立值就行了。它们不需要改变,因为它们在一个constructor中,他们最后会被制造出来的。现在他们是最终的结果,类公开也没有任何风险,因为他们没有受到影响,所以现在你可以摆脱getters和setter了。结果很短而且便于使用:
PersonNameDOB personNameDOB = SSNLookup.lookupBySSN("123-45-6789");
System.out.println(personNameDOB.name);
System.out.println(personNameDOB.dob);
And the lookupBySSN method: lookupBySSN方法:
public PersonNameDOB lookupBySSN(String ssn) {
... Find the person record in the DB, etc. ...
return new PersonNameDOB(person.getName(), person.getDOB());
}
如果这个显然看起来非常棒,只要忍受我把事情进一步发展。
我喜欢这个方法来减轻返回对象。它是typesafe,所以没有必要在返回后分配数组外的对象。更好的是,最后修改的属性意味着这些返回的对象不能滥用——它们只是用于数据的转移。
将这个安全的步骤进一步,我建议你可以复制对象或是有可能使用不改变的对象,因为不这样做通过调用方法会增加在你的donor对象的值的意想不到的修改。在我们的例子中,String是不可改变的,但是数据是复制的:
public PersonNameDOB lookupBySSN(String ssn) {
... Find the person record in the DB, etc. ...
return new PersonNameDOB(person.getName(), new Date(person.getDOB().getTime()));
}
这个将阻止一个caller,操作如下:
PersonNameDOB personNameDOB = SSNLookup.lookupBySSN("123-45-6789");
personNameDOB.dob.setTime(0);
从一方影响原始DOB值,这是个很大的风险。如果你不能使用这些不改变的值,要务必在你的结果中复制并返回那些副本。
以上的模式是一个使用过多次的作为一个struct代替Java API调用,但是对创建这些类它仍然是一个损耗,如果你想要做的是返回两个类型对象,这确实是很平常的(许多finder算法可以更有效率的工作,通过简单的返回相关的一对代替一个,如一个密码,是添加到地图中的有价值的pair)。
这种情况下这似乎像是一个低挂的水果,但是从Java SE标准分配中神秘失踪的是一个genericized Pair class。看一看你如何能够从上面的模式中构建它。
首先,值要比name和dob要普遍。最普遍的似乎是把fields命名为first和 second:
public class Pair {
public final String first;
public final Date second;
public Pair(String first, Date second) {
this.first = first;
this.second = second;
}
}
到目前为止一起都很顺利。你现在有一个大致的类来返回Strings 和Dates,但不是其他的类型。如下:
public class Pair {
public final A first;
public final B second;
public Pair(A first, B second) {
this.first = first;
this.second = second;
}
}
不必去担心通配符这些东西只是代码一但返回类型的一个快捷方式。这个类现在可用于general type pairs,例如:
public static Pair lookupBySSN(String ssn) {
// find the person in the DB....
return new Pair(person.getName(), new Date(person.getDOB().getTime()));
}
使用它:
Pair personNameDOB = SSNLookup.lookupBySSN("123-45-6789");
System.out.println(personNameDOB.first);
System.out.println(personNameDOB.second);
你用的Pair 类还没有结束。如果这个事情真的具有普遍性,你需要考虑一些事情:
· 你不想别人来扩展Pair class并改变它所做的事情——有肯能打破的类的原本意图。
· new Pair()可以,但是它看上去有点笨拙。你可以做到比它还要好。
· Pair对返回的值很有用,但是作用很小,例如,作为地图中的答案。
· 有一个很好的形式的Pair字符串代表是相当不错的可以进行调试或是其他toString()使用。
· 最后,也许(这是有争议的),让Pair和包含的对象序列化如果内容也序列化那将是非常好的。
所以,让我们看一下pair执行时如何变化的:
public final class Pair implements Serializable {
private static final long serialVersionUID = 1L; // shouldn't
// need to change
public final A first;
public final B second;
private Pair (A first, B second) {
this.first = first;
this.second = second;
}
public static Pair of (A first, B second) {
return new Pair(first,second);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Pair other = (Pair) obj;
if (this.first != other.first &&
(this.first == null || !this.first.equals(other.first))) {
return false;
}
if (this.second != other.second &&
(this.second == null || !this.second.equals(other.second))) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 37 * hash + (this.first != null ?
this.first.hashCode() : 0);
hash = 37 * hash + (this.second != null ? this.second.hashCode() : 0);
return hash;
}
@Override
public String toString () {
return String.format("Pair[%s,%s]", first,second);
}
}
你应该让constructor很秘密的,但是提供一个静态的of()方法,我想读起来会更好:
return Pair.of(person.getName(), new Date(person.getDOB().getTime()));
你把Pair类放最后,所以没人会不理它并且改变类的原本意图。这看起来很严格,但是为了更广泛使用的目的,防范这样的事情是十分明智的。如果有人像让Pair做不同的工作,他们需要写入自己的执行,向同行证明它是有道理的。
equals()和hashCode()方法说明这个类能够用于更多的目的而不仅仅是返回值。他们可用于,例如,作为地图的关键点。这有一个建议,是对使用这个样式的任何类型的返回对象,是让你的IDE为你创建equals和hashCode方法——这些是简单的实现但是这里有要记住的一些事情是关于hashCode 和equals的合同,例如,null checks和不同的types(参见在Josh Bloch的Effective Java 2nd ed书中关于明确的描述)。IDEs往往有插入最好的已定义的练习样板,所以我只用NetBeans来创建这些。也许它们可以再精简一点,但是这些执行是很安全的。我从NetBeans equals()执行中删除通用签名,因为它没有必要了而且会制造疑惑。
toString()覆盖了刚刚打印的一个漂亮格式的pair,像"Pair[Fred Jones,Sun Mar 22 12:55:44 PDT 2009]"。这个特别用于调试的popups。
现在类完成序列化。我相信这点是选择变得更不可相信的一点,但是因为collection序列化,在我看来Pair也应该序列化。如果类在没有序列化的Pair中使用,Pair就不是阻止序列在类中使用的东西了。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:IT专家网面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号