Practical Design Patterns for Java Developers

Book description

Unravel the power of Java design patterns by learning where to apply them effectively to solve specific software design and development problems

Key Features

  • Decouple logic across objects with dependency injection by creating various vehicles with features
  • Finalize vehicle construction by chaining handlers using the Chain of Responsibility Pattern
  • Plan and execute an advanced vehicle sensor initiation with the Scheduler Pattern

Book Description

Design patterns are proven solutions to standard problems in software design and development, allowing you to create reusable, flexible, and maintainable code. This book enables you to upskill by understanding popular patterns to evolve into a proficient software developer.

You’ll start by exploring the Java platform to understand and implement design patterns. Then, using various examples, you’ll create different types of vehicles or their parts to enable clarity in design pattern thinking, along with developing new vehicle instances using dedicated design patterns to make the process consistent. As you progress, you’ll find out how to extend vehicle functionalities and keep the code base structure and behavior clean and shiny. Concurrency plays an important role in application design, and you'll learn how to employ a such design patterns with the visualization of thread interaction. The concluding chapters will help you identify and understand anti-pattern utilization in the early stages of development to address refactoring smoothly. The book covers the use of Java 17+ features such as pattern matching, switch cases, and instances of enhancements to enable productivity.

By the end of this book, you’ll have gained practical knowledge of design patterns in Java and be able to apply them to address common design problems.

What you will learn

  • Understand the most common problems that can be solved using Java design patterns
  • Uncover Java building elements, their usages, and concurrency possibilities
  • Optimize a vehicle memory footprint with the Flyweight Pattern
  • Explore one-to-many relations between instances with the observer pattern
  • Discover how to route vehicle messages by using the visitor pattern
  • Utilize and control vehicle resources with the thread-pool pattern
  • Understand the penalties caused by anti-patterns in software design

Who this book is for

If you are an intermediate-level Java developer or software architect looking to learn the practical implementation of software design patterns in Java, then this book is for you. No prior knowledge of design patterns is required, but an understanding of Java programming is necessary.

