Table of Contents

foreword xv
preface xvii
acknowledgments xxi
about this book xxiii
about the cover illustration xxvii

Part 1 The basics 1

1 Bitter tales 3
1.1 A Java development free fall 4
Antipatterns in life 6
1.2 Using design patterns accentuates the positive 7
Design patterns online 8
UML provides a language for patterns 9
1.3 Antipatterns teach from the negative 9
Some well-known antipatterns 10
Antipatterns in practice 11
Antipattern resources 12
1.4 Antipattern ideas are not new 13
Learning from the industry 14
Detective work 15
Refactoring antipatterns 17
1.5 Why Bitter Java? 17
The Bitter Java approach 18
Bitter Java tools 18
The Bitter Java organization 19
The Bitter Java audience 21
1.6 Looking ahead 21
2 The bitter landscape 23
2.1 Fertile grounds for antipatterns 24
The benefits of layering 24
Layering can work against us 26
2.2 Internet technologies 28
Internet topologies affect our applications 28
Enterprise layers add security and overhead 29
Standards enable the Internet and add layers 31
TCP and IP provide low-level communications 32
HTTP provides application-level transport 33
HTML and XML 34
Mini-antipattern: Too Many Web Page Items 35
2.3 Object technologies and antipatterns 37
Encapsulation helps to isolate change 38
Inheritance enables packaging of common behavior 38
Polymorphism enables flexible reuse 39
Mini-antipatterns: Excessive Layering 39
Setting the stage for Java 42
2.4 Java technologies solve antipatterns 42
2.5 Major problems with the waterfall 44
Iterative methodologies 45
Mini-antipatterns: Incomplete Process Transitions 45
Programming horizons: Extreme programming 46
2.6 A quick survey of the bitter landscape 48
2.7 Antipatterns in this chapter 48

Part 2 Server-side Java antipatterns 51

3 Bitter servlets 53
3.1 Getting off on the wrong foot 54
An early antipattern: The Magic Pushbutton 54
Building with Model-View-Controller 56
Failing to separate model and view 56
Breaking out the model 58
3.2 Antipattern: The Magic Servlet 59
Can we use servlets as the model? 60
Stumbling into the Magic Servlet trap 62
Causes of the Magic Servlet 66
3.3 Solution: Refactor using commands 67
Break out the model 67
Wrapping the model with command objects 68
Separating the model logic 69
Separating the return trip 74
Using a JSP for the return trip 77
3.4 Summary 79
3.5 Antipattern in this chapter 79
4 Bitter JSPs 81
4.1 Getting only halfway home 82
Recognizing the danger signs 82
4.2 Antipattern: Monolithic JSPs 84
This program lacks model-view separation 84
Solution: Refactor to Model-View-Controller 86
4.3 Antipattern: Compound JSPs 88
Should we combine multiple JSPs? 88
An example combining two interfaces 89
Solution: Split the JSP 94
Making decisions in the controller servlet 94
4.4 Mini-antipatterns: Coarse and Fine Commands 98
Too many commands in a group 99
Solution: Refactor to appropriate granularity 99
Tips for granularity 101
4.5 Mini-antipattern: Fat Commands 102
4.6 Reviewing the JSP antipatterns 102
4.7 Antipatterns in this chapter 103
5 Bitter cache management 107
5.1 We need caches! 108
5.2 Antipattern: The Cacheless Cow 109
Bitter BBS with no cache 110
Building the model, view, and controller for ShowBoard 112
Building the model, view, and controller for ShowThread 115
Building the model, view and controller for AddPost 119
Performance problems 125
5.3 Solution: Cache 125
Solution 1: Use a hardware cache 126
Solution 2: Cache commands 126
Adding a cache to our BBS 128
Possible enhancements to cached commands 133
5.4 Cache-related mini-antipatterns 135
Concurrent access to static cache 135
The ever-growing cache 136
5.5 Antipattern: Synchronized Read/Write Bottlenecks 136
Collisions between readers can hurt performance 137
Read/write locks allow correct shared access 138
5.6 Cooking the Cacheless Cow 140
5.7 Antipatterns in this chapter 140
6 Bitter memories 143
6.1 Understanding memory leaks and antipatterns 144
Managing memory 145
Understanding garbage collection 146
Reference counting 146
Reachable objects 148
6.2 Trading C++ for Java 149
Circumstances that cause Java memory leaks 149
Finding Java leaks 150
6.3 Antipattern: Lapsed Listeners Leak 151
Examining some dangerous practices 152
Solution 1: Explicitly remove the listeners 155
Solution 2: Shorten the life cycle of the anchor 155
Solution 3: Weaken the reference 156
Reference objects simplify memory management 156
6.4 Antipattern: The Leak Collection 157
Causing trouble with caches and session state 158
Solution 1: Search for common warning signs 159
Solution 2: Aggressively pair adds with removes 160
Solution 3: Use soft references for caches 160
Solution 4: Use collections with weak references 161
Solution 5: Use finally 161
6.5 Shooting memory leaks 161
Make sure there is a leak 161
Determine that the leak should be fixed 162
Isolate the problem 163
Determine the source and fix the problem 164
Protect against the problem for the future 165
6.6 Mini-Antipatterns: Little Hogs 166
String manipulation 166
Collections 167
Inheritance chains 168
6.7 Summary 168
6.8 Antipatterns in this chapter 169
7 Bitter connections and coupling 171
7.1 Making connections 172
7.2 Antipattern: Connection Thrashing 172
Creating and terminating with every access 174
Solution: Reuse connections with a pool 174
Refactoring our BBS to add pooled connections 177
Using getPooledConnection 179
Using the J2EE connector architecture 180
7.3 Antipattern: Split Cleaners 181
Exceptions can lead to Split Cleaners 183
Solution: Pair connection with cleanup, in finally 184
7.4 Antipattern: Hardwired Connections 185
The communications buffer 186
Premature binding 189
Solution 1: Decouple with XML messages 189
Solution 2: Delay binding with web services 191
7.5 Mini-antipatterns for XML misuse 192
XML?s Golden Hammers 193
XML?s bitter transitions 193
7.6 Mini-antipatterns: Rigid XML 194
Name collisions 195
Rigid constructs 197
Restrictive variable-content containers 199
XML versioning 201
7.7 Summary: Sweetening bitter connections 202
7.8 Antipatterns in this chapter 203
8 Bitter beans 207
8.1 A brief Enterprise JavaBeans review 208
The component-based distributed architecture 208
Types of EJBs 209
8.2 Bitter BBS with EJBs 210
Elements of an EJB application 211
Building the remote interface 213
Creating the home interface 215
Implementing the bean class 216
Defining the primary key 221
Creating a deployment descriptor 222
Using the model 224
8.3 Antipattern: Round-tripping 225
Computing the cost of a distributed deployment 226
Chatty interfaces 227
Solution: Group together round-trips with a facade 228
Roots of round-tripping 229
Refactoring the BBS with a facade 230
8.4 Antipattern: Square Bean in a Round Hole 237
Mini-antipattern: Bean-Managed Joins 237
Solution: Views, mappers, bean-managed joins 238
Mini-antipattern: Entity Beans for Lightweight Functions 238
Mini-antipattern: Entities for Read Only 240
Mini-antipattern: Entity Beans for Write but Not Read 240
Troublesome scrollable lists 240
Overall solution: Pick the right bean for the job 241
8.5 Mini-antipattern: Everything Is an EJB 242
8.6 EJBs and caching 243
Implementing a cache with a facade 243
8.7 Smoothing out the bitter beans 244
8.8 Antipatterns in this chapter 245

