Skip to main content
deleted 3 characters in body
Source Link
Robert Harvey
  • 200.1k
  • 55
  • 468
  • 679

Like many other things in software development, the degree of coupling in software systems is a tradeoff between competing objectives.

Consider this constructor method that takes a Customer as a parameter.

public CustomerProcessor(Customer customer)

As you can see, you're tightly-bound to the Customer class. You can inject it from somewhere else, but you're limited to that specific type.

Now consider this constructor:

public CustomerProcessor(ICustomer customer)

So nowNow we're specifying an Interface instead of a Class. We can pass whatever object we wish to this constructor method, so long as that object conforms to the ICustomer interface (including a mock or stub, for testing purposes).

But what if we did this?

public CustomerProcessor(string customer)

What's in customer? A JSON string? An XML string? Just a name? It could be anything. How it's handled depends on what code is in the CustomerProcessor object, but if your CustomerProcessor object was actually passed into some other class as an ICustomerProcessor, you could have a family of CustomerProcessors that could work out what the format is and correctly parse the string automatically, including a change from int to int[]. Now you're even more loosely coupled.

What does this cost you? Compile-time type safety, of course. That, and significantly increased complexity. It also costs you performance.

So why would you ever do this? Well, there are valid use cases. Consider a system of sensors. Each sensor has a value or a set of values that it emits. There are hundreds of different sensor types. Would you write a class for each new one? Some systems like this merely pass such information as strings along a data bus. Each string has a sensor type embedded, so that the sensor can be properly identified, and its data correctly decoded from the string.


As to your ripple effect, changing a member of a type should only affect that code that actually touches your int. When you make the decision to change from an int to an int[], you commit to refactoring all of the code in your system that touches that int. That's by-design. It has more to do with type systems than it does with the degree of coupling between software modules; since you're changing your fundamental declaration of what a customer is, the type system is going to complain when your old code doesn't meet the new expectations.

Like many other things in software development, the degree of coupling in software systems is a tradeoff between competing objectives.

Consider this constructor method that takes a Customer as a parameter.

public CustomerProcessor(Customer customer)

As you can see, you're tightly-bound to the Customer class. You can inject it from somewhere else, but you're limited to that specific type.

Now consider this constructor:

public CustomerProcessor(ICustomer customer)

So now we're specifying an Interface instead of a Class. We can pass whatever object we wish to this constructor method, so long as that object conforms to the ICustomer interface (including a mock or stub, for testing purposes).

But what if we did this?

public CustomerProcessor(string customer)

What's in customer? A JSON string? An XML string? Just a name? It could be anything. How it's handled depends on what code is in the CustomerProcessor object, but if your CustomerProcessor object was actually passed into some other class as an ICustomerProcessor, you could have a family of CustomerProcessors that could work out what the format is and correctly parse the string automatically, including a change from int to int[]. Now you're even more loosely coupled.

What does this cost you? Compile-time type safety, of course. That, and significantly increased complexity. It also costs you performance.

So why would you ever do this? Well, there are valid use cases. Consider a system of sensors. Each sensor has a value or a set of values that it emits. There are hundreds of different sensor types. Would you write a class for each new one? Some systems like this merely pass such information as strings along a data bus. Each string has a sensor type embedded, so that the sensor can be properly identified, and its data correctly decoded from the string.


As to your ripple effect, changing a member of a type should only affect that code that actually touches your int. When you make the decision to change from an int to an int[], you commit to refactoring all of the code in your system that touches that int. That's by-design. It has more to do with type systems than it does with the degree of coupling between software modules; since you're changing your fundamental declaration of what a customer is, the type system is going to complain when your old code doesn't meet the new expectations.

Like many other things in software development, the degree of coupling in software systems is a tradeoff between competing objectives.

Consider this constructor method that takes a Customer as a parameter.

public CustomerProcessor(Customer customer)

As you can see, you're tightly-bound to the Customer class. You can inject it from somewhere else, but you're limited to that specific type.

Now consider this constructor:

public CustomerProcessor(ICustomer customer)

