Slide 1

Slide 1 text

vladikk doit-intl.com #KanDDDinsky BALANCING COUPLING IN SOFTWARE DESIGN

Slide 2

Slide 2 text

VLAD 
 KHONONOV @vladikk vladikk.com [email protected]

Slide 3

Slide 3 text

VLAD 
 KHONONOV @vladikk vladikk.com [email protected]

Slide 4

Slide 4 text

VLAD 
 KHONONOV @vladikk vladikk.com [email protected]

Slide 5

Slide 5 text

vladikk doit-intl.com #KanDDDinsky BALANCING COUPLING IN SOFTWARE DESIGN

Slide 6

Slide 6 text

vladikk doit-intl.com #KanDDDinsky “System design is inherently about boundaries (what’s in, what’s out, what spans, what moves between), and about tradeo ff s. It reshapes what is outside, just as it shapes what is inside.” 
 - Ruth Malan (@ruthmalan)

Slide 7

Slide 7 text

vladikk doit-intl.com #KanDDDinsky “System design is inherently about boundaries (what’s in, what’s out, what spans, what moves between), and about tradeo ff s. It reshapes what is outside, just as it shapes what is inside.” 
 - Ruth Malan (@ruthmalan)

Slide 8

Slide 8 text

vladikk doit-intl.com #KanDDDinsky COUPLING

Slide 9

Slide 9 text

vladikk doit-intl.com #KanDDDinsky COUPLING

Slide 10

Slide 10 text

vladikk doit-intl.com #KanDDDinsky

Slide 11

Slide 11 text

vladikk doit-intl.com #KanDDDinsky 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩 💩

Slide 12

Slide 12 text

vladikk doit-intl.com #KanDDDinsky “"As small as possible”… is almost universally bad advice in so ft ware design. Some critical logic is going to cross those boundaries and result in poorly implemented, preventable workarounds” 
 - Mathias Verraes (@mathiasverraes)

Slide 13

Slide 13 text

vladikk doit-intl.com #KanDDDinsky “There are many useful and revealing heuristics for defining the boundaries of a service. Size is one of the least useful.” 
 - Nick Tune (@ntcoding)

Slide 14

Slide 14 text

vladikk doit-intl.com #KanDDDinsky AGENDA 1. WHAT IS COUPLING? 2. EXPLORE THE DIMENSIONS OF COUPLING 3. USE COUPLING AS A DESIGN TOOL / HEURISTIC

Slide 15

Slide 15 text

vladikk doit-intl.com #KanDDDinsky WHAT IS 
 COUPLING?

Slide 16

Slide 16 text

vladikk doit-intl.com #KanDDDinsky co- 
 together apere 
 fasten copula 
 copulare cople 
 copler couple LATIN LATIN OLD FRENCH MIDDLE ENGLISH

Slide 17

Slide 17 text

vladikk doit-intl.com #KanDDDinsky co- 
 apere 
 copula 
 cople 
 couple LATIN LATIN OLD FRENCH MIDDLE ENGLISH COUPLED = CONNECTED

Slide 18

Slide 18 text

vladikk doit-intl.com #KanDDDinsky

Slide 19

Slide 19 text

vladikk doit-intl.com #KanDDDinsky

Slide 20

Slide 20 text

vladikk doit-intl.com #KanDDDinsky COUPLING

Slide 21

Slide 21 text

vladikk doit-intl.com #KanDDDinsky COUPLING IS AN INHERENT PART OF SYSTEM DESIGN

Slide 22

Slide 22 text

vladikk doit-intl.com #KanDDDinsky Downstream Component Upstream Component depends on

Slide 23

Slide 23 text

vladikk doit-intl.com #KanDDDinsky Downstream Component Upstream Component depends on Change

Slide 24

Slide 24 text

vladikk doit-intl.com #KanDDDinsky Downstream Component Upstream Component depends on Change

Slide 25

Slide 25 text

vladikk doit-intl.com #KanDDDinsky Downstream Component Upstream Component depends on Change

Slide 26

Slide 26 text

vladikk doit-intl.com #KanDDDinsky “Coupling defines the components’ degrees of freedom” 
 - Michael Nygard (@mtnygard)

Slide 27

Slide 27 text

