📄 lib0069.html
字号:
<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Value Objects Made Easy</title>
<link rel="STYLESHEET" type="text/css" href="images/xpolecat.css">
<link rel="STYLESHEET" type="text/css" href="images/ie.content.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle" alt="Team LiB"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="LiB0068.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0070.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr></table>
<br>
<div class="chapter">
<a name="ch10"></a>
<div class="section">
<h2 class="first-section-title"><a name="323"></a><a name="ch10lev1sec2"></a>Value Objects Made Easy</h2><p class="first-para">My laundry list of recommendations makes implementing value objects extremely boring, tedious, and time consuming. As a technical architect, you have the option of mentoring developers as they follow these recommendations and, you hope, implement them consistently. Another option is to provide architectural utilities that make coding value objects easier and quicker and bring some consistency to value object behavior.</p>
<p class="para">These goals are achieved by CementJ, a tool I created to provide architectural support for value objects. To use CementJ value object support, you need to extend <span class="fixed">org.cementj.base.ValueObject</span> from the CementJ API. <span class="fixed">ValueObject</span> contains a meaningful implementation of <span class="fixed">equals()</span>, <span class="fixed">hashcode()</span>, and <span class="fixed">describe()</span> so you don't have to implement them. Unfortunately, CementJ isn't able to provide a reliable implementation of <span class="fixed">compareTo()</span> because of current limitations with Java's reflection API. <a class="internaljump" href="#ch10list08">Listing 10.8</a> is an example of how you can extend <span class="fixed">ValueObject</span>.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 10.8: </span>Sample Value Object Extending org.cementj.base.ValueObject</span><a name="324"></a><a name="ch10list08"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
1:package book.sample.vo.cementj;
2:
3:import org.cementj.base.ValueObject;
4:
5:public class CustomerVO extends ValueObject
6:{
7:
8: public CustomerVO() {}
9:
10: public String getCustomerId()
11: {
12: return _customerId;
13: }
14: public void setCustomerId(String id)
15: {
16: if (id == null)
17: {
18: throw new IllegalArgumentException
19: ("Null customer Id not allowed.");
20: }
21: if (id.equals(""))
22: {
23: throw new IllegalArgumentException
24: ("Blank customer Id not allowed.");
25: }
26: _customerId = id;
27: }
28:
29: // some code ommitted for bevity
30:
31: private String _customerId = null;
32: private String _firstName = null;
33: private String _lastName = null;
34: private String _address = null;
35: private String _city = null;
36: private String _state = null;
37: private String _zipCode = null;
38:}
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<a name="325"></a><a name="IDX-131"></a>
<p class="para">
<i class="emphasis">Source:</i> /src/book/sample/vo/cementj/CustomerVO.java</p>
<p class="para">Although <a class="internaljump" href="#ch10list08">listing 10.8</a> has the same functionality as the custom-coded original value object, it's only 73 lines long as opposed to 180. You don't need to specify implementation of <span class="fixed">Serializable</span> or <span class="fixed">Describable</span> because <span class="fixed">ValueObject</span> does it for you.</p>
<a name="326"></a><a name="IDX-132"></a>
<p class="para">In addition, <span class="fixed">ValueObject</span> provides a <span class="fixed">describeAsXML()</span> feature that formats the content of a value object into an XML formatted document. This feature can save you time in applications that need to transmit the content of a value object via messaging technologies to another application. Another possible use of this feature is to use the XML version of the content to provide better presentation in error messages. <a class="internaljump" href="#ch10list09">Listing 10.9</a> illustrates an XML document generated by <span class="fixed">ValueObject</span>.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 10.9: </span>Sample XML Document Description of a ValueObject</span><a name="327"></a><a name="ch10list09"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
<?xml version="1.0" encoding=" UTF-8"?>
<!DOCTYPE book-sample-dto-cementj-CustomerDTO>
<book-sample-dto-cementj-CustomerDTO name=" book-sample-dto-cementj-
CustomerDTO">
<Field name="_customerId" type=" java.lang.String"
value="12345"/>
<Field name="_firstName" type=" java.lang.String"
value=" Derek"/>
<Field name="_lastName" type=" java.lang.String"
value=" Ashmore"/>
<Field name="_address" type=" java.lang.String"
value="34 Yorktown Center, PMB 400"/>
<Field name="_city" type=" java.lang.String"
value=" Lombard"/>
<Field name="_state" type=" java.lang.String"
value=" IL"/>
<Field name="_zipCode" type=" java.lang.String"
value="60148"/>
</book-sample-dto-cementj-CustomerDTO>
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<p class="para">
<span class="fixed">ValueObject</span> does use reflection to achieve its magic, so it's slower than custom-coded value objects. <a class="internaljump" href="#ch10table01">Table 10.1</a> presents a performance comparison for our sample <span class="fixed">CustomerVO</span>.</p>
<a name="328"></a><a name="ch10table01"></a>
<table class="table" border="1">
<caption class="table-title">
<span class="table-title"><span class="table-titlelabel">Table 10.1: </span>Performance Comparison for ValueObject for 1,000</span>
</caption>
<thead>
<tr valign="top">
<th class="th" scope="col" align="center">
<p class="table-para">
<b class="bold">Version</b>
</p>
</th><th class="th" scope="col" align="center">
<p class="table-para">
<b class="bold">JVM</b>
</p>
</th><th class="th" scope="col" align="center" valign="top" colspan="3">
<p class="table-para">
<b class="bold">Milliseconds per 1,000 operations</b>
</p>
</th>
</tr>
<tr valign="top">
<th class="th" scope="col" align="center">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -