patterncsharpMinor
Loosely coupled movement
Viewed 0 times
movementlooselycoupled
Problem
I'm working on my ability to write loosely coupled applications that follow SOLID principles. This is a simple application trying to demonstrate the concept. Is it OK? Am I going along the right lines? What needs to be improved or changed?
I'd just like your overall opinion on the design structure and the code please. If you'd like a straightforward question to answer directly, then it'd be "Is this code that is appropriate to be used in production?"
```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LooselyCoupled
{
public class Program
{
static void Main(string[] args)
{
//Usage
Human human = new Human();
human.Name = "John";
human.Age = 36;
Cat cat = new Cat();
cat.Name = "Molly";
cat.Age = 8;
MovementManager movement = new MovementManager(human);
movement.Move();
MovementManager movement2 = new MovementManager(cat);
movement2.Move();
}
//Interface to act as a middle man (inversion) to redirect the otherwise narrow flow
public interface iMovement
{
void Move();
}
//A manager that has no idea of any implementation, but only an interface
public class MovementManager
{
private iMovement movement;
public MovementManager(iMovement movement)
{
this.movement = movement;
}
public void Move()
{
movement.Move();
}
}
//I've decided that every class that implements iMovement will have certain attributes
//therefore I've decided to add an abstract class into the mix (is this OK?)
public abstract class BaseMovementEntity : iMovement
{
public string Name { get; set; }
public int Age { get; set; }
public abstract void Move();
}
public class Human : BaseMovementEntity
{
public override void Move()
{
I'd just like your overall opinion on the design structure and the code please. If you'd like a straightforward question to answer directly, then it'd be "Is this code that is appropriate to be used in production?"
```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LooselyCoupled
{
public class Program
{
static void Main(string[] args)
{
//Usage
Human human = new Human();
human.Name = "John";
human.Age = 36;
Cat cat = new Cat();
cat.Name = "Molly";
cat.Age = 8;
MovementManager movement = new MovementManager(human);
movement.Move();
MovementManager movement2 = new MovementManager(cat);
movement2.Move();
}
//Interface to act as a middle man (inversion) to redirect the otherwise narrow flow
public interface iMovement
{
void Move();
}
//A manager that has no idea of any implementation, but only an interface
public class MovementManager
{
private iMovement movement;
public MovementManager(iMovement movement)
{
this.movement = movement;
}
public void Move()
{
movement.Move();
}
}
//I've decided that every class that implements iMovement will have certain attributes
//therefore I've decided to add an abstract class into the mix (is this OK?)
public abstract class BaseMovementEntity : iMovement
{
public string Name { get; set; }
public int Age { get; set; }
public abstract void Move();
}
public class Human : BaseMovementEntity
{
public override void Move()
{
Solution
Let me share my thoughts. From the SOLID perspective your example is very simple and does not explicitly break any principles.
The only thing that you should not do in large-scale production code is to couple your application code (
What you should usually do is to put your application code into separate assembly(ies), employ some DI Container and create a Composition Root (also preferable in separate assembly). Application code/assemblies must not have any references to DI Container or Composition Root. On the other side, your execution host (Console App project) must reference Composition Root and Application Code assemblies, and resolve an instance of
You would need
As a side note: everywhere in your application when you use
Dependency Injection in .NET by Mark Seemann is an excellent book about design of loosely coupled application.
The only thing that you should not do in large-scale production code is to couple your application code (
MovementManager, etc.) with execution host (Console app project). What you should usually do is to put your application code into separate assembly(ies), employ some DI Container and create a Composition Root (also preferable in separate assembly). Application code/assemblies must not have any references to DI Container or Composition Root. On the other side, your execution host (Console App project) must reference Composition Root and Application Code assemblies, and resolve an instance of
MovementManagerFactory via DI Container. Then you can use MovementManagerFactory to create your MovementManager with appropriate iMovement object.You would need
MovementManagerFactory because your MovementManager constructor requires iMovement object. To simplify things I'd rather remove that constructor and instead pass iMovement object to the Move() method directly:public class MovementManager
{
public void Move(iMovement movement)
{
movement.Move();
}
}As a side note: everywhere in your application when you use
new operator to create an instance of a class, you potentially make your code tightly coupled. It is especially true when that 'new-ed' class belongs to another module or component. Dependency Injection in .NET by Mark Seemann is an excellent book about design of loosely coupled application.
Code Snippets
public class MovementManager
{
public void Move(iMovement movement)
{
movement.Move();
}
}Context
StackExchange Code Review Q#147359, answer score: 3
Revisions (0)
No revisions yet.