vladikk doit-intl.com #KanDDDinsky Downstream Component Upstream Component depends on

Slide 28

Slide 28 text

vladikk doit-intl.com #KanDDDinsky

Slide 29

Slide 29 text

vladikk doit-intl.com #KanDDDinsky COUPLING Should only allow changes that we actually need Design decision Defines the relationship between components Limits components’ degrees of freedom

Slide 30

Slide 30 text

vladikk doit-intl.com #KanDDDinsky DIMENSIONS 
 OF COUPLING

Slide 31

Slide 31 text

vladikk doit-intl.com #KanDDDinsky DIMENSIONS OF COUPLING Distance Volatility Strength

Slide 32

Slide 32 text

vladikk doit-intl.com #KanDDDinsky STRENGTH 1

Slide 33

Slide 33 text

vladikk doit-intl.com #KanDDDinsky • Coupling in Structured Design • Connascence COUPLING MODELS

Slide 34

Slide 34 text

vladikk doit-intl.com #KanDDDinsky

Slide 35

Slide 35 text

vladikk doit-intl.com #KanDDDinsky 1. CONTENT COUPLING 2. COMMON COUPLING 3. EXTERNAL COUPLING 4. CONTROL COUPLING 5. STAMP COUPLING 6. DATA COUPLING

Slide 36

Slide 36 text

vladikk doit-intl.com #KanDDDinsky 1. CONTENT COUPLING 2. COMMON COUPLING 3. EXTERNAL COUPLING 4. CONTROL COUPLING 5. STAMP COUPLING 6. DATA COUPLING • Directly referencing another module’s “contents” - implementation details • Private interfaces • “GO TO”

Slide 37

Slide 37 text

vladikk doit-intl.com #KanDDDinsky 1. CONTENT COUPLING 2. COMMON COUPLING 3. EXTERNAL COUPLING 4. CONTROL COUPLING 5. STAMP COUPLING 6. DATA COUPLING • Communicate through globally accessible memory space • Unstructured global data item • Global byte array

Slide 38

Slide 38 text

vladikk doit-intl.com #KanDDDinsky 1. CONTENT COUPLING 2. COMMON COUPLING 3. EXTERNAL COUPLING 4. CONTROL COUPLING 5. STAMP COUPLING 6. DATA COUPLING • Communicate through globally accessible primitive value or an array of primitive values • Global variable

Slide 39

Slide 39 text

vladikk doit-intl.com #KanDDDinsky 1. CONTENT COUPLING 2. COMMON COUPLING 3. EXTERNAL COUPLING 4. CONTROL COUPLING 5. STAMP COUPLING 6. DATA COUPLING • A module controls execution logic of another module • Close familiarity with its behavior and execution context • The controlled module doesn’t have enough information (input) to control its own behavior

Slide 40

Slide 40 text

vladikk doit-intl.com #KanDDDinsky 1. CONTENT COUPLING 2. COMMON COUPLING 3. EXTERNAL COUPLING 4. CONTROL COUPLING 5. STAMP COUPLING 6. DATA COUPLING • Modules communicate through exchanging data structures • Data structures are the modules’ implementation details • Sensitive to changes in the data structures

Slide 41

Slide 41 text

vladikk doit-intl.com #KanDDDinsky 1. CONTENT COUPLING 2. COMMON COUPLING 3. EXTERNAL COUPLING 4. CONTROL COUPLING 5. STAMP COUPLING 6. DATA COUPLING • Modules communicate through exchanging primitive types • Communicating by sharing minimum information • Integration specific data

Slide 42

Slide 42 text

vladikk doit-intl.com #KanDDDinsky Referencing implementation details Globally accessible memory Global variable Controlling behavior Exchanging data records Minimizing integration interface CONTENT COUPLING: COMMON COUPLING: EXTERNAL COUPLING: CONTROL COUPLING: STAMP COUPLING: DATA COUPLING:

Slide 43

Slide 43 text

vladikk doit-intl.com #KanDDDinsky

Slide 44

Slide 44 text

vladikk doit-intl.com #KanDDDinsky CONNASCENCE

Slide 45

Slide 45 text

vladikk doit-intl.com #KanDDDinsky CONNASCENCE “Having been born together” (Latin) Components are connnascent (born together) if: • A change in one component, requires a change in another component • You can postulate a change that would require both components to change