Now we're specifying an Interface instead of a Class. We can pass whatever object we wish to this constructor method, so long as that object conforms to the ICustomer interface (including a mock or stub, for testing purposes).

But what if we did this?

public CustomerProcessor(string customer)

What's in customer? A JSON string? An XML string? Just a name? It could be anything. How it's handled depends on what code is in the CustomerProcessor object, but if your CustomerProcessor object was actually passed into some other class as an ICustomerProcessor, you could have a family of CustomerProcessors that could work out what the format is and correctly parse the string automatically, including a change from int to int[]. Now you're even more loosely coupled.

What does this cost you? Compile-time type safety, of course. That, and significantly increased complexity. It also costs you performance.

So why would you ever do this? Well, there are valid use cases. Consider a system of sensors. Each sensor has a value or a set of values that it emits. There are hundreds of different sensor types. Would you write a class for each new one? Some systems like this merely pass such information as strings along a data bus. Each string has a sensor type embedded, so that the sensor can be properly identified, and its data correctly decoded from the string.


As to your ripple effect, changing a member of a type should only affect that code that actually touches your int. When you make the decision to change from an int to an int[], you commit to refactoring all of the code in your system that touches that int. That's by-design. It has more to do with type systems than it does with the degree of coupling between software modules; since you're changing your fundamental declaration of what a customer is, the type system is going to complain when your old code doesn't meet the new expectations.

added 13 characters in body
Source Link
Robert Harvey
  • 200.1k
  • 55
  • 468
  • 679

Like many other things in software development, the degree of coupling in software systems is a tradeoff between competing objectives.

Consider this constructor method that takes a Customer as a parameter.

public CustomerProcessor(Customer customer)

As you can see, you're tightly-bound to the Customer class. You can inject it from somewhere else, but you're limited to that specific type.

Now consider this constructor:

public CustomerProcessor(ICustomer customer)

So now we're specifying an Interface instead of a Class. We can pass whatever object we wish to this constructor method, so long as that object conforms to the ICustomer interface (including a mock or stub, for testing purposes).

But what if we did this?

public CustomerProcessor(string customer)

What's in customer? A JSON string? An XML string? Just a name? It could be anything. How it's handled depends on what code is in the CustomerProcessor object, but if your CustomerProcessor object was actually passed into some other class as an ICustomerProcessor, you could have a family of CustomerProcessors that could work out what the format is and correctly parse the string automatically, including a change from int to int[]. Now you're even more loosely coupled.

What does this cost you? Type Compile-time type safety, of course. That, and significantly increased complexity. It also costs you performance.

So why would you ever do this? Well, there are valid use cases. Consider a system of sensors. Each sensor has a value or a set of values that it emits. There are hundreds of different sensor types. Would you write a class for each new one? Some systems like this merely pass such information as strings along a data bus. Each string has a sensor type embedded, so that the sensor can be properly identified, and its data correctly decoded from the string.


As to your ripple effect, changing a member of a type should only affect that code that actually touches your int. When you make the decision to change from an int to an int[], you commit to refactoring all of the code in your system that touches that int. That's by-design. It has more to do with type systems than it does with the degree of coupling between software modules; since you're changing your fundamental declaration of what a customer is, the type system is going to complain when your old code doesn't meet the new expectations.

Like many other things in software development, the degree of coupling in software systems is a tradeoff between competing objectives.

Consider this constructor method that takes a Customer as a parameter.

public CustomerProcessor(Customer customer)

As you can see, you're tightly-bound to the Customer class. You can inject it from somewhere else, but you're limited to that specific type.

Now consider this constructor:

public CustomerProcessor(ICustomer customer)

So now we're specifying an Interface instead of a Class. We can pass whatever object we wish to this constructor method, so long as that object conforms to the ICustomer interface (including a mock or stub, for testing purposes).

But what if we did this?

public CustomerProcessor(string customer)

