Author Holger Gast focuses on the concepts that have repeatedly proven most valuable and shows how to render those concepts in concrete code. Rather than settling for minimal examples, he explores crucial intricacies, clarifies easily misunderstood ideas, and helps you avoid subtle errors that could have disastrous consequences.
Gast addresses the technical aspects of working with languages, libraries, and frameworks, as well as the strategic decisions associated with patterns, contracts, design, and system architecture. He explains the roles of individual objects in a complete application, how they react to events and fulfill service requests, and how to transform excellent designs into excellent code. Using practical examples based on Eclipse, he also shows how tools can help you work more efficiently, save you time, and sometimes even write high-quality code for you.
Gast writes for developers who have at least basic experience: those who’ve finished an introductory programming course, a university computer science curriculum, or a first or second job assignment.
Coverage includes
• Understanding what a professionally designed object really looks like
• Writing code that reflects your true intentions and testing to make sure it does
• Applying language idioms and connotations to write more readable and maintainable code
• Using design-by-contract to write code that consistently does what it’s supposed to do
• Coding and architecting effective event-driven software
• Separating model and view, and avoiding common mistakes
• Mastering strategies and patterns for efficient, flexible design
• Ensuring predictable object collaboration via responsibility-driven design
Data Structures
1.3.2 Collaborators
1.3.3 Properties
1.3.4 Flags and Configuration
1.3.5 Abstract State
1.3.6 Caches
1.3.7 Data Shared Between Methods
1.3.8 Static Fields
1.4 Methods
1.4.1 An Object-Oriented View on Methods
1.4.2 Method Overloading
1.4.3 Service Provider
1.4.4 Convenience Method
1.4.5 Processing Step
1.4.6 Explanatory Methods
1.4.7 Events and Callbacks
1.4.8 Reused Functionality
1.4.9 Template Method
1.4.10 Delegated to Subclass
1.4.11 Extending Inherited Behavior
1.4.12 Factory Methods
1.4.13 Identity, Equality, and Hashing
1.4.14 Refused Bequest
1.5 Exceptions
1.5.1 Basic Usage
1.5.2 Exceptions and the System Boundary
1.5.3 Exceptions to Clarify the Program Logic
1.5.4 Exceptions for Checking Expectations
1.5.5 Exceptions to Signal Incompleteness
1.5.6 Exception Safety
1.5.7 Checked Versus Unchecked Exceptions
1.6 Constructors
1.6.1 Initializing Objects
1.6.2 Initialization by Life-Cycle Methods
1.6.3 Constructors and Inheritance
1.6.4 Copying Objects
1.6.5 Static Constructor Methods
1.7 Packages
1.7.1 Packages as Components
1.7.2 The Facade Pattern
1.8 Basics of Using Classes and Objects
1.8.1 General Facets of Objects
1.8.2 Service Provider
1.8.3 Information Holder
1.8.4 Value Object
1.8.5 Reusable Functionality
1.8.6 Algorithms and Temporary Data
1.8.7 Boundary Objects
1.8.8 Nested Classes
1.8.9 The null Object
Chapter 2 Fundamental Object Structures
2.1 Propagating State Changes: Observer
2.1.1 Example: Observing Background Jobs
2.1.2 Crucial Design and Implementation Constraints
2.1.3 Implementation Details and Decisions
2.1.4 Judging the Need for Observers
2.2 Compound Objects
2.2.1 Ownership
2.2.2 Structure Sharing
2.2.3 Compound Objects and Encapsulation
2.2.4 Compound Objects and Observers
2.3 Hierarchical Structures
2.3.1 The Composite Pattern
2.3.2 The Visitor Pattern
2.3.3 Objects as Languages: Interpreter
2.3.4 Excursion: Composites and Stack Machines
2.4 Wrappers: Adapters, Proxies, and Decorators
2.4.1 The Adapter Pattern
2.4.2 The Decorator Pattern
2.4.3 The Proxy Pattern
2.4.4 Encapsulation Wrappers
Chapter 3 Abstraction and Hierarchy
3.1 Inheritance
3.1.1 The Liskov Substitution Principle
3.1.2 Interface Between the Base Class and Subclasses
3.1.3 Factoring Out Common Behavior
3.1.4 Base Classes for Reusable Infrastructure
3.1.5 Base Classes for Abstraction
3.1.6 Reifying Case Distinctions
3.1.7 Adapting Behavior
3.1.8 Inheritance Versus Delegation
3.1.9 Downcasts and instanceof
3.1.10 Implementation Inheritance
3.1.11 The Fragile Base Class Problem
3.2 Interfaces
3.2.1 Behavioral Abstraction
3.2.2 Client-Specific Classification and Abstraction
3.2.3 Abstraction Hierarchies
3.2.4 Multiple Classification
3.2.5 Extension Interface
3.2.6 Specifying Callbacks
3.2.7 Decoupling Subsystems
3.2.8 Tagging Interfaces
3.2.9 Management of Constants
3.2.10 Inheritance Versus Interfaces
Part II Contracts
Chapter 4 Contracts for Objects
4.1 The Core: Assertions Plus Encapsulation
4.2 Elaborating the Concepts by Example
4.2.1 Invariants and Model Fields
4.2.2 Contracts in Terms of Model Fields
4.2.3 Contracts, Invariants, and Processing Steps
4.2.4 The Role of Constructors
4.2.5 Pure Methods for Specification
4.2.6 Frame Conditions: Taming Side Effects
4.3 Motivating Contracts with Hindsight
4.4 Invariants and Callbacks
4.5 Checking Assertions at Runtime
4.6 The System Boundary
4.7 Arguing About the Correctness of Programs
4.7.1 Assignment
4.7.2 Loops: Summing over an Array
4.7.3 Conditionals and Loops: Binary Search
4.7.4 Outlook
Chapter 5 Testing
5.1 The Core: Unit Testing
5.2 The Test First Principle
5.3 Writing and Running Unit Tests
5.3.1 Basic Testing Guidelines
5.3.2 Creating Fixtures
5.3.3 Dependency Injection
5.3.4 Testing OSGi Bundles
5.3.5 Testing the User Interface
5.4 Applications and Motivations for Testing
5.4.1 Testing to Fix Bugs
5.4.2 Testing to Capture the Contracts
5.4.3 Testing to Design the Interface
5.4.4 Testing to Find and Document the Requirements
5.4.5 Testing to Drive the Design
5.4.6 Testing to Document Progress
5.4.7 Testing for Safety
5.4.8 Testing to Enable Change
5.4.9 Testing to Understand an API
5.4.10 Testing for a Better Work–Life Balance
Chapter 6 Fine Print in Contracts
6.1 Design-by-Contract
6.1.1 Contracts First
6.1.2 Weaker and Stronger Assertions
6.1.3 Tolerant and Demanding Style
6.1.4 Practical Examples of Demanding Style
6.1.5 Stronger and Weaker Class Invariants
6.2 Contracts and Compound Objects
6.2.1 Basics
6.2.2 Ownership and Invariants
6.2.3 Invariants on Shared Objects
6.3 Exceptions and Contracts
6.4 Inheritance and Subtyping
6.4.1 Contracts of Overridden Methods
6.4.2 Invariants and Inheritance
Part III Events
Chapter 7 Introduction to the Standard Widget Toolkit
7.1 The Core: Widgets, Layouts, and Events
7.2 The WindowBuilder: A Graphical Editor for UIs
7.2.1 Overview
7.2.2 Creating and Launching SWT Applications
7.3 Developing with Frameworks
7.3.1 The Goals of Frameworks
7.3.2 Inversion of Control
7.3.3 Adaptation Points in Frameworks
7.3.4 Liabilities of Frameworks
7.4 SWT and the Native Interface
7.4.1 Influence on the API
7.4.2 Influence on Launching Applications
7.5 Compound Widgets
7.6 Dialogs
7.7 Mediator Pattern
7.8 Custom Painting for Widgets
7.9 Timers
7.9.1 Timeouts and Delays
7.9.2 Animations
7.10 Background Jobs
7.10.1 Threads and the User Interface
7.10.2 Long-Running Tasks
7.10.3 Periodic Jobs
7.11 Review: Events and Contracts
Chapter 8 A Brief Introduction to Threads
8.1 The Core: Parallel Code Execution
8.2 Correctness in the Presence of Threads
8.3 Notifications Between Threads
8.4 Asynchronous Messages
8.5 Open Calls for Notification
8.6 Deadlocks
Chapter 9 Structuring Applications with Graphical Interfaces
9.1 The Core: Model-View Separation
9.2 The Model-View-Controller Pattern
9.2.1 The Basic Pattern
9.2.2 Benefits of the Model-View-Controller Pattern
9.2.3 Crucial Design and Implementation Constraints
9.2.4 Common Misconceptions
9.2.5 Behavior at the User Interface Level
9.2.6 Controllers Observing the Model
9.2.7 Pluggable Controllers
9.2.8 The Document-View Variant
9.3 The JFace Layer
9.3.1 Viewers
9.3.2 Finishing Model-View-Controller with JFace
9.3.3 Data Binding
9.3.4 Menus and Actions
9.4 The MVC Pattern at the Application Level
9.4.1 Setting up the Application
9.4.2 Defining the Model
9.4.3 Incremental Screen Updates
9.4.4 View-Level Logic
9.5 Undo/Redo
9.5.1 The Command Pattern
9.5.2 The Command Processor Pattern
9.5.3 The Effort of Undo/Redo
9.5.4 Undo/Redo in the Real World
9.6 Wrapping Up
Chapter 10 State Machines
10.1 The Core: An Object’s State and Reactions
10.2 State Machines in Real-World Scenarios
10.2.1 Additional Fundamental Elements
10.2.2 Ongoing Activities
10.2.3 Nested State Machines
10.3 Implementing Finite State Machines
10.3.1 Running Example: Line Editor
10.3.2 States-as-Assertions
10.3.3 Explicit States
10.3.4 State Pattern
Part IV Responsibility-Driven Design
Chapter 11 Responsibility-Driven Design
11.1 The Core: Networks of Collaborating Objects
11.2 The Single Responsibility Principle
11.2.1 The Idea
11.2.2 The SRP and Abstraction
11.2.3 The SRP and Changeability
11.3 Exploring Objects and Responsibilities
11.3.1 Example: A Function Plotter
11.3.2 CRC Cards
11.3.3 Identifying Objects and Their Responsibilities
11.3.4 Summing Up
11.4 Responsibilities and Hierarchy
11.5 Fundamental Goals and Strategies
11.5.1 Information Hiding and Encapsulation
11.5.2 Separation of Concerns
11.5.3 Compositionality
11.5.4 Design-Code Traceability
11.5.5 DRY
11.5.6 The SOLID Principles
Chapter 12 Design Strategies
12.1 Coupling and Cohesion
Eclipse Extension Mechanism
12.3.4 Pipes and Filters
12.4 Reusability
12.4.1 The Challenge of Reusability
12.4.2 The Case of the Wizard Dialogs in JFace
12.4.3 Building a Reusable Parser
12.4.4 Strategies for Reuse
Part V Appendix
Appendix A Working with Eclipse Plugins
A.1 OSGi: A Module System for Java
A.1.1 The Structure of OSGi Bundles
A.1.2 Working with Bundles in Eclipse
A.1.3 OSGi as an Application Platform
A.1.4 Defining Target Platforms
A.2 Launching Plugins
A.2.1 JUnit Plugin Tests
A.2.2 Contributions to the Eclipse IDE
A.2.3 Eclipse Applications
A.2.4 Installing Plugins in the Workspace
A.2.5 Java Programs
A.3 Where to Go from Here
No comments:
Post a Comment