Slide 46

Slide 46 text

vladikk doit-intl.com #KanDDDinsky STATIC CONNASCENCE: 1. Name 2. Type 3. Meaning 4. Algorithm 5. Position DYNAMIC CONNASCENCE: 1. Execution 2. Timing 3. Value 4. Identity

Slide 47

Slide 47 text

vladikk doit-intl.com #KanDDDinsky STATIC CONNASCENCE: 1. NAME 2. Type 3. Meaning 4. Algorithm 5. Position • Two variables reference the same thing • Need to have the same name

Slide 48

Slide 48 text

vladikk doit-intl.com #KanDDDinsky STATIC CONNASCENCE: 1. Name 2. TYPE 3. Meaning 4. Algorithm 5. Position • Types of two variables have to match

Slide 49

Slide 49 text

vladikk doit-intl.com #KanDDDinsky STATIC CONNASCENCE: 1. Name 2. Type 3. MEANING 4. Algorithm 5. Position • Conventions used to assign meaning to values • “Magic numbers” • int status = 7;

Slide 50

Slide 50 text

vladikk doit-intl.com #KanDDDinsky STATIC CONNASCENCE: 1. Name 2. Type 3. Meaning 4. ALGORITHM 5. Position • Same algorithm is applied in multiple modules • Assume expected behaviour • E.g. encoding, encryption

Slide 51

Slide 51 text

vladikk doit-intl.com #KanDDDinsky STATIC CONNASCENCE: 1. Name 2. Type 3. Meaning 4. Algorithm 5. POSITION • Order of passed values

Slide 52

Slide 52 text

vladikk doit-intl.com #KanDDDinsky STATIC CONNASCENCE: Name Type Meaning Algorithm Position Two variables need to have the same name Types have to match Conventions for assinging meaning to values A common algorithm is used or assumed Values must be passed in a specific order

Slide 53

Slide 53 text

vladikk doit-intl.com #KanDDDinsky DYNAMIC CONNASCENCE: 1. Execution 2. Timing 3. Value 4. Identity

Slide 54

Slide 54 text

vladikk doit-intl.com #KanDDDinsky DYNAMIC CONNASCENCE: 1. EXECUTION 2. Timing 3. Value 4. Identity • Execution must be carried out in a given order • No intervening execution • Dynamic equivalent of connascence of position

Slide 55

Slide 55 text

vladikk doit-intl.com #KanDDDinsky DYNAMIC CONNASCENCE: 1. Execution 2. TIMING 3. Value 4. Identity • Execution in a set amount of time • E.g.: Timeouting a request • E.g.: Turning off an X-Ray machine

Slide 56

Slide 56 text

vladikk doit-intl.com #KanDDDinsky DYNAMIC CONNASCENCE: 1. Execution 2. Timing 3. VALUE 4. Identity • Values have to change together • Logical transaction • E.g.: Arithmetic constraint • E.g.: Replicated data • E.g.: Business invariant

Slide 57

Slide 57 text

vladikk doit-intl.com #KanDDDinsky DYNAMIC CONNASCENCE: 1. Execution 2. Timing 3. VALUE 4. Identity

Slide 58

Slide 58 text

vladikk doit-intl.com #KanDDDinsky DYNAMIC CONNASCENCE: 1. Execution 2. Timing 3. Value 4. IDENTITY • Two objects must reference the same instance of another object • E.g.: Unit of work

Slide 59

Slide 59 text

vladikk doit-intl.com #KanDDDinsky DYNAMIC CONNASCENCE: Execution Timing Value Identity Execution in a given order Execution after a set amount of time Values have to change together Reference the same instance of an object

Slide 60

Slide 60 text

vladikk doit-intl.com #KanDDDinsky Connascence of Identity Connascence of Value Connascence of Timing Connascence of Execution Connascence of Position Connascence of Algorithm Connascence of Meaning Connascence of Type Connascence of Name Content Coupling Common Coupling External Coupling Control Coupling Stamp Coupling Data Coupling Strength Refactor

Slide 61

Slide 61 text

vladikk doit-intl.com #KanDDDinsky • 1960s - Coupling in Structured Design • 1990s - Connascence • 2020s - Integration Strength COUPLING MODELS