Part 3 The big picture 249

9 Bitter hygiene 251
9.1 Why study programming hygiene? 252
Extreme programming requires good hygiene 252
Coding standards protect against antipatterns 253
9.2 Mini-antipatterns: Unreadable code 255
Names matter 255
Standards for names 256
Braces and indentation 260
Comments 261
Tabs vs. spaces 264
Editors 265
9.3 Mini-antipatterns: Organization and visibility 266
9.4 Mini-antipatterns: Structure 269
Basic object-oriented philosophy 270
Low-level design considerations 270
Exceptions 272
9.5 Mini-antipatterns: Leaks and performance 273
9.6 Conventions for testing 274
9.7 Building a good style guide 276
Buy, borrow, or steal? 276
A sample style guide from Contextual, Inc. 277
9.8 Summary of coding standards 280
10 Bitter scalability 283
10.1 Good topologies for performance 284
Layering hardware in homogeneous groups 286
Other topology variations 289
10.2 Antipattern: Performance Afterthoughts 289
Developing without performance planning 290
Some real-world examples 291
Solution: Plan for performance! 292
10.3 Antipattern: Round-tripping 295
Solution: Cache and Facade 295
10.4 Antipattern: Bad Workload Management 298
Solution: Workload Management 299
True load balancing 301
10.5 Antipattern: Chaotic Session Management 302
Solution 1: Dispatching with session affinity 302
Solution 2: Using a distributed state management service 303
Using custom session bean solutions 303
Using custom entity bean solutions 304
10.6 Antipattern: Thrash-tuning 304
Solution: Use sound performance methodologies 305
10.7 Taming the performance beast 307
10.8 Antipatterns in this chapter 307
11 Sweet parting thoughts 311
11.1 Antipatterns help us on many levels 312
Antipatterns ignite careers 313
Understanding antipatterns improves programs 313
Understanding antipatterns makes you a better programmer 314
11.2 Integrating antipatterns with process 315
11.3 Next steps, last steps 317
A Cross-references of antipatterns 319

 
 
bibliography 329
index 333