patterncsharpMinor
Comparison between two design battle approaches
Viewed 0 times
battledesigncomparisontwobetweenapproaches
Problem
I've recently been learning about design patterns. Now I decided that I know enough to be able to refactor my inventory code. The question solely exist so I could show my fellow programmers the kind of destructive and lame mindset you'd get out of OOP, SOLID etc.
In an inventory, there are items. Wherever there are items, there's adding and swapping items. In my inventory, there's more than one way to add or swap items -
Currently, I have all those methods in my
I came up with an interesting system, which I think is SOLID. It's a mixture of the strategy and a bit of factor method patterns.
Usage:
The idea, is that you have a
Different strategies have different arguments, that's why a custom
Diagram:
Code:
(This is the main part - the bottom left part of the diagram)
```
public abstract class Args
{
}
public abstract class Strategy
{
public abstract bool Implement(Args args);
}
public static class StrategyCreator
{
static public T Create() where T : Strategy, new()
{
return new T();
}
}
public abstract class StrategyImplementor where T : Strategy
{
private Dictionary dic = new Dictionary();
protected bool Implement(Args args) where
Adder.Add(new CoolAddArgs(1, 2, 3, etc) instead of the simple function CoolAdd(1, 2, 3, etc) is just absurd.In an inventory, there are items. Wherever there are items, there's adding and swapping items. In my inventory, there's more than one way to add or swap items -
NormalAdd, ForceAdd, MouseSwapAdd, etc. SnapSwap, HoldSwap, etc. (Video)Currently, I have all those methods in my
ItemsBag. I decided to move them outside, to an Adder/Swapper.I came up with an interesting system, which I think is SOLID. It's a mixture of the strategy and a bit of factor method patterns.
Usage:
Adder adder = new Adder();
adder.Add(new NormalAddArgs(1, item, slot));
adder.Add(new ForceAddArgs(index));
Swapper swapper = new Swapper();
swapper.Swap(new SnapSwapArgs(1, 2, 3, etc));
swapper.Swap(new HoldSwapArgs("", 1));The idea, is that you have a
Strategy that does something, given an Args. Now Adder and Swapper are StrategyImplementers.Adderis anAddingStrategyimplementer.
NormalAddandForceAddareAddingStrategy.
Swapperon the other hand, is aSwappingStrategyimplementer.
Different strategies have different arguments, that's why a custom
Args object has to be created.Diagram:
Code:
(This is the main part - the bottom left part of the diagram)
```
public abstract class Args
{
}
public abstract class Strategy
{
public abstract bool Implement(Args args);
}
public static class StrategyCreator
{
static public T Create() where T : Strategy, new()
{
return new T();
}
}
public abstract class StrategyImplementor where T : Strategy
{
private Dictionary dic = new Dictionary();
protected bool Implement(Args args) where
Solution
As an exercise, I think your evaluation is fair - by all means, carry on. I think it's worth mentioning, though, that in terms of production, the factors you've enumerated aren't all weighted equally.
At the end of the day, if your code is totally DRY, you can go home happy. DRY (don't repeat yourself) implies that every datum about how your system works is located in exactly one place in your source. You can't make readable, DRY code difficult to extend - there's only one place to make a change. The "code inertia" as I like to call it, as measured in keystrokes per behavior difference, is at its minimum.
Beyond that point, any addition of complexity should be driven by necessity only. If the system outside of your adders and swappers evolves such that the simpler design cannot logically suffice, that's when you can think about picking apart the simplest thing that could possibly work. If your simpler design is DRY, there is minimal risk in leaving it alone. Complexity, on the other hand, is always a cost - it's work expanding to fill available time, and it's more time you have to spend training someone when you get promoted before they can test/maintain/extend your code.
Since I don't see egregious repetition in either design, I would therefore prefer the simpler one.
At the end of the day, if your code is totally DRY, you can go home happy. DRY (don't repeat yourself) implies that every datum about how your system works is located in exactly one place in your source. You can't make readable, DRY code difficult to extend - there's only one place to make a change. The "code inertia" as I like to call it, as measured in keystrokes per behavior difference, is at its minimum.
Beyond that point, any addition of complexity should be driven by necessity only. If the system outside of your adders and swappers evolves such that the simpler design cannot logically suffice, that's when you can think about picking apart the simplest thing that could possibly work. If your simpler design is DRY, there is minimal risk in leaving it alone. Complexity, on the other hand, is always a cost - it's work expanding to fill available time, and it's more time you have to spend training someone when you get promoted before they can test/maintain/extend your code.
Since I don't see egregious repetition in either design, I would therefore prefer the simpler one.
Context
StackExchange Code Review Q#35807, answer score: 7
Revisions (0)
No revisions yet.