
Patterns, Principles, and Practices of Domain-Driven Design
Description
Alles über E-Books | Antworten auf Fragen rund um E-Books, Kopierschutz und Dateiformate finden Sie in unserem Info- & Hilfebereich.
More details
Other editions
Additional editions

Persons
Content
- Cover
- Title Page
- Copyright
- About the Author
- Credits
- Acknowledgments
- Contents
- Introduction
- Part I: The Principles and Practices of Domain-Driven Design
- Chapter 1: What is Domain-Driven Design?
- The Challenges of Creating Software for Complex Problem Domains
- Code Created Without a Common Language
- A Lack of Organization
- The Ball of Mud Pattern Stifles Development
- A Lack of Focus on the Problem Domain
- How the Patterns of Domain-Driven Design Manage Complexity
- The Strategic Patterns of DDD
- Distilling the Problem Domain to Reveal What Is Important
- Creating a Model to Solve Domain Problems
- Using a Shared Language to Enable Modeling Collaboration
- Isolate Models from Ambiguity and Corruption
- Understanding the Relationships between Contexts
- The Tactical Patterns of DDD
- The Problem Space and the Solution Space
- The Practices and Principles of Domain-Driven Design
- Focusing on the Core Domain
- Learning through Collaboration
- Creating Models through Exploration and Experimentation
- Communication
- Understanding the Applicability of a Model
- Constantly Evolving the Model
- Popular Misconceptions of Domain-Driven Design
- Tactical Patterns Are Key to DDD
- DDD Is a Framework
- DDD Is a Silver Bullet
- The Salient Points
- Chapter 2: Distilling the Problem Domain
- Knowledge Crunching and Collaboration
- Reaching a Shared Understanding through a Shared Language
- The Importance of Domain Knowledge
- The Role of Business Analysts
- An Ongoing Process
- Gaining Domain Insight with Domain Experts
- Domain Experts vs Stakeholders
- Deeper Understanding for the Business
- Engaging with Your Domain Experts
- Patterns for Effective Knowledge Crunching
- Focus on the Most Interesting Conversations
- Start from the Use Cases
- Ask Powerful Questions
- Sketching
- Class Responsibility Collaboration Cards
- Defer the Naming of Concepts in Your Model
- Behavior-Driven Development
- Rapid Prototyping
- Look at Paper-Based Systems
- Look For Existing Models
- Understanding Intent
- Event Storming
- Impact Mapping
- Understanding the Business Model
- Deliberate Discovery
- Model Exploration Whirlpool
- The Salient Points
- Chapter 3: Focusing on the Core Domain
- Why Decompose a Problem Domain?
- How to Capture the Essence of the Problem
- Look Beyond Requirements
- Capture the Domain Vision for a Shared Understanding of What Is Core
- How to Focus on the Core Problem
- Distilling a Problem Domain
- Core Domains
- Treat Your Core Domain as a Product Rather than a Project
- Generic Domains
- Supporting Domains
- How Subdomains Shape a Solution
- Not All Parts of a System will be Well Designed
- Focus on Clean Boundaries over Perfect Models
- The Core Domain Doesn't Always Have to Be Perfect the First Time
- Build Subdomains for Replacement Rather than Reuse
- What if You Have no Core Domain?
- The Salient Points
- Chapter 4: Model-Driven Design
- What Is a Domain Model?
- The Domain versus the Domain Model
- The Analysis Model
- The Code Model
- The Code Model Is the Primary Expression of the Domain Model
- Model-Driven Design
- The Challenges with Upfront Design
- Team Modeling
- Using a Ubiquitous Language to Bind the Analysis to the Code Model
- A Language Will Outlive Your Software
- The Language of the Business
- Translation between the Developers and the Business
- Collaborating on a Ubiquitous Language
- Carving Out a Language by Working with Concrete Examples
- Teach Your Domain Experts to Focus on the Problem and Not Jump to a Solution
- Best Practices for Shaping the Language
- How to Create Effective Domain Models
- Don't Let the Truth Get in the Way of a Good Model
- Model Only What Is Relevant
- Domain Models Are Temporarily Useful
- Be Explicit with Terminology
- Limit Your Abstractions
- Focus Your Code at the Right Level of Abstraction
- Abstract Behavior Not Implementations
- Implement the Model in Code Early and Often
- Don't Stop at the First Good Idea
- When to Apply Model-Driven Design
- If It's Not Worth the Effort Don't Try and Model It
- Focus on the Core Domain
- The Salient Points
- Chapter 5: Domain Model Implementation Patterns
- The Domain Layer
- Domain Model Implementation Patterns
- Domain Model
- Transaction Script
- Table Module
- Active Record
- Anemic Domain Model
- Anemic Domain Model and Functional Programming
- The Salient Points
- Chapter 6: Maintaining the Integrity of Domain Models with Bounded Contexts
- The Challenges of a Single Model
- A Model Can Grow in Complexity
- Multiple Teams Working on a Single Model
- Ambiguity in the Language of the Model
- The Applicability of a Domain Concept
- Integration with Legacy Code or Third Party Code
- Your Domain Model Is not Your Enterprise Model
- Use Bounded Contexts to Divide and Conquer a Large Model
- Defining a Model's Boundary
- Define Boundaries around Language
- Align to Business Capabilities
- Create Contexts around Teams
- Try to Retain Some Communication between Teams
- Context Game
- The Difference between a Subdomain and a Bounded Context
- Implementing Bounded Contexts
- The Salient Points
- Chapter 7: Context Mapping
- A Reality Map
- The Technical Reality
- The Organizational Reality
- Mapping a Relevant Reality
- X Marks the Spot of the Core Domain
- Recognising the Relationships between Bounded Contexts
- Anticorruption Layer
- Shared Kernel
- Open Host Service
- Separate Ways
- Partnership
- An Upstream/Downstream Relationship
- Customer-Supplier
- Conformist
- Communicating the Context Map
- The Strategic Importance of Context Maps
- Retaining Integrity
- The Basis for a Plan of Attack
- Understanding Ownership and Responsibility
- Revealing Areas of Confusion in Business Work Flow
- Identifying Nontechnical Obstacles
- Encourages Good Communication
- Helps On-Board New Starters
- The Salient Points
- Chapter 8: Application Architecture
- Application Architecture
- Separating the Concerns of Your Application
- Abstraction from the Complexities of the Domain
- A Layered Architecture
- Dependency Inversion
- The Domain Layer
- The Application Service Layer
- The Infrastructural Layers
- Communication Across Layers
- Testing in Isolation
- Don't Share Data Schema between Bounded Contexts
- Application Architectures versus Architectures for Bounded Contexts
- Application Services
- Application Logic versus Domain Logic
- Defi ning and Exposing Capabilities
- Business Use Case Coordination
- Application Services Represent Use Cases, Not Create, Read, Update, and Delete
- Domain Layer As an Implementation Detail
- Domain Reporting
- Read Models versus Transactional Models
- Application Clients
- The Salient Points
- Chapter 9: Common Problems for Teams Starting out with Domain-Driven Design
- Overemphasizing the Importance of Tactical Patterns
- Using the Same Architecture for All Bounded Contexts
- Striving for Tactical Pattern Perfection
- Mistaking the Building Blocks for the Value of DDD
- Focusing on Code Rather Than the Principles of DDD
- Missing the Real Value of DDD: Collaboration, Communication, and Context
- Producing a Big Ball of Mud Due to Underestimating the Importance of Context
- Causing Ambiguity and Misinterpretations by Failing to Create a UL
- Designing Technical-Focused Solutions Due to a Lack of Collaboration
- Spending Too Much Time on What's Not Important
- Making Simple Problems Complex
- Applying DDD Principles to a Trivial Domain with Little Business Expectation
- Disregarding CRUD as an Antipattern
- Using the Domain Model Pattern for Every Bounded Context
- Ask Yourself: Is It Worth This Extra Complexity?
- Underestimating the Cost of Applying DDD
- Trying to Succeed Without a Motivated and Focused Team
- Attempting Collaboration When a Domain Expert Is Not Behind the Project
- Learning in a Noniterative Development Methodology
- Applying DDD to Every Problem
- Sacrifi cing Pragmatism for Needless Purity
- Wasted Effort by Seeking Validation
- Always Striving for Beautiful Code
- DDD Is About Providing Value
- The Salient Points
- Chapter 10: Applying the Principles, Practices,and Patterns of DDD
- Selling DDD
- Educating Your Team
- Speaking to Your Business
- Applying the Principles of DDD
- Understand the Vision
- Capture the Required Behaviors
- Distilling the Problem Space
- Focus on What Is Important
- Understand the Reality of the Landscape
- Modeling a Solution
- All Problems Are Not Created Equal
- Engaging with an Expert
- Select a Behavior and Model Around a Concrete Scenario
- Collaborate with the Domain Expert on the Most Interesting Parts
- Evolve UL to Remove Ambiguity
- Throw Away Your First Model, and Your Second
- Implement the Model in Code
- Creating a Domain Model
- Keep the Solution Simple and Your Code Boring
- Carve Out an Area of Safety
- Integrate the Model Early and Often
- Nontechnical Refactoring
- Decompose Your Solution Space
- Rinse and Repeat
- Exploration and Experimentation
- Challenge Your Assumptions
- Modeling Is a Continuous Activity
- There Are No Wrong Models
- Supple Code Aids Discovery
- Making the Implicit Explicit
- Tackling Ambiguity
- Give Things a Name
- A Problem Solver First, A Technologist Second
- Don't Solve All the Problems
- How Do I Know That I Am Doing It Right?
- Good Is Good Enough
- Practice, Practice, Practice
- The Salient Points
- Part II: Strategic Patterns: Communicating Between Bounded Contexts
- Chapter 11: Introduction to Bounded Context Integration
- How to Integrate Bounded Contexts
- Bounded Contexts Are Autonomous
- The Challenges of Integrating Bounded Contexts at the Code Level
- Multiple Bounded Contexts Exist within a Solution
- Namespaces or Projects to Keep Bounded Contexts Separate
- Integrating via the Database
- Multiple Teams Working in a Single Codebase
- Models Blur
- Use Physical Boundaries to Enforce Clean Models
- Integrating with Legacy Systems
- Bubble Context
- Autonomous Bubble Context
- Exposing Legacy Systems as Services
- Integrating Distributed Bounded Contexts
- Integration Strategies for Distributed Bounded Contexts
- Database Integration
- Flat File Integration
- RPC
- Messaging
- REST
- The Challenges of DDD with Distributed Systems
- The Problem with RPC
- RPC Is Harder to Make Resilient
- RPC Costs More to Scale
- RPC Involves Tight Coupling
- Distributed Transactions Hurt Scalability and Reliability
- Bounded Contexts Don't Have to Be Consistent with Each Other
- Eventual Consistency
- Event-Driven Reactive DDD
- Demonstrating the Resilience and Scalability of Reactive Solutions
- Challenges and Trade-Offs of Asynchronous Messaging
- Is RPC Still Relevant?
- SOA and Reactive DDD
- View Your Bounded Contexts as SOA Services
- Decompose Bounded Contexts into Business Components
- Decompose Business Components into Components
- Going Even Further with Micro Service Architecture
- The Salient Points
- Chapter 12: Integrating via Messaging
- Messaging Fundamentals
- Message Bus
- Reliable Messaging
- Store-and-Forward
- Commands and Events
- Eventual Consistency
- Building an E-Commerce Application with NServiceBus
- Designing the System
- Domain-Driven Design
- Containers Diagrams
- Evolutionary Architecture
- Sending Commands from a Web Application
- Creating a Web Application to Send Messages with NServiceBus
- Sending Commands
- Handling Commands and Publishing Events
- Creating an NServiceBus Server to Handle Commands
- Confi guring the Solution for Testing and Debugging
- Publishing Events
- Subscribing to Events
- Making External HTTP Calls Reliable with Messaging Gateways
- Messaging Gateways Improve Fault Tolerance
- Implementing a Messaging Gateway
- Controlling Message Retries
- Eventual Consistency in Practice
- Dealing with Inconsistency
- Rolling Forward into New States
- Bounded Contexts Store All the Data They Need Locally
- Storage Is Cheap-Keep a Local Copy
- Common Data Duplication Concerns
- Pulling It All Together in the UI
- Business Components Need Their Own APIs
- Be Wary of Server-Side Orchestration
- UI Composition with AJAX Data
- UI Composition with AJAX HTML
- Sharing Your APIs with the Outside World
- Maintaining a Messaging Application
- Message Versioning
- Backward-Compatible Message Versioning
- Handling Versioning with NServiceBus's Polymorphic Handlers
- Monitoring and Scaling
- Monitoring Errors
- Monitoring SLAs
- Scaling Out
- Integrating a Bounded Context with Mass Transit
- Messaging Bridge
- Mass Transit
- Installing and Configuring Mass Transit
- Declaring Messages for Use by Mass Transit
- Creating a Message Handler
- Subscribing to Events
- Linking the Systems with a Messaging Bridge
- Publishing Events
- Testing It Out
- Where to Learn More about Mass Transit
- The Salient Points
- Chapter 13: Integrating via Http with RPC and Rest
- Why Prefer HTTP?
- No Platform Coupling
- Everyone Understands HTTP
- Lots of Mature Tooling and Libraries
- Dogfooding Your APIs
- RPC
- Implementing RPC over HTTP
- SOAP
- Plain XML or JSON: The Modern Approach to RPC
- Choosing a Flavor of RPC
- REST
- Demystifying REST
- Resources
- Hypermedia
- Statelessness
- REST Fully Embraces HTTP
- What REST Is Not
- REST for Bounded Context Integration
- Designing for REST
- Building Event-Driven REST Systems with ASP.NET Web API
- Maintaining REST Applications
- Versioning
- Monitoring and Metrics
- Drawbacks with REST for Bounded Context Integration
- Less Fault Tolerance Out of the Box
- Eventual Consistency
- The Salient Points
- Part III: Tactical Patterns: Creating Effective Domain Models
- Chapter 14: Introducing the Domain Modeling Building Blocks
- Tactical Patterns
- Patterns to Model Your Domain
- Entities
- Value Objects
- Domain Services
- Modules
- Lifecycle Patterns
- Aggregates
- Factories
- Repositories
- Emerging Patterns
- Domain Events
- Event Sourcing
- The Salient Points
- Chapter 15: Value Objects
- When to Use a Value Object
- Representing a Descriptive, Identity-Less Concept
- Enhancing Explicitness
- Defining Characteristics
- Identity-Less
- Attribute-Based Equality
- Behavior-Rich
- Cohesive
- Immutable
- Combinable
- Self-Validating
- Testable
- Common Modeling Patterns
- Static Factory Methods
- Micro Types (Also Known as Tiny Types)
- Collection Aversion
- Persistence
- NoSQL
- SQL
- Flat Denormalization
- Normalizing into Separate Tables
- The Salient Points
- Chapter 16: Entities
- Understanding Entities
- Domain Concepts with Identity and Continuity
- Context-Dependent
- Implementing Entities
- Assigning Identifiers
- Natural Keys
- Arbitrarily Generated IDs
- Datastore-Generated IDs
- Pushing Behavior into Value Objects and Domain Services
- Validating and Enforcing Invariants
- Focusing on Behavior, Not Data
- Avoiding the "Model the Real-World" Fallacy
- Designing for Distribution
- Common Entity Modeling Principles and Patterns
- Implementing Validation and Invariants with Specifi cations
- Avoid the State Pattern
- Use Explicit Modeling
- Avoiding Getters and Setters with the Memento Pattern
- Favor Hidden-Side-Effect-Free Functions
- The Salient Points
- Chapter 17: Domain Services
- Understanding Domain Services
- When to Use a Domain Service
- Encapsulating Business Policies and Processes
- Representing Contracts
- Anatomy of a Domain Service
- Avoiding Anemic Domain Models
- Contrasting with Application Services
- Utilizing Domain Services
- In the Service Layer
- In the Domain
- Manually Wiring Up
- Using Dependency Injection
- Using a Service Locator
- Applying Double Dispatch
- Decoupling with Domain Events
- Should Entities Even Know About Domain Services?
- The Salient Points
- Chapter 18: Domain Events
- Essence of the Domain Events Pattern
- Important Domain Occurrences That Have Already Happened
- Reacting to Events
- Optional Asynchrony
- Internal vs External Events
- Event Handling Actions
- Invoke Domain Logic
- Invoke Application Logic
- Domain Events' Implementation Patterns
- Use the .Net Framework's Events Model
- Use an In-Memory Bus
- Udi Dahan's Static DomainEvents Class
- Handling Threading Issues
- Avoid a Static Class by Using Method Injection
- Return Domain Events
- Use an IoC Container as an Event Dispatcher
- Testing Domain Events
- Unit Testing
- Application Service Layer Testing
- The Salient Points
- Chapter 19: Aggregates
- Managing Complex Object Graphs
- Favoring a Single Traversal Direction
- Qualifying Associations
- Preferring IDs Over Object References
- Aggregates
- Design Around Domain Invariants
- Higher Level of Domain Abstraction
- Consistency Boundaries
- Transactional Consistency Internally
- Eventual Consistency Externally
- Special Cases
- Favor Smaller Aggregates
- Large Aggregates Can Degrade Performance
- Large Aggregates Are More Susceptible to Concurrency Conflicts
- Large Aggregates May Not Scale Well
- Defining Aggregate Boundaries
- eBidder: The Online Auction Case Study
- Aligning with Invariants
- Aligning with Transactions and Consistency
- Ignoring User Interface Influences
- Avoiding Dumb Collections and Containers
- Don't Focus on HAS-A Relationships
- Refactoring to Aggregates
- Satisfying Business Use Cases-Not Real Life
- Implementing Aggregates
- Selecting an Aggregate Root
- Exposing Behavioral Interfaces
- Protecting Internal State
- Allowing Only Roots to Have Global Identity
- Referencing Other Aggregates
- Nothing Outside An Aggregate's Boundary May Hold a Reference to Anything Inside
- The Aggregate Root Can Hand Out Transient References to the Internal Domain Objects
- Objects within the Aggregate Can Hold References to Other Aggregate Roots
- Implementing Persistence
- Access to Domain Objects for Reading Can Be at the Database Level
- A Delete Operation Must Remove Everything within the Aggregate Boundary at Once
- Avoiding Lazy Loading
- Implementing Transactional Consistency
- Implementing Eventual Consistency
- Rules That Span Multiple Aggregates
- Asynchronous Eventual Consistency
- Implementing Concurrency
- The Salient Points
- Chapter 20: Factories
- The Role of a Factory
- Separating Use from Construction
- Encapsulating Internals
- Hiding Decisions on Creation Type
- Factory Methods on Aggregates
- Factories for Reconstitution
- Use Factories Pragmatically
- The Salient Points
- Chapter 21: Repositories
- Repositories
- A Misunderstood Pattern
- Is the Repository an Antipattern?
- The Difference between a Domain Model and a Persistence Model
- The Generic Repository
- Aggregate Persistence Strategies
- Using a Persistence Framework That Can Map the Domain Model to the Data Model without Compromise
- Using a Persistence Framework That Cannot Map the Domain Model Directly without Compromise
- Public Getters and Setters
- Using the Memento Pattern
- Event Streams
- Be Pragmatic
- A Repository Is an Explicit Contract
- Transaction Management and Units of Work
- To Save or Not To Save
- Persistence Frameworks That Track Domain Object Changes
- Having to Explicitly Save Changes to Aggregates
- The Repository as an Anticorruption Layer
- Other Responsibilities of a Repository
- Entity ID Generation
- Collection Summaries
- Concurrency
- Audit Trails
- Repository Antipatterns
- Antipatterns: Don't Support Ad Hoc Queries
- Antipatterns: Lazy Loading Is Design Smell
- Antipatterns: Don't Use Repositories for Reporting Needs
- Repository Implementations
- Persistence Framework Can Map Domain Model to Data Model without Compromise
- NHibernate Example
- RavenDB Example
- Persistence Framework Cannot Map Domain Model Directly without Compromise
- Entity Framework Example
- Micro ORM Example
- The Salient Points
- Chapter 22: Event Sourcing
- The Limitations of Storing State as a Snapshot
- Gaining Competitive Advantage by Storing State as a Stream of Events
- Temporal Queries
- Projections
- Snapshots
- Event-Sourced Aggregates
- Structuring
- Adding Event-Sourcing Capabilities
- Exposing Expressive Domain-Focused APIs
- Adding Snapshot Support
- Persisting and Rehydrating
- Creating an Event-Sourcing Repository
- Adding Snapshot Persistence and Reloading
- Handling Concurrency
- Testing
- Building an Event Store
- Designing a Storage Format
- Creating Event Streams
- Appending to Event Streams
- Querying Event Streams
- Adding Snapshot Support
- Managing Concurrency
- A SQL Server-Based Event Store
- Choosing a Schema
- Creating a Stream
- Saving Events
- Loading Events from a Stream
- Snapshots
- Is Building Your Own Event Store a Good Idea?
- Using the Purpose-Built Event Store
- Installing Greg Young's Event Store
- Using the C# Client Library
- Running Temporal Queries
- Querying a Single Stream
- Querying Multiple Streams
- Creating Projections
- CQRS with Event Sourcing
- Using Projections to Create View Caches
- CQRS and Event Sourcing Synergy
- Event Streams as Queues
- No Two-Phase Commits
- Recapping the Benefits of Event Sourcing
- Competitive Business Advantage
- Expressive Behavior-Focused Aggregates
- Simplified Persistence
- Superior Debugging
- Weighing the Costs of Event Sourcing
- Versioning
- New Concepts to Learn and Skills to Hone
- New Technologies to Learn and Master
- Greater Data Storage Requirements
- Additional Learning Resources
- The Salient Points
- Part IV: Design Patterns for Effective Applications
- Chapter 23: Architecting Application user Interfaces
- Design Considerations
- Owned UIs versus Composed UIs
- Autonomous
- Authoritative
- Some Help Deciding
- HTML APIs versus Data APIs
- Client versus Server-Side Aggregation/Coordination
- Example 1: An HTML API-Based, Server-Side UI for Nondistributed Bounded Contexts
- Example 2: A Data API-Based, Client-Side UI for Distributed Bounded Contexts
- The Salient Points
- Chapter 24: CQRS: An Architecture of a Bounded Context
- The Challenges of Maintaining a Single Model for Two Contexts
- A Better Architecture for Complex Bounded Contexts
- The Command Side: Business Tasks
- Explicitly Modeling Intent
- A Model Free from Presentational Distractions
- Handling a Business Request
- The Query Side: Domain Reporting
- Reports Mapped Directly to the Data Model
- Materialized Views Built from Domain Events
- The Misconceptions of CQRS
- CQRS Is Hard
- CQRS Is Eventually Consistent
- Your Models Need to Be Event Sourced
- Commands Should Be Asynchronous
- CQRS Only Works with Messaging Systems
- You Need to Use Domain Events with CQRS
- Patterns to Enable Your Application to Scale
- Scaling the Read Side: An Eventually Consistent Read Model
- The Impact to the User Experience
- Use the Read Model to Consolidate Many Bounded Contexts
- Using a Reporting Database or a Caching Layer
- Scaling the Write Side: Using Asynchronous Commands
- Command Validation
- Impact to the User Experience
- Scaling It All
- The Salient Points
- Chapter 25: Commands: Application Service Patterns for Processing Business use Cases
- Differentiating Application Logic and Domain Logic
- Application Logic
- Infrastructural Concerns
- Coordinating Full Business Use Cases
- Application Services and Framework Integration
- Domain Logic from an Application Service's Perspective
- Application Service Patterns
- Command Processor
- Publish/Subscribe
- Request/Reply Pattern
- async/await
- Testing Application Services
- Use Domain Terminology
- Test as Much Functionality as Possible
- The Salient Points
- Chapter 26: Queries: Domain Reporting
- Domain Reporting within a Bounded Context
- Deriving Reports from Domain Objects
- Using Simple Mappings
- Using the Mediator Pattern
- Going Directly to the Datastore
- Querying a Datastore
- Reading Denormalized View Caches
- Building Projections from Event Streams
- Setting Up ES for Projections
- Creating Reporting Projections
- Counting the Number of Events in a Stream
- Creating As Many Streams As Required
- Building a Report from Streams and Projections
- Domain Reporting Across Bounded Contexts
- Composed UI
- Separate Reporting Context
- The Salient Points
- Index
- Advertisement
- EULA
System requirements
File format: PDF
Copy-Protection: Adobe-DRM (Digital Rights Management)
System requirements:
- Computer (Windows; MacOS X; Linux): Install the free reader Adobe Digital Editions prior to download (see eBook Help).
- Tablet/smartphone (Android; iOS): Install the free app Adobe Digital Editions or the app PocketBook before downloading (see eBook Help).
- E-reader: Bookeen, Kobo, Pocketbook, Sony, Tolino and many more (only limited: Kindle).
The file format PDF always displays a book page identically on any hardware. This makes PDF suitable for complex layouts such as those used in textbooks and reference books (images, tables, columns, footnotes). Unfortunately, on the small screens of e-readers or smartphones, PDFs are rather annoying, requiring too much scrolling.
This eBook uses Adobe-DRM, a „hard” copy protection. If the necessary requirements are not met, unfortunately you will not be able to open the eBook. You will therefore need to prepare your reading hardware before downloading.
Please note: We strongly recommend that you authorise using your personal Adobe ID after installation of any reading software.
For more information, see our eBook Help page.