Skip to content

Commit 00715a0

Browse files
Jill BalzanoJill Balzano
authored andcommitted
Initial commit
0 parents  commit 00715a0

File tree

174 files changed

+21848
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+21848
-0
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

9781484261798.jpg

29 KB
Loading
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using DotNetDesignPatternDemos.Behavioral.ChainOfResponsibility.MethodChain;
4+
using static System.Console;
5+
6+
namespace DotNetDesignPatternDemos.Behavioral.ChainOfResponsibility.ModifierChain.BrokerChain
7+
{
8+
// command query separation is being used here
9+
10+
public class Query
11+
{
12+
public string CreatureName;
13+
14+
public enum Argument
15+
{
16+
Attack, Defense
17+
}
18+
19+
public Argument WhatToQuery;
20+
21+
public int Value; // bidirectional
22+
23+
public Query(string creatureName, Argument whatToQuery, int value)
24+
{
25+
CreatureName = creatureName;
26+
WhatToQuery = whatToQuery;
27+
Value = value;
28+
}
29+
}
30+
31+
public class Game // mediator pattern
32+
{
33+
public event EventHandler<Query> Queries; // effectively a chain
34+
35+
public void PerformQuery(object sender, Query q)
36+
{
37+
Queries?.Invoke(sender, q);
38+
}
39+
}
40+
41+
public class Creature
42+
{
43+
private readonly Game game;
44+
public string Name;
45+
private readonly int attack;
46+
private readonly int defense;
47+
48+
public Creature(Game game, string name, int attack, int defense)
49+
{
50+
this.game = game;
51+
this.Name = name;
52+
this.attack = attack;
53+
this.defense = defense;
54+
}
55+
56+
public int Attack
57+
{
58+
get
59+
{
60+
var q = new Query(Name, Query.Argument.Attack, attack);
61+
game.PerformQuery(this, q);
62+
return q.Value;
63+
}
64+
}
65+
66+
public int Defense
67+
{
68+
get
69+
{
70+
var q = new Query(Name, Query.Argument.Defense, defense);
71+
game.PerformQuery(this, q);
72+
return q.Value;
73+
}
74+
}
75+
76+
public override string ToString() // no game
77+
{
78+
return $"{nameof(Name)}: {Name}, " +
79+
$"{nameof(attack)}: {Attack}, " +
80+
$"{nameof(defense)}: {Defense}";
81+
// ^^^^^^ using a property ^^^^^^^^^
82+
}
83+
}
84+
85+
public abstract class CreatureModifier : IDisposable
86+
{
87+
protected readonly Game game;
88+
protected readonly Creature creature;
89+
90+
protected CreatureModifier(Game game, Creature creature)
91+
{
92+
this.game = game;
93+
this.creature = creature;
94+
game.Queries += Handle;
95+
}
96+
97+
protected abstract void Handle(object sender, Query q);
98+
99+
public void Dispose()
100+
{
101+
game.Queries -= Handle;
102+
}
103+
}
104+
105+
public class DoubleAttackModifier : CreatureModifier
106+
{
107+
public DoubleAttackModifier(Game game, Creature creature)
108+
: base(game, creature) {}
109+
110+
protected override void Handle(object sender, Query q)
111+
{
112+
if (q.CreatureName == creature.Name &&
113+
q.WhatToQuery == Query.Argument.Attack)
114+
q.Value *= 2;
115+
}
116+
}
117+
118+
public class IncreaseDefenseModifier : CreatureModifier
119+
{
120+
public IncreaseDefenseModifier(Game game, Creature creature) : base(game, creature)
121+
{
122+
}
123+
124+
protected override void Handle(object sender, Query q)
125+
{
126+
if (q.CreatureName == creature.Name &&
127+
q.WhatToQuery == Query.Argument.Defense)
128+
q.Value += 2;
129+
}
130+
}
131+
132+
public class Demo
133+
{
134+
public static void Main()
135+
{
136+
var game = new Game();
137+
var goblin = new Creature(game, "Strong Goblin", 2, 2);
138+
WriteLine(goblin);
139+
140+
using (new DoubleAttackModifier(game, goblin))
141+
{
142+
WriteLine(goblin);
143+
using (new IncreaseDefenseModifier(game, goblin))
144+
{
145+
WriteLine(goblin);
146+
}
147+
}
148+
149+
WriteLine(goblin);
150+
}
151+
}
152+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using NUnit.Framework;
4+
5+
namespace DotNetDesignPatternDemos.Behavioral.ChainOfResponsibility
6+
{
7+
namespace Coding.Exercise
8+
{
9+
public abstract class Creature
10+
{
11+
protected Game game;
12+
protected readonly int baseAttack;
13+
protected readonly int baseDefense;
14+
15+
protected Creature(Game game, int baseAttack, int baseDefense)
16+
{
17+
this.game = game;
18+
this.baseAttack = baseAttack;
19+
this.baseDefense = baseDefense;
20+
}
21+
22+
public virtual int Attack { get; set; }
23+
public virtual int Defense { get; set; }
24+
public abstract void Query(object source, StatQuery sq);
25+
}
26+
27+
public class Goblin : Creature
28+
{
29+
public override void Query(object source, StatQuery sq)
30+
{
31+
if (ReferenceEquals(source, this))
32+
{
33+
switch (sq.Statistic)
34+
{
35+
case Statistic.Attack:
36+
sq.Result += baseAttack;
37+
break;
38+
case Statistic.Defense:
39+
sq.Result += baseDefense;
40+
break;
41+
default:
42+
throw new ArgumentOutOfRangeException();
43+
}
44+
}
45+
else
46+
{
47+
if (sq.Statistic == Statistic.Defense)
48+
{
49+
sq.Result++;
50+
}
51+
}
52+
}
53+
54+
public override int Defense
55+
{
56+
get
57+
{
58+
var q = new StatQuery {Statistic = Statistic.Defense};
59+
foreach (var c in game.Creatures)
60+
c.Query(this, q);
61+
return q.Result;
62+
}
63+
}
64+
65+
public override int Attack
66+
{
67+
get
68+
{
69+
var q = new StatQuery {Statistic = Statistic.Attack};
70+
foreach (var c in game.Creatures)
71+
c.Query(this, q);
72+
return q.Result;
73+
}
74+
}
75+
76+
public Goblin(Game game) : base(game, 1, 1)
77+
{
78+
}
79+
80+
protected Goblin(Game game, int baseAttack, int baseDefense)
81+
: base(game, baseAttack, baseDefense)
82+
{
83+
}
84+
}
85+
86+
public class GoblinKing : Goblin
87+
{
88+
public GoblinKing(Game game) : base(game, 3, 3)
89+
{
90+
}
91+
92+
public override void Query(object source, StatQuery sq)
93+
{
94+
if (!ReferenceEquals(source, this)
95+
&& sq.Statistic == Statistic.Attack)
96+
{
97+
sq.Result++; // every goblin gets +1 attack
98+
}
99+
else base.Query(source, sq);
100+
}
101+
}
102+
103+
public enum Statistic
104+
{
105+
Attack,
106+
Defense
107+
}
108+
109+
public class StatQuery
110+
{
111+
public Statistic Statistic;
112+
public int Result;
113+
}
114+
115+
public class Game
116+
{
117+
public IList<Creature> Creatures = new List<Creature>();
118+
}
119+
}
120+
121+
namespace Coding.Exercise.Tests
122+
{
123+
[TestFixture]
124+
public class TestSuite
125+
{
126+
[Test]
127+
public void ManyGoblinsTest()
128+
{
129+
var game = new Game();
130+
var goblin = new Goblin(game);
131+
game.Creatures.Add(goblin);
132+
133+
Assert.That(goblin.Attack, Is.EqualTo(1));
134+
Assert.That(goblin.Defense, Is.EqualTo(1));
135+
136+
var goblin2 = new Goblin(game);
137+
game.Creatures.Add(goblin2);
138+
139+
Assert.That(goblin.Attack, Is.EqualTo(1));
140+
Assert.That(goblin.Defense, Is.EqualTo(2));
141+
142+
var goblin3 = new GoblinKing(game);
143+
game.Creatures.Add(goblin3);
144+
145+
Assert.That(goblin.Attack, Is.EqualTo(2));
146+
Assert.That(goblin.Defense, Is.EqualTo(3));
147+
}
148+
}
149+
}
150+
}

0 commit comments

Comments
 (0)