What's in customer? A JSON string? An XML string? Just a name? It could be anything. How it's handled depends on what code is in the CustomerProcessor object, but if your CustomerProcessor object was actually passed into some other class as an ICustomerProcessor, you could have a family of CustomerProcessors that could work out what the format is and correctly parse the string automatically, including a change from int to int[]. Now you're even more loosely coupled.

What does this cost you? Type safety, of course. That, and significantly increased complexity. It also costs you performance.

So why would you ever do this? Well, there are valid use cases. Consider a system of sensors. Each sensor has a value or a set of values that it emits. There are hundreds of different sensor types. Would you write a class for each new one? Some systems like this merely pass such information as strings along a data bus. Each string has a sensor type embedded, so that the sensor can be properly identified, and its data correctly decoded from the string.


As to your ripple effect, changing a member of a type should only affect that code that actually touches your int. When you make the decision to change from an int to an int[], you commit to refactoring all of the code in your system that touches that int. That's by-design. It has more to do with type systems than it does with the degree of coupling between software modules; since you're changing your fundamental declaration of what a customer is, the type system is going to complain when your old code doesn't meet the new expectations.

Like many other things in software development, the degree of coupling in software systems is a tradeoff between competing objectives.

Consider this constructor method that takes a Customer as a parameter.

public CustomerProcessor(Customer customer)

As you can see, you're tightly-bound to the Customer class. You can inject it from somewhere else, but you're limited to that specific type.

Now consider this constructor:

public CustomerProcessor(ICustomer customer)

So now we're specifying an Interface instead of a Class. We can pass whatever object we wish to this constructor method, so long as that object conforms to the ICustomer interface (including a mock or stub, for testing purposes).

But what if we did this?

public CustomerProcessor(string customer)

What's in customer? A JSON string? An XML string? Just a name? It could be anything. How it's handled depends on what code is in the CustomerProcessor object, but if your CustomerProcessor object was actually passed into some other class as an ICustomerProcessor, you could have a family of CustomerProcessors that could work out what the format is and correctly parse the string automatically, including a change from int to int[]. Now you're even more loosely coupled.

What does this cost you? Compile-time type safety, of course. That, and significantly increased complexity. It also costs you performance.

So why would you ever do this? Well, there are valid use cases. Consider a system of sensors. Each sensor has a value or a set of values that it emits. There are hundreds of different sensor types. Would you write a class for each new one? Some systems like this merely pass such information as strings along a data bus. Each string has a sensor type embedded, so that the sensor can be properly identified, and its data correctly decoded from the string.


As to your ripple effect, changing a member of a type should only affect that code that actually touches your int. When you make the decision to change from an int to an int[], you commit to refactoring all of the code in your system that touches that int. That's by-design. It has more to do with type systems than it does with the degree of coupling between software modules; since you're changing your fundamental declaration of what a customer is, the type system is going to complain when your old code doesn't meet the new expectations.

deleted 14 characters in body
Source Link
Robert Harvey
  • 200.1k
  • 55
  • 468
  • 679

Like many other things in software development, the degree of coupling in software systems is a tradeoff between competing objectives.

Consider this constructor method that takes a Customer as a parameter.

public CustomerProcessor(Customer customer)

As you can see, you're tightly-bound to the Customer class. You can inject it from somewhere else, but you're limited to that specific type.

Now consider this constructor:

public CustomerProcessor(ICustomer customer)

So now we're specifying an Interface instead of a Class. We can pass whatever object we wish to this constructor method, so long as that object conforms to the ICustomer interface (including a mock or stub, for testing purposes).

But what if we did this?

public CustomerProcessor(string customer)

What's in customer? A JSON string? An XML string? Just a name? It could be anything. How it's handled depends on what code is in the CustomerProcessor object, but if your CustomerProcessor object was actually passed into some other class as an ICustomerProcessor, you could have a family of CustomerProcessors that could work out what the format is and correctly parse the string automatically, including a change from int to int[]. Now you're even more loosely coupled.

What does this cost you? Type safety, of course. That, and significantly increased complexity. It also costs you performance.

