⚔ LOTR with SOLID principles 💍👿
Tags: oop, lotr, solid, dotnet
Published: 2021-05-09 01:34:10

This is going to be a weird and sort of fun way of looking at the SOLID principals and how the Lord of the Rings apply it in different parts of its series of films. The hope of this is to encourage a more fun discussion around programming concepts in general and to get less technically gifted individuals like me another perspective of the SOLID principals. Granted, I am not perfect and will apologize in advance for any miss information regarding the film or the concepts in general.  

TLDR: Same old SOLID principals but using LOTR to explain it.  

### Single responsibility

A few characters in this film had a (sort of) clear, single responsibility in mind. In the obvious case for Frodo, his one true responsibility was to go to Mordor and to drop it like it’s hot.  

```
public class Frodo 

{ 

  public void ExecuteMission() 

  { 
     Console.WriteLine($"I, {nameof(Frodo)}, am tasked with 
                carrying the ring and throwing it in the ever 
                 fiery pit of Mordor!"); 

  } 
}
```

This example can also be extended to Samwise Gamgee, who’s tasked with helping his best friend reach their goal by keeping them company.


### Open-Closed 

The battle at helm’s deep. I know what you’re thinking, how could this possibly apply but hear me out. Helm’s deep’s structure was not bad at all, you had all sorts of places where “any” archer can come in and shoot from above (quotations used to remind you of the idiot that fired the first shot 🤦‍♂️). 

```
public class HelmsDeep 
{ 
        private readonly IEnumerable<IArcher> _archers;

        public HelmsDeep(IEnumerable<IArcher> archers) 
        { 
            _archers = archers; 
        } 

        public void DefendHelmsDeep(AttackType attackType) 
        { 
            if (attackType = AttackType.areApproachingTheWall) 
                 DefendUsing(_archers); 
        } 
} 
```

This is all well and good, but helms deep want to prepare for another sort of attack, coming from within the wall, so what do we do? We add an if else statement asking: 

```
else if (attackType = AttackType. penetratedTheWalls) 
                DefendUsing(_swordsmen); 
```
 
Imagine if each line of code was the years of preparation it takes to be able to defend helms deep with a particular tactic. It would be jarring to have to add new lines around helms deep to configure for every sort of situation. That massive structure that was stuck to the mountain should in no way be open for modification when it comes to any battle. All we need to do is to take in a type of defense tactic and execute it, this is all that helms deeps needs, to be defended at all costs! 

We create an `IDefensiveTactic` interface that needs it’s Execute method implemented: 

```
public interface IDefensiveTactic 
{ 
   void Execute(); 
} 
```

We then implement this interface with whatever tactic we want such as an `ArchersDefenceTactic` or a `SwordsmanDefenceTactic` who both must implement the interface method `execute`.  We finally come to Helm’s deep’s class and provide the `DefendHelmsDeep` method with the `IDefensiveTactic` type as it’s argument and call execute: 

```
public void DefendHelmsDeep (IDefensiveTactic defensiveTactic) 
{ 
   defensiveTactic.Execute(); 
} 
```

As we can see from here, Helms’ deep does not exactly know what is defending it, but it welcomes all forms of defense against what’s attacking it. 🤬 “Brace the gaaaate”


### Liskov substitution 

This one I feel could be simplified in terms of kingship inheritance, as shown below: 

```
public abstract class King 
{ 
   public abstract void DoKingStuff(); 
} 

public class Thengel : King 
{
    public override void DoKingStuff() 
      => Console.WriteLine("doing Thengel the king stuff"); 
}

public class Théoden : Thengel 
{ 
    public override void DoKingStuff() 
      => Console.WriteLine("doing Théoden the king stuff"); 
} 
```

`Théoden` is a king because his daddy came from a `King` and they all come from a long line of kings, the first king had to do king stuff, lord knows what that is but we assume it’s what kings do.  As a result, whoever inherits directly from them is forced to `DoKingStuff` the Kings way, using the same signature. In this case, it was `Thengel` who inherited directly from the king, and so was forced to override the method. Funnily enough, `Théoden` doesn’t have to override anything as they inherited from their father, who already did the hard work; but they do inherit the same method and therefore inherit the same output of that method. Whatever happened to kings who didn’t want to do thing’s their father’s way, eh? 

### Interface Segregation 

Good old Gimli, does nothing but fight fight fight fight, never been able to sneak past anything or be able to hold a ring. I guess this is kind of related to SRP in that every character is known for a particular trait/function. Legolas, like other elves, is very physically fit, is an archer and has long pointy ears. 

What I’m getting to is that if every character was wrapped up in one super character, for this sake named `IMainCharacter`, it would make the movie more tedious to watch. This main character may not have to take part in many battles, do a bunch of sneaky stuff, talk to trees, do magic and save himself from a huge monster in a cave but they have all of that in their arsenal all the while it’s wasting away. This would translate to this: 

```
public interface IMainCharacter 
{
    void ExecuteMission(); 
    void ResistTemptation(); 
    void SaveMyself(); 
    void SneakPastStuff(); 
    void TalkToTrees(); 
    void Battle(); 
    void DoMagic(); 
    void DoArcheryStuff(); 
    void BeShortAndAngryWithAnAxeFor100Years(); 
} 
```

What happened instead is that every character was able to inherit a particular trait, like `ICanSneak` , `ICanFight` or `ICanHoldTheRing` for example. Many characters with one ability can simultaneously perform 100% of their abilities (because there’s so few for each), but one main character with all the abilities will most likely not use all of them.

### Dependency Inversion 

There was one other way this whole story could have gone; the whole fellowship of the ring could have been established while in Mordor. “We must discuss Sauron, but only once we get to Mordor”. So, they would walk inside the class of Mordor, and then initialize an instance of the mission right there and then... 

```
public class Mordor 
{ 
    public void EnterAndExecute(Fellowship theFellowship) 
    { 
        theFellowship.DiscussSauron(); 
        theFellowship.ComeUpWithIdeaOfDestroyingRing(); 
        var mission  = new DropTheRingInPit(new Frodo()); 
        mission.ExecuteMission(); 
    } 
} 
```

So umm 😑... In this instance we can see that the fellowship clearly considers Mordor as a coffee shop to talk about things and relax in, if we spelled Mordor backwards it would say Starbucks. However, what if the mission needs to change half way through (during run time) and not just during it’s conception (during compile time)?

```
public class Mordor
{ 
    private readonly IMission _mission; 
    public MordorDIP(IMission mission) 
    { 
        _mission = mission; 
    }

    public void EnterAndExecute(List<IHobbit> hobbits) 
    { 
        _mission.ExecuteMission(); 
    } 
} 
```

Here we can see how the mission, whatever it is, is less coupled to the class Mordor than before. We go into Mordor already knowing what we need to do (details depending on abstractions here). No one goes in there to find that out later. I left the list of hobbits as an argument in there to consider what the hobbits would be doing before the `_mission` line is executed, I.e Smeagol (who technically was from a race that birthed hobbits) squabbling with Frodo and Samwise about the ring.

I always found it fun to look at programming concepts and relate to scenarios in films or items in real life, granted I can be labelled as weird for it but hey ho what can you do. I hope you enjoyed this and I wasted your time in a charming way 😂 But thank you for taking the time to do so and I hope to do more of these in the future! 

Let me know if you agree, disagree and if you can see other parts in LOTR that resonate with one of the SOLID principles!