Table of contents

  1. Practical Design Patterns for Java Developers
  2. Foreword
  3. Contributors
  4. About the author
  5. About the reviewer
  6. Preface
    1. Who this book is for
    2. What this book covers
    3. To get the most out of this book
    4. Download the example code files
    5. Download the color images
    6. Conventions used
    7. Get in touch
    8. Share Your Thoughts
    9. Download a free PDF copy of this book
  7. Part 1: Design Patterns and Java Platform Functionalities
  8. Chapter 1: Getting into Software Design Patterns
    1. Technical requirements
    2. Code – from symbols to program
    3. Examining OOP and APIE
      1. Only exposing what’s required – encapsulation
      2. Inevitable evolution – inheritance
      3. Behavior on demand – polymorphism
      4. Standard features – abstraction
      5. Gluing parts to APIE
    4. Understanding the SOLID design principles
      1. The single-responsibility principle (SRP) – the engine is just an engine
      2. The open-closed principle (OCP)
      3. The Liskov Substitution Principle (LSP) – substitutability of classes
      4. The interface segregation principle (ISP)
      5. The dependency inversion principle (DIP)
    5. Significance of design patterns
    6. Reviewing what challenges design patterns solve
    7. Summary
    8. Questions
    9. Further reading
  9. Chapter 2: Discovering the Java Platform for Design Patterns
    1. Technical requirements
    2. Knocking on Java’s door
    3. Exploring the model and functionality of the Java platform
      1. The JDK
      2. The JRE
      3. The JVM
    4. Reviewing GC and the Java memory model
      1. The JMM
      2. GC and automatic memory management
    5. Examining the core Java APIs
      1. Primitive data types and wrappers
      2. Working with the String API
      3. Introducing arrays
      4. Discovering a collection framework
      5. Math APIs
    6. Functional programming and Java
      1. Introducing lambdas and functional interfaces
      2. Using functional interfaces in lambda expressions
    7. Getting to grips with the Java Module System
    8. A quick review of Java features from 11 to 17+
      1. The local variable syntax for lambda parameters (Java SE 11, JEP-323)
      2. Switch expressions (Java SE 14, JEP-361)
      3. Text blocks (Java SE 15, JEP-378)
      4. Pattern matching for instanceof (Java SE 16, JEP-394)
      5. Records (Java SE 16, JEP-395)
      6. Sealed classes (Java SE 17, JEP-409)
      7. UTF-8 by default (Java SE 18, JEP-400)
      8. Pattern matching for switch (Java SE 18, Second Preview, JEP-420)
    9. Understanding Java concurrency
      1. From a basic thread to executors
      2. Executing tasks
    10. Summary
    11. Questions
    12. Further reading
  10. Part 2: Implementing Standard Design Patterns Using Java Programming
  11. Chapter 3: Working with Creational Design Patterns
    1. Technical requirements
    2. It all starts with a class that becomes an object
    3. Creating objects based on input with the factory method pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    4. Creating objects from different families using the abstract factory pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    5. Instantiating complex objects with the builder pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    6. Cloning objects with the prototype pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    7. Ensuring only one instance with the singleton pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    8. Improving performance with the object pool pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    9. Initiating objects on demand with the lazy initialization pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    10. Reducing class dependencies with the dependency injection pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    11. Summary
    12. Questions
    13. Further reading
  12. Chapter 4: Applying Structural Design Patterns
    1. Technical requirements
    2. Incompatible object collaboration with the adapter pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    3. Decoupling and developing objects independently with the bridge pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    4. Treating objects the same way using the composite pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    5. Extending object functionality by using the decorator pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    6. Simplifying communication with the facade pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    7. Using conditions to select desired objects with the filter pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    8. Sharing objects across an application with the flyweight pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    9. Handling requests with the front-controller pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    10. Identifying instances using the marker pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    11. Exploring the concept of modules with the module pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    12. Providing a placeholder for an object using the proxy pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    13. Discovering multiple inheritance in Java with the twin pattern
      1. Motivation
      2. Sample code
      3. Conclusion
    14. Summary
    15. Questions
    16. Further reading
  13. Chapter 5: Behavioral Design Patterns
    1. Technical requirements
    2. Limiting expensive initialization using the caching pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    3. Handling events using the chain of responsibility pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    4. Turning information into action with the command pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    5. Giving meaning to the context using the interpreter pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    6. Checking all the elements with the iterator pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    7. Utilizing the mediator pattern for information exchange
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    8. Restoring the desired state with the memento pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    9. Avoiding a null pointer exception state with the null object pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    10. Keeping all interested parties informed using the observer pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    11. Dealing with instance stages by using the pipeline pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    12. Changing object behavior with the state pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    13. Using the strategy pattern to change object behavior
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    14. Standardizing processes with the template pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    15. Executing code based on the object type using the visitor pattern
      1. Motivation
      2. Finding it in the JDK
      3. Sample code
      4. Conclusion
    16. Summary
    17. Questions
    18. Further reading
  14. Part 3: Other Essential Patterns and Anti-Patterns
  15. Chapter 6: Concurrency Design Patterns
    1. Technical requirements
    2. Decoupling a method execution with an active object pattern
      1. Motivation
      2. Sample code
      3. Conclusion
    3. Non-blocking tasks using async method invocation pattern
      1. Motivation
      2. Sample code
      3. Conclusion
    4. Delay execution until the previous task is completed with the balking pattern
      1. Motivation
      2. Sample code
      3. Conclusion
    5. Providing a unique object instance with a double-checked locking pattern
      1. Motivation
      2. Sample code
      3. Conclusion
    6. Using purposeful thread blocking via a read-write lock pattern
      1. Motivation
      2. Sample code
      3. Conclusion
    7. Decoupling the execution logic with a producer-consumer pattern
      1. Motivation
      2. Sample code
      3. Conclusion
    8. Executing isolated tasks with the scheduler pattern
      1. Motivation
      2. Sample code
      3. Conclusion
    9. Effective thread utilization using a thread-pool pattern
      1. Motivation
      2. Sample code
      3. Conclusion
    10. Summary
    11. Questions
    12. Further reading
    13. Answers
  16. Chapter 7: Understanding Common Anti-Patterns
    1. Technical requirements
    2. What anti-patterns are and how to identify them
      1. Theoretical principles challenges
      2. Collecting technical debt as a bottleneck
      3. Inappropriately squeezing the capabilities of the Java platform
      4. Selecting the right tool
      5. Conclusion of the code smell anti-pattern
    3. Examining typical software anti-patterns
      1. Spaghetti code
      2. Cut and paste programming
      3. Blob
      4. Lava flow
      5. Functional decomposition
      6. Boat anchor
      7. Conclusion
    4. Understanding software architecture anti-patterns
      1. Golden hammer
      2. Continuous obsolescence
      3. Input kludge
      4. Working in a minefield
      5. Ambiguous viewpoint
      6. Poltergeists
      7. Dead end
      8. Conclusion
    5. Summary
    6. Further reading
  17. Assessments
    1. Chapter 1 – Getting into Software Design Patterns
    2. Chapter 2 – Discovering the Java Platform for Design Patterns
    3. Chapter 3 – Working with Creational Design Patterns
    4. Chapter 4 – Applying Structural Design Patterns
    5. Chapter 5 – Behavioral Design Patterns
    6. Chapter 6 – Concurrency Design Patterns
  18. Index
    1. Why subscribe?
  19. Other Books You May Enjoy
    1. Packt is searching for authors like you
    2. Share Your Thoughts
    3. Download a free PDF copy of this book

Product information

  • Title: Practical Design Patterns for Java Developers
  • Author(s): Miroslav Wengner
  • Release date: February 2023
  • Publisher(s): Packt Publishing
  • ISBN: 9781804614679