Slide 62

Slide 62 text

vladikk doit-intl.com #KanDDDinsky • Remix of structured design and connascence models • Focuses on the knowledge shared between the connected components • Practical applicability INTEGRATION STRENGTH

Slide 63

Slide 63 text

vladikk doit-intl.com #KanDDDinsky INTEGRATION STRENGTH: 1. Implementation Coupling 2. Functional Coupling 3. Model Coupling 4. Contract Coupling

Slide 64

Slide 64 text

vladikk doit-intl.com #KanDDDinsky INTEGRATION STRENGTH 1. IMPLEMENTATION COUPLING 2. Functional Coupling 3. Model Coupling 4. Contract Coupling • Dependence on implementation details • Integration through private interfaces • Fragile • Implicit

Slide 65

Slide 65 text

vladikk doit-intl.com #KanDDDinsky INTEGRATION STRENGTH 1. Implementation Coupling 2. FUNCTIONAL COUPLING 3. Model Coupling 4. Contract Coupling • Functionally related • Implementing closely-related business functionality • Change in business requirements affect both components • Don’t have to be physically integrated!

Slide 66

Slide 66 text

vladikk doit-intl.com #KanDDDinsky INTEGRATION STRENGTH 1. Implementation Coupling 2. Functional Coupling 3. MODEL COUPLING 4. Contract Coupling • Sharing a model of the business domain • Structures • Hinders evolution of the shared model

Slide 67

Slide 67 text

vladikk doit-intl.com #KanDDDinsky INTEGRATION STRENGTH 1. Implementation Coupling 2. Functional Coupling 3. Model coupling 4. CONTRACT COUPLING • Explicit integration contract • Integration-specific model • Decoupled from the implementation model

Slide 68

Slide 68 text

vladikk doit-intl.com #KanDDDinsky Strength Shared Knowledge INTEGRATION STRENGTH Implementation Coupling Functional Coupling Model Coupling Contract Coupling

Slide 69

Slide 69 text

vladikk doit-intl.com #KanDDDinsky Strength Shared Knowledge INTEGRATION STRENGTH Implementation Coupling Functional Coupling Model Coupling Contract Coupling Implicit 
 Interfaces Explicit 
 Interfaces

Slide 70

Slide 70 text

vladikk doit-intl.com #KanDDDinsky Strength Shared Knowledge INTEGRATION STRENGTH Implementation Coupling Functional Coupling Model Coupling Contract Coupling

Slide 71

Slide 71 text

vladikk doit-intl.com #KanDDDinsky DISTANCE 2

Slide 72

Slide 72 text

vladikk doit-intl.com #KanDDDinsky DISTANCE Statem ents M ethods Classes Nam espaces Com ponents (M icro)Services System s

Slide 73

Slide 73 text

vladikk doit-intl.com #KanDDDinsky DISTANCE Statem ents M ethods Classes Nam espaces Com ponents (M icro)Services System s Coordination

Slide 74

Slide 74 text

vladikk doit-intl.com #KanDDDinsky COST OF CHANGE IS PROPORTIONAL TO THE DISTANCE BETWEEN COMPONENTS

Slide 75

Slide 75 text

vladikk doit-intl.com #KanDDDinsky DISTANCE Statem ents M ethods Classes Nam espaces Com ponents (M icro)Services System s Coordination

Slide 76

Slide 76 text

vladikk doit-intl.com #KanDDDinsky DISTANCE Statem ents M ethods Classes Nam espaces Com ponents (M icro)Services System s Coordination Lifecycle 
 Coupling

Slide 77

Slide 77 text

vladikk doit-intl.com #KanDDDinsky • Defines the components’ lifecycle coupling • Sets the probability of “collateral” cascading changes • A ff ected by the type of encapsulation boundaries • Can also be a ff ected by the organizational structure DISTANCE

Slide 78

Slide 78 text

vladikk doit-intl.com #KanDDDinsky DISTANCE Statem ents M ethods Classes Nam espaces Com ponents (M icro)Services Coordination Lifecycle 
 Coupling

Slide 79

Slide 79 text

