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