HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Loosely coupled movement

Submitted by: @import:stackexchange-codereview··
0
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()
{

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 (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.