vladikk doit-intl.com #KanDDDinsky DISTANCE Statem ents M ethods Classes Nam espaces Com ponents (M icro)Services (M icro)Services Coordination Lifecycle 
 Coupling One 
 Team Multiple 
 Teams

Slide 80

Slide 80 text

vladikk doit-intl.com #KanDDDinsky Component A Component B System A System B Functional Coupling

Slide 81

Slide 81 text

vladikk doit-intl.com #KanDDDinsky

Slide 82

Slide 82 text

vladikk doit-intl.com #KanDDDinsky VOLATILITY 3

Slide 83

Slide 83 text

vladikk doit-intl.com #KanDDDinsky How o ft en do the coupled components change? VOLATILITY

Slide 84

Slide 84 text

vladikk doit-intl.com #KanDDDinsky • Subdomain is an area of activity required for the company to achieve its goals • Business building blocks • Coherent set of interrelated use cases SUBDOMAINS

Slide 85

Slide 85 text

vladikk doit-intl.com #KanDDDinsky SUBDOMAINS Supporting Core Generic

Slide 86

Slide 86 text

vladikk doit-intl.com #KanDDDinsky SUBDOMAINS Supporting CORE Generic • The company’s competitive advantage • What it does differently from its competitors • New invention or optimizing existing processes • How it makes money (or hopes to)

Slide 87

Slide 87 text

vladikk doit-intl.com #KanDDDinsky SUBDOMAINS Supporting Core GENERIC • “Solved problems” • Things all companies are doing in the same way • Cheaper to buy / adopt than to build in-house

Slide 88

Slide 88 text

vladikk doit-intl.com #KanDDDinsky SUBDOMAINS SUPPORTING Core Generic • Implemented in-house • Provide no competitive advantage • Needed by Core Subdomains • No innovation, optimization, or intellectual property

Slide 89

Slide 89 text

vladikk doit-intl.com #KanDDDinsky SUBDOMAINS Supporting Generic High Volatility Low Volatility Low Volatility CORE

Slide 90

Slide 90 text

vladikk doit-intl.com #KanDDDinsky

Slide 91

Slide 91 text

vladikk doit-intl.com #KanDDDinsky

Slide 92

Slide 92 text

vladikk doit-intl.com #KanDDDinsky DIMENSIONS OF COUPLING Volatility Strength Distance

Slide 93

Slide 93 text

vladikk doit-intl.com #KanDDDinsky BALANCING THE 
 DIMENSIONS OF COUPLING

Slide 94

Slide 94 text

vladikk doit-intl.com #KanDDDinsky Strength increases cascading changes High Strength + High Volatility = High Maintenance E ff ort STRENGTH & VOLATILITY

Slide 95

Slide 95 text

vladikk doit-intl.com #KanDDDinsky Strength increases cascading changes Distance increases coordination overhead High Strength over High Distance = High Cost of Evolving the System STRENGTH & DISTANCE

Slide 96

Slide 96 text

vladikk doit-intl.com #KanDDDinsky Distance increases coordination overhead High Volatility over High Distance = High Coordination E ff ort DISTANCE & VOLATILITY

Slide 97

Slide 97 text

vladikk doit-intl.com #KanDDDinsky Distance Strength Volatility Pain = 𝑓 (S, V, D) Maintenance Pain STRENGTH & DISTANCE & VOLATILITY

Slide 98

Slide 98 text

vladikk doit-intl.com #KanDDDinsky Pain = 𝑓 (S, V, D) STRENGTH & DISTANCE & VOLATILITY Pain = Strength * Volatility * Distance

Slide 99

Slide 99 text

vladikk doit-intl.com #KanDDDinsky PAIN = 𝑓 (S, V, D) Pain = Strength * Volatility * Distance 
 0 = 0 * ∞ * ∞

Slide 100

Slide 100 text

vladikk doit-intl.com #KanDDDinsky PAIN = 𝑓 (S, V, D) Pain = Strength * Volatility * Distance 
 0 = ∞ * ∞ * 0

Slide 101

Slide 101 text

vladikk doit-intl.com #KanDDDinsky PAIN = 𝑓 (S, V, D) Pain = Strength * Volatility * Distance 
 0 = ∞ * 0 * ∞

Slide 102

Slide 102 text

