Object-Oriented Software Design in C++

Book description

Learn the fundamentals of Object-Oriented design by investigating good—and bad—code!

Well-designed applications run more efficiently, have fewer bugs, and are easier to revise and maintain. Using an engaging “before-and-after” approach, Object-Oriented Software Design in C++ shows you exactly what bad software looks like and how to fix it with good design principles and patterns.

In Object-Oriented Software Design in C++, you’ll find:

  • Design-code-test iterations that improve code with each revision
  • Gathering requirements to make sure you’re developing the right application
  • Design principles like encapsulation and delegation that solve programming problems
  • Design patterns including Observer Design Pattern that fix architecture issues
  • Using recursion and multithreading to simplify common solutions

Object-Oriented Software Design in C++ is a vital guide to building the kind of high performance applications delivered by the pros—all using industry-proven design principles and patterns. You’ll learn how to gather and analyze requirements so you’re building exactly what your client is looking for, backtrack mistakes with iterative development, and build a toolbox of design patterns that troubleshoot common issues with application architecture. The book’s accessible examples are written in C++ 17, but its universal principles can be applied to any object-oriented language.

About the Technology
Good design is the foundation of great software. Mastering the principles of object-oriented design is the surest way to create applications that run fast, have few bugs, and last well into the future. Written especially for new C++ programmers, this easy-to-read book gently mentors you in the art of designing great software.

About the Book
Object-Oriented Software Design in C++ introduces object-oriented design principles, practices, and patterns in clear, jargon-free language. The instantly-familiar before-and-after examples highlight the benefits of good design. Each chapter is full of friendly conversations that anticipate your questions and help point out the subtleties you might overlook. Along the way, you’ll pick up tips about idiomatic C++ style that will set your code apart.

What's Inside
  • Design-code-test iterations
  • Design principles for common programming problems
  • Architecture design patterns in plain English
  • Recursion and multithreading


About the Reader
Examples are in C++ 17.

About the Author
Ronald Mak is a former NASA senior scientist. Currently, he teaches computer science at San Jose State University.

The technical editor on this book was Juan Rufes.

Quotes
It is a joy to see these timeless and pragmatic lessons! If you have basic C++ knowledge, you will become a better programmer by mastering these principles and patterns of object-oriented design.
- Cay Horstmann, author of Core Java and Big C++

Ron Mak has mentored many, many students and through this book you can benefit from his knowledge and experience.
- Dan Harkey, Director of Software Engineering, San Jose State University

Elevate your software design skills with this exceptional guide. A brilliantly crafted masterpiece that goes deep into the art of designing software.
- Eros Pedrini, NTT Data