So why would you ever do this? Well, there are valid use cases. Consider a system of sensors. Each sensor has a value or a set of values that it emits. There are hundreds of different sensor types. Would you write a class for each new one? Some systems like this merely pass such information as strings along a data bus. Each string has a sensor type embedded, so that the sensor can be properly identified, and its data correctly decoded from the string.


As to your ripple effect, changing a member of a type should only affect that code that actually touches your int. When you make the decision to change from an int to an int[], you commit to refactoring all of the code in your system that touches that int. That's by-design. It has more to do with type systems than it does with the degree of coupling between software modules; since you're changing your fundamental declaration of what a customer is, the type system is going to complain when your old code doesn't meet the new expectations.

Like many other things in software development, the degree of coupling in software systems is a tradeoff between competing objectives.

Consider this constructor method that takes a Customer as a parameter.

public CustomerProcessor(Customer customer)

As you can see, you're tightly-bound to the Customer class. You can inject it from somewhere else, but you're limited to that specific type.

Now consider this constructor:

public CustomerProcessor(ICustomer customer)

So now we're specifying an Interface instead of a Class. We can pass whatever object we wish to this constructor method, so long as that object conforms to the ICustomer interface (including a mock or stub, for testing purposes).

But what if we did this?

public CustomerProcessor(string customer)

What's in customer? A JSON string? An XML string? Just a name? It could be anything. How it's handled depends on what code is in the CustomerProcessor object, but if your CustomerProcessor object was actually passed into some other class as an ICustomerProcessor, you could have a family of CustomerProcessors that could work out what the format is and correctly parse the string automatically, including a change from int to int[]. Now you're even more loosely coupled.

What does this cost you? Type safety, of course. That, and significantly increased complexity. It also costs you performance.

So why would you ever do this? Well, there are valid use cases. Consider a system of sensors. Each sensor has a value or a set of values that it emits. There are hundreds of different sensor types. Would you write a class for each new one? Some systems like this merely pass such information as strings along a data bus. Each string has a sensor type embedded, so that the sensor can be properly identified, and its data correctly decoded from the string.

Like many other things in software development, the degree of coupling in software systems is a tradeoff between competing objectives.

Consider this constructor method that takes a Customer as a parameter.

public CustomerProcessor(Customer customer)

As you can see, you're tightly-bound to the Customer class. You can inject it from somewhere else, but you're limited to that specific type.

Now consider this constructor:

public CustomerProcessor(ICustomer customer)

So now we're specifying an Interface instead of a Class. We can pass whatever object we wish to this constructor method, so long as that object conforms to the ICustomer interface (including a mock or stub, for testing purposes).

But what if we did this?

public CustomerProcessor(string customer)

What's in customer? A JSON string? An XML string? Just a name? It could be anything. How it's handled depends on what code is in the CustomerProcessor object, but if your CustomerProcessor object was actually passed into some other class as an ICustomerProcessor, you could have a family of CustomerProcessors that could work out what the format is and correctly parse the string automatically, including a change from int to int[]. Now you're even more loosely coupled.

What does this cost you? Type safety, of course. That, and significantly increased complexity. It also costs you performance.

So why would you ever do this? Well, there are valid use cases. Consider a system of sensors. Each sensor has a value or a set of values that it emits. There are hundreds of different sensor types. Would you write a class for each new one? Some systems like this merely pass such information as strings along a data bus. Each string has a sensor type embedded, so that the sensor can be properly identified, and its data correctly decoded from the string.


As to your ripple effect, changing a member of a type should only affect that code that actually touches your int. When you make the decision to change from an int to an int[], you commit to refactoring all of the code in your system that touches that int. That's by-design. It has more to do with type systems than it does with the degree of coupling between software modules; since you're changing your fundamental declaration of what a customer is, the type system is going to complain when your old code doesn't meet the new expectations.

deleted 14 characters in body
Source Link
Robert Harvey
  • 200.1k
  • 55
  • 468
  • 679
Loading
Source Link
Robert Harvey
  • 200.1k
  • 55
  • 468
  • 679
Loading