vladikk doit-intl.com #KanDDDinsky 1. Eliminate accidental coupling 2. Reduce integration strength as much as possible 3. If strength and volatility is high: reduce distance PAIN = S * V * D

Slide 103

Slide 103 text

vladikk doit-intl.com #KanDDDinsky EXAMPLE: INTEGRATION STRENGTH

Slide 104

Slide 104 text

vladikk doit-intl.com #KanDDDinsky EXAMPLE: INTEGRATION STRENGTH Implementation Coupling Functional Coupling Model Coupling Contract Coupling Component A 
 Component B

Slide 105

Slide 105 text

vladikk doit-intl.com #KanDDDinsky EXAMPLE: INTEGRATION STRENGTH IMPLEMENTATION COUPLING Functional Coupling Model Coupling Contract Coupling Component A 
 Component B Not intended 
 for integration

Slide 106

Slide 106 text

vladikk doit-intl.com #KanDDDinsky EXAMPLE: INTEGRATION STRENGTH Implementation Coupling FUNCTIONAL COUPLING Model Coupling Contract Coupling Component A 
 Component B Have to operate on the same data

Slide 107

Slide 107 text

vladikk doit-intl.com #KanDDDinsky EXAMPLE: INTEGRATION STRENGTH Implementation Coupling Model Coupling MODEL COUPLING Contract Coupling Component A 
 Component B BI imports data for analysis

Slide 108

Slide 108 text

vladikk doit-intl.com #KanDDDinsky EXAMPLE: INTEGRATION STRENGTH Implementation Coupling Functional Coupling Model Coupling CONTRACT COUPLING Component A 
 Component B Dedicated integration DB

Slide 109

Slide 109 text

vladikk doit-intl.com #KanDDDinsky EXAMPLE: DOMAIN-DRIVEN DESIGN

Slide 110

Slide 110 text

vladikk doit-intl.com #KanDDDinsky AGGERGATES Pain = Strength * Volatility * Distance 
 0 = Functional * High * 0

Slide 111

Slide 111 text

vladikk doit-intl.com #KanDDDinsky BOUNDED CONTEXTS Pain = Strength * Volatility * Distance 
 0 = Model * High * 0

Slide 112

Slide 112 text

vladikk doit-intl.com #KanDDDinsky SUPPORTING SUBDOMAINS Pain = Strength * Volatility * Distance 
 0 = ∞ * 0 * ∞

Slide 113

Slide 113 text

vladikk doit-intl.com #KanDDDinsky ANTICORRUPTION LAYER, OPEN-HOST SERVICE, PUBLISHED LANGUAGE Pain = Strength * Volatility * Distance 
 0 = 0 * High * High

Slide 114

Slide 114 text

vladikk doit-intl.com #KanDDDinsky WRAP UP

Slide 115

Slide 115 text

vladikk doit-intl.com #KanDDDinsky • Defines the relationship between a system’s components • Is an inherent part of system design • Happens in 3 dimensions: strength, volatility, distance WRAP UP: COUPLING

Slide 116

Slide 116 text

vladikk doit-intl.com #KanDDDinsky Strength Shared Knowledge Implementation Coupling Functional Coupling Model Coupling Contract Coupling WRAP UP: INTEGRATION STRENGTH

Slide 117

Slide 117 text

vladikk doit-intl.com #KanDDDinsky • The coordination e ff ort and cost of a change is proportional to the distance between the a ff ected components • Couples components’ lifecycles WRAP UP: DISTANCE

Slide 118

Slide 118 text

vladikk doit-intl.com #KanDDDinsky WRAP UP: VOLATILITY • How often do the coupled components have to change? • Affects the actual effort • Can be estimated using domain-driven design’s subdomains: Core (high), Supporting (low), Generic (low)

Slide 119

Slide 119 text

vladikk doit-intl.com #KanDDDinsky Distance Strength Volatility Pain = 𝑓 (S, V, D) Maintenance Pain WRAP UP: BALANCING COUPLING

Slide 120

Slide 120 text

@vladikk vladikk.com vladik at khononov.com

Slide 121

Slide 121 text

@vladikk vladikk.com vladik at khononov.com

Slide 122

Slide 122 text

QUESTIONS?

Slide 123

Slide 123 text

@vladikk vladikk.com vladik at khononov.com THANK YOU!