Table of contents

  1. Object-Oriented Software Design in C++
  2. Copyright
  3. contents
  4. front matter
    1. preface
      1. Experience is the best teacher
    2. acknowledgments
    3. about this book
      1. Who should read this book?
      2. How this book is organized: A roadmap
      3. About the code
      4. liveBook discussion forum
    4. about the author
    5. about the cover illustration
  5. Part 1. Introduction
  6. 1 The path to well-designed software
    1. 1.1 What is software design?
    2. 1.2 What you will learn from this book
    3. 1.3 The benefits of good software design
    4. 1.4 A few design examples
      1. 1.4.1 Leaking changes
      2. 1.4.2 Code that’s too complex
      3. 1.4.3 Inflexible code
      4. 1.4.4 Surprise!
      5. 1.4.5 Common architecture problems
    5. 1.5 Make sure we’re going to build the right application; then, build it right
    6. 1.6 Good design doesn’t come easily
    7. 1.7 Change and complexity are the enemies of good design
    8. 1.8 Design with object-oriented programming concepts
    9. Summary
  7. 2 Iterate to achieve good design
    1. 2.1 Good application design requires an iterative process
    2. 2.2 Don’t let changes leak out
    3. 2.3 Iterate to achieve good design
      1. 2.3.1 Iteration 1: Initial cohesive classes
      2. 2.3.2 Iteration 2: Encapsulation, delegation, and loose coupling
      3. 2.3.3 Iteration 3: More kinds of books and their attributes
      4. 2.3.4 Iteration 4: A better design after backtracking
    4. Summary
  8. Part 2. Design the right application
  9. 3 Get requirements to build the right application
    1. 3.1 The overture to application design
    2. 3.2 Functional requirements: What must the application do?
    3. 3.3 Nonfunctional requirements: Constraints on the application
    4. 3.4 What are good requirements?
    5. 3.5 How to get requirements
      1. 3.5.1 A short requirements case study
      2. 3.5.2 Stated and implied requirements
    6. 3.6 Unified Modeling Language diagrams for creating and documenting design
    7. 3.7 Use cases provide context for the requirements
      1. 3.7.1 UML use case diagram
      2. 3.7.2 Use case description
    8. 3.8 The functional specification and software validation
    9. 3.9 Where do classes come from?
      1. 3.9.1 Textual analysis: Nouns can become classes
      2. 3.9.2 Textual analysis: Verbs can become member functions
    10. Summary
  10. 4 Good class design to build the application right
    1. 4.1 When do we do application design?
    2. 4.2 Two important goals for good class design
      1. 4.2.1 Cohesion and the Single Responsibility Principle
      2. 4.2.2 Loose coupling and the Principle of Least Knowledge
    3. 4.3 UML class diagrams to document class design
    4. 4.4 Class relationships determine runtime interactions
      1. 4.4.1 Dependency: The most basic relationship
      2. 4.4.2 Aggregation and composition: Objects that contain other objects
      3. 4.4.3 Generalization: Superclasses and their subclasses
      4. 4.4.4 Abstract classes and interfaces: What subclasses must implement
    5. 4.5 UML state diagram: How an object changes state
    6. 4.6 UML sequence diagram: How objects interact [optional]
    7. 4.7 The design specification and software verification
    8. Summary
  11. Part 3. Design the application right
  12. 5 Hide class implementations
    1. 5.1 The Principle of Least Knowledge and hidden implementations
    2. 5.2 Public getter and setter functions access hidden implementation selectively
    3. 5.3 Class Date: An example of implementation hiding
      1. 5.3.1 Iteration 1: Date arithmetic with loops
      2. 5.3.2 Iteration 2: Julian day numbers simplify date arithmetic
      3. 5.3.3 Iteration 3: A hybrid approach with lazy evaluation
    4. 5.4 Public setter functions carefully modify hidden implementation
    5. 5.5 Beware of dangerous setter functions
    6. 5.6 Rules from the Law of Demeter
    7. 5.7 But is the implementation really hidden?
    8. 5.8 The Open-Closed Principle supports code stability
    9. Summary
  13. 6 Don’t surprise your users
    1. 6.1 No surprises and the Principle of Least Astonishment
      1. 6.1.1 Off-by-one errors
      2. 6.1.2 Misnamed functions can mislead their callers
    2. 6.2 Poor performance is an unwelcome surprise
      1. 6.2.1 Bad design can cause unexpected performance problems
      2. 6.2.2 The vexatious performance of C++ vectors
    3. 6.3 Programming by Contract helps to eliminate surprises [optional]
      1. 6.3.1 Programming a circular buffer by contract
      2. 6.3.2 Precondition: What must be true before calling a function
      3. 6.3.3 Postcondition: What must be true after returning from a function
      4. 6.3.4 Class invariant: What must remain true of object states
    4. Summary
  14. 7 Design subclasses right
    1. 7.1 When to use function overriding or overloading
      1. 7.1.1 Override superclass member functions to get subclass behavior
      2. 7.1.2 Overload functions that have similar or equivalent behaviors
    2. 7.2 The Liskov Substitution Principle and proper subclasses
    3. 7.3 Choosing the is-a and has-a relationships
    4. 7.4 Use a factory function with the Code to the Interface Principle
    5. 7.5 Programming by Contract with subclasses [optional]
    6. Summary
  15. Part 4. Design patterns solve application architecture problems
    1. The benefits of design patterns
    2. Explaining the design patterns
    3. The sports examples
  16. 8 The Template Method and Strategy Design Patterns
    1. 8.1 The Template Method Design Pattern defines the steps of an algorithm
      1. 8.1.1 Desired design features
      2. 8.1.2 Before using the Template Method Design Pattern
      3. 8.1.3 After using the Template Method Design Pattern
      4. 8.1.4 Template Method’s generic model
    2. 8.2 The Strategy Design Pattern encapsulates algorithms
      1. 8.2.1 Desired design features
      2. 8.2.2 Before using the Strategy Design Pattern
      3. 8.2.3 After using the Strategy Design Pattern
      4. 8.2.4 Strategy’s generic model
    3. 8.3 Choose between Template Method and Strategy
    4. Summary
  17. 9 The Factory Method and Abstract Factory Design Patterns
    1. 9.1 The Factory Method Design Pattern lets subclasses create objects
      1. 9.1.1 Desired design features
      2. 9.1.2 Before using the Factory Method Design Pattern
      3. 9.1.3 After using the Factory Method Design Pattern
      4. 9.1.4 Factory Method’s generic model
    2. 9.2 The Abstract Factory Design Pattern creates families of objects
      1. 9.2.1 Before using the Abstract Factory Design Pattern
      2. 9.2.2 After using the Abstract Factory Design Pattern
      3. 9.2.3 Abstract Factory’s generic model
    3. Summary
  18. 10 The Adapter and Façade Design Patterns
    1. 10.1 The Adapter Design Pattern integrates code
      1. 10.1.1 Desired design features
      2. 10.1.2 Before using the Adapter Design Pattern
      3. 10.1.3 After using the Adapter Design Pattern
      4. 10.1.4 Adapter’s generic model
      5. 10.1.5 An alternative Adapter Design Pattern model
    2. 10.2 The Façade Design Pattern hides a subsystem of interfaces
      1. 10.2.1 Desired design features
      2. 10.2.2 Before using the Façade Design Pattern
      3. 10.2.3 After using the Façade Design Pattern
      4. 10.2.4 Façade’s generic model
    3. Summary
  19. 11 The Iterator and Visitor Design Patterns
    1. 11.1 The Iterator Design Pattern encapsulates iterating over different sequential collections
      1. 11.1.1 Desired design features
      2. 11.1.2 Before using the Iterator Design Pattern
      3. 11.1.3 After using the Iterator Design Pattern
      4. 11.1.4 Iterator’s generic model
    2. 11.2 The Visitor Design Pattern encapsulates different algorithms that operate on a data collection
      1. 11.2.1 Desired design features
      2. 11.2.2 Before using the Visitor Design Pattern
    3. 11.3 After using the Visitor Design Pattern
      1. 11.3.1 Visitor’s generic model
    4. Summary
  20. 12 The Observer Design Pattern
    1. 12.1 The Observer Design Pattern represents the publisher–subscriber model
      1. 12.1.1 Desired design features
      2. 12.1.2 Before using the Observer Design Pattern
      3. 12.1.3 After using the Observer Design Pattern
      4. 12.1.4 The Observer’s generic model
    2. Summary
  21. 13 The State Design Pattern
    1. 13.1 The State Design Pattern models state transitions
      1. 13.1.1 Desired design features
      2. 13.1.2 Before using the State Design Pattern
      3. 13.1.3 After using the State Design Pattern
      4. 13.1.4 State’s generic model
    2. Summary
  22. 14 The Singleton, Composite, and Decorator Design Patterns
    1. 14.1 The Singleton Design Pattern ensures a class has only one object
      1. 14.1.1 Desired design features
      2. 14.1.2 Before using the Singleton Design Pattern
      3. 14.1.3 After using the Singleton Design Pattern
      4. 14.1.4 Singleton’s generic model
    2. 14.2 The Composite Design Pattern treats individual and composite objects uniformly
      1. 14.2.1 Desired design features
      2. 14.2.2 Before using the Composite Design Pattern
      3. 14.2.3 After using the Composite Design Pattern
      4. 14.2.4 Composite’s generic model
    3. 14.3 The Decorator Design Pattern dynamically adds object responsibilities
      1. 14.3.1 Desired design features
      2. 14.3.2 Before using the Decorator Design Pattern
      3. 14.3.3 After using the Decorator Design Pattern
      4. 14.3.4 Decorator’s generic model
    4. Summary
  23. Part 5. Additional Design Techniques
  24. 15 Designing solutions with recursion and backtracking
    1. 15.1 Recursion compared to the for loop
    2. 15.2 Finding the largest value by recursion
    3. 15.3 Reversing a vector by recursion
    4. 15.4 Solve the Towers of Hanoi puzzle by recursion
    5. 15.5 Recursive algorithms for a binary search tree
      1. 15.5.1 Inserting into a BST with recursion
      2. 15.5.2 Printing a BST with recursion
      3. 15.5.3 Removing all the nodes of a BST with recursion
    6. 15.6 Quicksort an array with recursion
      1. 15.6.1 Quicksort in action
      2. 15.6.2 Partitioning an array into subarrays
      3. 15.6.3 Quicksort implementation
    7. 15.7 The Fibonacci sequence and a recursion disaster
    8. 15.8 Dynamic backtracking increases the power of recursion
    9. 15.9 Solving the eight queens puzzle with recursion and backtracking
    10. 15.10 Solving Sudoku puzzles with recursion and backtracking
    11. Summary
  25. 16 Designing multithreaded programs
    1. 16.1 How do things happen simultaneously?
    2. 16.2 A mutex enforces mutual exclusion
      1. 16.2.1 Protect the integrity of a shared resource
      2. 16.2.2 The classic reader–writer problem
    3. 16.3 Condition variables synchronize threads
      1. 16.3.1 How condition variables synchronize threads
      2. 16.3.2 The classic producer–consumer problem
    4. 16.4 A final note on multithreading
    5. Summary
  26. index

Product information

  • Title: Object-Oriented Software Design in C++
  • Author(s): Ron Mak
  • Release date: June 2024
  • Publisher(s): Manning Publications
  • ISBN: 9781633439504