📄 lib0111.html
字号:
<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Chapter 17: Application Architecture Strategies</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="LiB0110.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0112.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="ch17"></a>
<h1 class="chapter-title"><span class="chapter-titlelabel">Chapter 17: </span>Application Architecture Strategies</h1><a name="537"></a><a name="IDX-223"></a>
<div class="highlights">
<p class="first-para">To ensure that your applications have internal consistency, you need to establish strategies for logging, exception handling, threading, and configuration management from the outset. Most developers have preferences for each area of application building. If your team has many developers and you let them use their preferences, you will create an application that is internally inconsistent and harder to maintain. This chapter offers strategies for each aspect of application architecture. In this section, I've articulated examples of strategies I've used in the past. Once you establish the strategy, don't be afraid to refine it with additional detail to suit the needs and comfort level of your developers.</p>
</div>
<div class="section">
<h2 class="sect2-title">
<a name="538"></a><a name="ch17lev1sec1"></a>Logging Strategies</h2>
<p class="first-para">
<b class="bold">Application components should not depend on a specific logger.</b> General-use components should be able to use any logging package an application adopts. This can be done by having one class in the application acting as a log manager, delegating the log write to Log4J or one of the other logging packages. <a class="internaljump" href="#ch17list01">Listing 17.1</a> is an example of an application logger implementation.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 17.1: </span>Sample Log Manager Using Log4J</span><a name="539"></a><a name="ch17list01"></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:import org.apache.log4j.ConsoleAppender;
2:import org.apache.log4j.FileAppender;
3:import org.apache.log4j.PatternLayout;
4:
5:public class Logger
6:{
7: public static void logInfo(String message)
8: {
9: _internalLogger.info(message);
10: }
11:
12:// Other "log" methods omitted.
13: private static org.apache.log4j.Logger _internalLogger
14: = null;
15: static
16: {
17: _internalLogger = org.apache.log4j.Logger.getLogger
18:(Logger.class);
19: _internalLogger.addAppender (
20:new FileAppender(new PatternLayout(),
21:Environment.getLogFileName()));
22: }
</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="540"></a><a name="IDX-224"></a>
<p class="para">The Apache open source component software, Commons, has a package called Logging designed to fill this need. Unfortunately, it is rather heavy (despite being billed as intentionally "lightweight") and not easy to use. It requires an XML parser and has a more complicated configuration scheme. I consider Logging more hassle than it's worth.</p>
<p class="para">
<b class="bold">Limit coding for logging methods to one line.</b> Logging is done so frequently that you'll save a lot of time by reducing the code it takes to log. Notice that <a class="internaljump" href="#ch17list01">listing 17.1</a> makes all logging methods static. You don't have to instantiate anything to log a message. Some logging implementations have you executing a static method on a factory of some type to get a logger. Don't subject your developers to this extra code.</p>
<p class="para">
<b class="bold">Decouple exception handling and logging.</b> Usually, the activity that follows catching an exception is logging the event with enough information to replicate the bug. Consequently, many developers incorporate logging logic within the exception they generate on construction. This practice is convenient programmatically because the logging takes place automatically when the exception is instantiated, and it ensures that an exception is logged and not swallowed.</p>
<a name="541"></a><a name="IDX-225"></a>
<p class="para">However, the strategy creates some problems. It leads to multiple log entries for the same error and log entries without enough context to solve the error (often informational context from the caller is needed). Further, reusing objects in another application that may have a different logging strategy is difficult under this strategy.</p>
<p class="para">Another problem with incorporating logging logic within the exception is that the same exception may be treated as a severe error in one application and as a nonevent in another. For example, "Customer not found on database" might be a grave error worthy of logging for a customer maintenance application but not for a reporting application. It would be logical for the customer look-up to be the same code.</p>
<p class="para">I prefer to log at the deployment level. For example, my enterprise beans log exceptions directly or indirectly generated by classes used by the enterprise beans. Similarly, my client applications and CORBA services log exceptions generated in those deployments. By logging at the deployment level, I can easily have a different logging strategy for each deployment. I can log to a file in a client application deployment and log through JMS for my enterprise bean deployment. This flexibility also allows me to treat exceptions differently in different contexts.</p>
<div class="section">
<h3 class="sect3-title">
<a name="542"></a><a name="ch17lev2sec1"></a>Sample Strategy</h3>
<ul class="itemizedlist">
<li class="first-listitem">
<p class="first-para">Use <span class="fixed">myapp.util.Logger</span> for all logging. Do not use <span class="fixed">System.out.println()</span>.</p>
</li>
<li class="listitem">
<p class="first-para">Log errors and exceptions in the deployment and presentation layers as well as in the <span class="fixed">run()</span> method of any asynchronously running code.</p>
</li>
<li class="listitem">
<p class="first-para">Warnings (i.e., errors not severe enough to warrant the throwing of an exception but would be useful to a developer fixing bugs) can be logged anywhere from any layer.</p>
</li>
<li class="listitem">
<p class="first-para">When using logging to output debug information, use <span class="fixed">logDebug()</span> so the output can optionally be suppressed.</p>
</li>
<li class="listitem">
<p class="first-para">Do not use the general logging facility as a transaction log.</p>
</li>
</ul>
</div>
</div>
</div><br>
<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="LiB0110.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0112.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr></table>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -