├── .gitignore ├── DesignPatterns.sln ├── DesignPatterns ├── DesignPatterns.csproj ├── GangOfFour │ ├── Behavioral │ │ ├── ChainOfResponsibility │ │ │ ├── ConcreteHandler1.cs │ │ │ ├── ConcreteHandler2.cs │ │ │ ├── ConcreteHandler3.cs │ │ │ ├── Handler.cs │ │ │ └── Tests │ │ │ │ └── ChainOfResponsibilityTest.cs │ │ ├── Command │ │ │ ├── CloseSwitchCommand.cs │ │ │ ├── ICommand.cs │ │ │ ├── ISwitchable.cs │ │ │ ├── Light.cs │ │ │ ├── OpenSwitchCommand .cs │ │ │ ├── Switch.cs │ │ │ └── Tests │ │ │ │ └── CommandTest.cs │ │ ├── Interpreter │ │ │ ├── AddExpression.cs │ │ │ ├── IExpression.cs │ │ │ ├── NumberExpression.cs │ │ │ ├── SubtractExpression.cs │ │ │ ├── Tests │ │ │ │ └── InterpreterTest.cs │ │ │ └── TokenReader.cs │ │ ├── Iterator │ │ │ ├── Collection.cs │ │ │ ├── ICollection.cs │ │ │ ├── IIterator.cs │ │ │ ├── Iterator.cs │ │ │ └── Tests │ │ │ │ └── IteratorTest.cs │ │ ├── Mediator │ │ │ ├── Colleague.cs │ │ │ ├── IColleague.cs │ │ │ ├── IMediator.cs │ │ │ ├── Mediator.cs │ │ │ └── Tests │ │ │ │ └── MediatorTest.cs │ │ ├── Memento │ │ │ ├── CareTaker.cs │ │ │ ├── Memento.cs │ │ │ ├── Originator.cs │ │ │ └── Tests │ │ │ │ └── MementoTest.cs │ │ ├── Observer │ │ │ ├── IObserver.cs │ │ │ ├── ISubject.cs │ │ │ ├── Observer.cs │ │ │ ├── Subject.cs │ │ │ └── Tests │ │ │ │ └── ObserverTest.cs │ │ ├── State │ │ │ ├── GreenLight.cs │ │ │ ├── ITrafficLightState.cs │ │ │ ├── RedLight.cs │ │ │ ├── RedYellowLight.cs │ │ │ ├── Tests │ │ │ │ └── StateTest.cs │ │ │ ├── TrafficLight.cs │ │ │ └── YellowLight.cs │ │ ├── Strategy │ │ │ ├── ISortStrategy.cs │ │ │ ├── MergeSort.cs │ │ │ ├── QuickSort.cs │ │ │ ├── ShellSort.cs │ │ │ ├── SortedList.cs │ │ │ └── Tests │ │ │ │ └── StrategyTest.cs │ │ ├── TemplateMethod │ │ │ ├── DataExporter.cs │ │ │ ├── ExcelExporter.cs │ │ │ ├── PdfExporter.cs │ │ │ └── Tests │ │ │ │ └── TemplateMethodTest.cs │ │ └── Visitor │ │ │ ├── BoldText.cs │ │ │ ├── Document.cs │ │ │ ├── DocumentPart.cs │ │ │ ├── HtmlVisitor.cs │ │ │ ├── Hyperlink.cs │ │ │ ├── IVisitor.cs │ │ │ ├── LatexVisitor.cs │ │ │ ├── PlainText.cs │ │ │ └── Tests │ │ │ └── VisitorTest.cs │ ├── Creational │ │ ├── AbstractFactory │ │ │ ├── IButton.cs │ │ │ ├── IContextMenu.cs │ │ │ ├── IGuiFactory.cs │ │ │ ├── IWindow.cs │ │ │ ├── OSX │ │ │ │ ├── Button.cs │ │ │ │ ├── ContextMenu.cs │ │ │ │ ├── GuiFactory.cs │ │ │ │ └── Window.cs │ │ │ ├── Tests │ │ │ │ └── AbstractFactoryTest.cs │ │ │ └── Windows │ │ │ │ ├── Button.cs │ │ │ │ ├── ContextMenu.cs │ │ │ │ ├── GuiFactory.cs │ │ │ │ └── Window.cs │ │ ├── Builder │ │ │ ├── AudiA8CarBuilder.cs │ │ │ ├── Car.cs │ │ │ ├── CarBuilderDirector.cs │ │ │ ├── ICar.cs │ │ │ ├── ICarBuilder.cs │ │ │ └── Tests │ │ │ │ └── BuilderTest.cs │ │ ├── FactoryMethod │ │ │ ├── Audi.cs │ │ │ ├── AudiFactory.cs │ │ │ ├── BMWFactory.cs │ │ │ ├── Bmw.cs │ │ │ ├── ICar.cs │ │ │ ├── ICarFactory.cs │ │ │ └── Tests │ │ │ │ └── FactoryMethodTest.cs │ │ ├── Prototype │ │ │ ├── ConcretePrototype1.cs │ │ │ ├── ConcretePrototype2.cs │ │ │ ├── Prototype.cs │ │ │ └── Tests │ │ │ │ └── PrototypeTest.cs │ │ └── Singleton │ │ │ ├── Singleton.cs │ │ │ ├── Tests │ │ │ ├── SingletonTest.cs │ │ │ └── ThreadSafeSingletonTest.cs │ │ │ └── ThreadSafeSingleton.cs │ └── Structural │ │ ├── Adapter │ │ ├── Book.cs │ │ ├── EBookAdapter.cs │ │ ├── IEBook.cs │ │ ├── IPaperBook.cs │ │ ├── Kindle.cs │ │ └── Tests │ │ │ └── AdapterTest.cs │ │ ├── Bridge │ │ ├── Circle.cs │ │ ├── DrawingApi1.cs │ │ ├── DrawingApi2.cs │ │ ├── IDrawingApi.cs │ │ ├── IShape.cs │ │ └── Tests │ │ │ └── BridgeTest.cs │ │ ├── Composite │ │ ├── Form.cs │ │ ├── IFormElement.cs │ │ ├── InputElement.cs │ │ ├── Tests │ │ │ └── CompositeTest.cs │ │ └── TextElement.cs │ │ ├── Decorator │ │ ├── HorizontalScrollBarDecorator .cs │ │ ├── IWindow.cs │ │ ├── SimpleWindow.cs │ │ ├── Tests │ │ │ └── DecoratorTest.cs │ │ ├── VerticalScrollBarDecorator.cs │ │ └── WindowDecorator.cs │ │ ├── Facade │ │ ├── Computer.cs │ │ ├── IBios.cs │ │ ├── IOs.cs │ │ └── Tests │ │ │ └── FacadeTest.cs │ │ ├── Flyweight │ │ ├── Circle.cs │ │ ├── CircleFactory.cs │ │ ├── IShape.cs │ │ └── Tests │ │ │ └── FlyweightTest.cs │ │ └── Proxy │ │ ├── Car.cs │ │ ├── CarProxy.cs │ │ ├── Driver.cs │ │ ├── ICar.cs │ │ └── Tests │ │ └── ProxyTest.cs ├── Other │ ├── Behavioral │ │ ├── NullObject │ │ │ ├── ConsoleLogger.cs │ │ │ ├── ILogger.cs │ │ │ ├── NullLogger.cs │ │ │ ├── Service.cs │ │ │ └── Tests │ │ │ │ └── NullLoggerTest.cs │ │ └── Specification │ │ │ ├── Base │ │ │ ├── AndNotSpecification.cs │ │ │ ├── AndSpecification.cs │ │ │ ├── CompositeSpecification.cs │ │ │ ├── ISpecification.cs │ │ │ ├── NotSpecification.cs │ │ │ ├── OrNotSpecification.cs │ │ │ └── OrSpecification.cs │ │ │ ├── InCollectionSpecification.cs │ │ │ ├── Invoice.cs │ │ │ ├── NoticeSentSpecification.cs │ │ │ ├── OverDueSpecification.cs │ │ │ └── Tests │ │ │ └── SpecificationTest.cs │ └── Creational │ │ ├── ObjectPool │ │ ├── Pool.cs │ │ ├── PooledObject.cs │ │ └── Tests │ │ │ └── ObjectPoolTest.cs │ │ └── SimpleFactory │ │ ├── Audi.cs │ │ ├── Bmw.cs │ │ ├── CarFactory.cs │ │ ├── ICar.cs │ │ └── Tests │ │ └── SimpleFactoryTest.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /obj/Debug 6 | /.vs/DesignPatterns/v14 7 | /packages/NUnit.3.2.1 8 | /bin/Debug 9 | /Tests/obj/Debug 10 | /Tests/bin/Debug 11 | /DesignPatterns/obj/Debug 12 | /DesignPatterns/bin/Debug 13 | /packages/Moq.4.2.1510.2205/lib 14 | /packages/Moq.4.2.1510.2205 15 | -------------------------------------------------------------------------------- /DesignPatterns.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignPatterns", "DesignPatterns\DesignPatterns.csproj", "{B75365E6-B18A-4B81-957E-0863DB236D69}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B75365E6-B18A-4B81-957E-0863DB236D69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B75365E6-B18A-4B81-957E-0863DB236D69}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B75365E6-B18A-4B81-957E-0863DB236D69}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B75365E6-B18A-4B81-957E-0863DB236D69}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /DesignPatterns/DesignPatterns.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B75365E6-B18A-4B81-957E-0863DB236D69} 8 | Library 9 | Properties 10 | DesignPatterns 11 | DesignPatterns 12 | v4.6.1 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll 35 | True 36 | 37 | 38 | ..\packages\NUnit.3.2.1\lib\net45\nunit.framework.dll 39 | True 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 226 | -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/ChainOfResponsibility/ConcreteHandler1.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.ChainOfResponsibility 2 | { 3 | using System; 4 | 5 | public class ConcreteHandler1 : Handler 6 | { 7 | public override void HandleRequest(int request) 8 | { 9 | if (request >= 0 && request < 10) 10 | { 11 | Console.WriteLine("{0} handled request: {1}.", this.GetType().Name, request); 12 | } 13 | else if (this.Successor != null) 14 | { 15 | this.Successor.HandleRequest(request); 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/ChainOfResponsibility/ConcreteHandler2.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.ChainOfResponsibility 2 | { 3 | using System; 4 | 5 | public class ConcreteHandler2 : Handler 6 | { 7 | public override void HandleRequest(int request) 8 | { 9 | if (request >= 10 && request < 20) 10 | { 11 | Console.WriteLine("{0} handled request: {1}.", this.GetType().Name, request); 12 | } 13 | else if (this.Successor != null) 14 | { 15 | this.Successor.HandleRequest(request); 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/ChainOfResponsibility/ConcreteHandler3.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.ChainOfResponsibility 2 | { 3 | using System; 4 | 5 | public class ConcreteHandler3 : Handler 6 | { 7 | public override void HandleRequest(int request) 8 | { 9 | if (request >= 20 && request < 30) 10 | { 11 | Console.WriteLine("{0} handled request: {1}.", this.GetType().Name, request); 12 | } 13 | else if (this.Successor != null) 14 | { 15 | this.Successor.HandleRequest(request); 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/ChainOfResponsibility/Handler.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.ChainOfResponsibility 2 | { 3 | public abstract class Handler 4 | { 5 | public Handler Successor { get; set; } 6 | 7 | public abstract void HandleRequest(int request); 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/ChainOfResponsibility/Tests/ChainOfResponsibilityTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.ChainOfResponsibility.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.ChainOfResponsibility; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class ChainOfResponsibilityTest 9 | { 10 | [TestCase(1)] 11 | [TestCase(12)] 12 | [TestCase(23)] 13 | public void TestChainOfResponsibility(int request) 14 | { 15 | var handler1 = new ConcreteHandler1(); 16 | var handler2 = new ConcreteHandler2(); 17 | var handler3 = new ConcreteHandler3(); 18 | 19 | handler1.Successor = handler2; 20 | handler2.Successor = handler3; 21 | 22 | handler1.HandleRequest(request); 23 | 24 | // OUTPUT: ConcreteHandler1 handled request: 1. 25 | 26 | // OUTPUT: ConcreteHandler2 handled request: 12. 27 | 28 | // OUTPUT: ConcreteHandler3 handled request: 23. 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Command/CloseSwitchCommand.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Command 2 | { 3 | public class CloseSwitchCommand : ICommand 4 | { 5 | private readonly ISwitchable switchable; 6 | 7 | public CloseSwitchCommand(ISwitchable switchable) 8 | { 9 | this.switchable = switchable; 10 | } 11 | 12 | public void Execute() 13 | { 14 | this.switchable.PowerOff(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Command/ICommand.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Command 2 | { 3 | public interface ICommand 4 | { 5 | void Execute(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Command/ISwitchable.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Command 2 | { 3 | public interface ISwitchable 4 | { 5 | void PowerOff(); 6 | 7 | void PowerOn(); 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Command/Light.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Command 2 | { 3 | using System; 4 | 5 | public class Light : ISwitchable 6 | { 7 | public void PowerOff() 8 | { 9 | Console.WriteLine("The light is off."); 10 | } 11 | 12 | public void PowerOn() 13 | { 14 | Console.WriteLine("The light is on."); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Command/OpenSwitchCommand .cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Command 2 | { 3 | public class OpenSwitchCommand : ICommand 4 | { 5 | private readonly ISwitchable switchable; 6 | 7 | public OpenSwitchCommand(ISwitchable switchable) 8 | { 9 | this.switchable = switchable; 10 | } 11 | 12 | public void Execute() 13 | { 14 | this.switchable.PowerOn(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Command/Switch.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Command 2 | { 3 | public class Switch 4 | { 5 | private readonly ICommand closeCommand; 6 | 7 | private readonly ICommand openCommand; 8 | 9 | public Switch(ICommand closeCommand, ICommand openCommand) 10 | { 11 | this.closeCommand = closeCommand; 12 | this.openCommand = openCommand; 13 | } 14 | 15 | public void Close() 16 | { 17 | this.closeCommand.Execute(); 18 | } 19 | 20 | public void Open() 21 | { 22 | this.openCommand.Execute(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Command/Tests/CommandTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Command.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.Command; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class CommandTest 9 | { 10 | [Test] 11 | public void TestCommand() 12 | { 13 | var lamp = new Light(); 14 | var closeCommand = new CloseSwitchCommand(lamp); 15 | var openCommand = new OpenSwitchCommand(lamp); 16 | var @switch = new Switch(closeCommand, openCommand); 17 | 18 | @switch.Open(); 19 | 20 | // OUTPUT: The light is on. 21 | 22 | @switch.Close(); 23 | 24 | // OUTPUT: The light is off. 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Interpreter/AddExpression.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Interpreter 2 | { 3 | public class AddExpression : IExpression 4 | { 5 | private readonly IExpression leftExpression; 6 | 7 | private readonly IExpression rightExpression; 8 | 9 | public AddExpression(IExpression leftExpression, IExpression rightExpression) 10 | { 11 | this.leftExpression = leftExpression; 12 | this.rightExpression = rightExpression; 13 | } 14 | 15 | public int Interpret() 16 | { 17 | return this.leftExpression.Interpret() + this.rightExpression.Interpret(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Interpreter/IExpression.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Interpreter 2 | { 3 | public interface IExpression 4 | { 5 | int Interpret(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Interpreter/NumberExpression.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Interpreter 2 | { 3 | public class NumberExpression : IExpression 4 | { 5 | private readonly int number; 6 | 7 | public NumberExpression(int number) 8 | { 9 | this.number = number; 10 | } 11 | 12 | public int Interpret() 13 | { 14 | return this.number; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Interpreter/SubtractExpression.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Interpreter 2 | { 3 | public class SubtractExpression : IExpression 4 | { 5 | private readonly IExpression leftExpression; 6 | 7 | private readonly IExpression rightExpression; 8 | 9 | public SubtractExpression(IExpression leftExpression, IExpression rightExpression) 10 | { 11 | this.leftExpression = leftExpression; 12 | this.rightExpression = rightExpression; 13 | } 14 | 15 | public int Interpret() 16 | { 17 | return this.leftExpression.Interpret() - this.rightExpression.Interpret(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Interpreter/Tests/InterpreterTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Interpreter.Tests 2 | { 3 | using System.Collections.Generic; 4 | 5 | using DesignPatterns.GangOfFour.Behavioral.Interpreter; 6 | 7 | using NUnit.Framework; 8 | 9 | [TestFixture] 10 | public class InterpreterTest 11 | { 12 | [TestCase("+ 10 2", 12)] 13 | [TestCase("+ - 10 2 3", 11)] 14 | [TestCase("- + 10 5 - 8 2", 9)] 15 | public void TestInterpreter(string tokenString, int expectedResult) 16 | { 17 | var tokenList = new List(tokenString.Split(' ')); 18 | var expression = new TokenReader().ReadToken(tokenList); 19 | 20 | Assert.That(expression.Interpret(), Is.EqualTo(expectedResult)); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Interpreter/TokenReader.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Interpreter 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class TokenReader 6 | { 7 | public IExpression ReadToken(List tokenList) 8 | { 9 | return this.ReadNextToken(tokenList); 10 | } 11 | 12 | private IExpression ReadNextToken(List tokenList) 13 | { 14 | int i; 15 | 16 | if (int.TryParse(tokenList[0], out i)) 17 | { 18 | tokenList.RemoveAt(0); 19 | 20 | return new NumberExpression(i); 21 | } 22 | 23 | return this.ReadNonTerminal(tokenList); 24 | } 25 | 26 | private IExpression ReadNonTerminal(List tokenList) 27 | { 28 | var token = tokenList[0]; 29 | tokenList.RemoveAt(0); 30 | 31 | var left = this.ReadNextToken(tokenList); 32 | var right = this.ReadNextToken(tokenList); 33 | 34 | switch (token) 35 | { 36 | case "+": 37 | return new AddExpression(left, right); 38 | case "-": 39 | return new SubtractExpression(left, right); 40 | default: 41 | return null; 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Iterator/Collection.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Iterator 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class Collection : ICollection 6 | { 7 | private readonly List items = new List(); 8 | 9 | public int Count 10 | { 11 | get 12 | { 13 | return this.items.Count; 14 | } 15 | } 16 | 17 | public object this[int index] 18 | { 19 | get 20 | { 21 | return this.items[index]; 22 | } 23 | 24 | set 25 | { 26 | this.items.Insert(index, value); 27 | } 28 | } 29 | 30 | public IIterator CreateIterator() 31 | { 32 | return new Iterator(this); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Iterator/ICollection.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Iterator 2 | { 3 | public interface ICollection 4 | { 5 | IIterator CreateIterator(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Iterator/IIterator.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Iterator 2 | { 3 | public interface IIterator 4 | { 5 | object CurrentItem(); 6 | 7 | object First(); 8 | 9 | bool IsDone(); 10 | 11 | object Next(); 12 | } 13 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Iterator/Iterator.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Iterator 2 | { 3 | public class Iterator : IIterator 4 | { 5 | private readonly Collection collection; 6 | 7 | private int current; 8 | 9 | public Iterator(Collection collection) 10 | { 11 | this.collection = collection; 12 | } 13 | 14 | public object CurrentItem() 15 | { 16 | return this.collection[this.current]; 17 | } 18 | 19 | public object First() 20 | { 21 | return this.collection[0]; 22 | } 23 | 24 | public bool IsDone() 25 | { 26 | return this.current >= this.collection.Count; 27 | } 28 | 29 | public object Next() 30 | { 31 | object result = null; 32 | 33 | if (++this.current < this.collection.Count) 34 | { 35 | result = this.collection[this.current]; 36 | } 37 | 38 | return result; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Iterator/Tests/IteratorTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Iterator.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.Iterator; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class IteratorTest 9 | { 10 | [Test] 11 | public void TestIterator() 12 | { 13 | var numbers = new[] { 11, 22, 33, 44 }; 14 | 15 | var collection = new Collection { [0] = numbers[0], [1] = numbers[1], [2] = numbers[2], [3] = numbers[3] }; 16 | 17 | var iterator = collection.CreateIterator(); 18 | var i = 0; 19 | 20 | for (var item = iterator.First(); !iterator.IsDone(); item = iterator.Next(), ++i) 21 | { 22 | Assert.That(item, Is.EqualTo(numbers[i])); 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Mediator/Colleague.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Mediator 2 | { 3 | using System; 4 | 5 | public class Colleague : IColleague 6 | { 7 | private readonly string name; 8 | 9 | public Colleague(string name) 10 | { 11 | this.name = name; 12 | } 13 | 14 | public void ReceiveMessage(T message) 15 | { 16 | Console.WriteLine(this.name + " received " + message + "."); 17 | } 18 | 19 | public void SendMessage(IMediator mediator, T message) 20 | { 21 | mediator.DistributeMessage(this, message); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Mediator/IColleague.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Mediator 2 | { 3 | public interface IColleague 4 | { 5 | void ReceiveMessage(T message); 6 | 7 | void SendMessage(IMediator mediator, T message); 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Mediator/IMediator.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Mediator 2 | { 3 | using System.Collections.Generic; 4 | 5 | public interface IMediator 6 | { 7 | List> ColleagueList { get; } 8 | 9 | void DistributeMessage(IColleague sender, T message); 10 | 11 | void Register(IColleague colleague); 12 | } 13 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Mediator/Mediator.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Mediator 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class Mediator : IMediator 6 | { 7 | public List> ColleagueList { get; } = new List>(); 8 | 9 | public void DistributeMessage(IColleague sender, T message) 10 | { 11 | foreach (var colleague in this.ColleagueList) 12 | { 13 | if (colleague != sender) 14 | { 15 | colleague.ReceiveMessage(message); 16 | } 17 | } 18 | } 19 | 20 | public void Register(IColleague colleague) 21 | { 22 | this.ColleagueList.Add(colleague); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Mediator/Tests/MediatorTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Mediator.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.Mediator; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class MediatorTest 9 | { 10 | [Test] 11 | public void TestMediator() 12 | { 13 | var mediator = new Mediator(); 14 | 15 | var colleague1 = new Colleague("Colleague 1"); 16 | var colleague2 = new Colleague("Colleague 2"); 17 | var colleague3 = new Colleague("Colleague 3"); 18 | 19 | mediator.Register(colleague1); 20 | mediator.Register(colleague2); 21 | mediator.Register(colleague3); 22 | 23 | colleague1.SendMessage(mediator, "Test message 1"); 24 | 25 | // OUTPUT: Colleague 2 received Test message 1. 26 | 27 | // OUTPUT: Colleague 3 received Test message 1. 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Memento/CareTaker.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Memento 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class CareTaker 6 | { 7 | private readonly List> savedStates = new List>(); 8 | 9 | public void AddMemento(Memento memento) 10 | { 11 | this.savedStates.Add(memento); 12 | } 13 | 14 | public Memento GetMemento(int index) 15 | { 16 | return this.savedStates[index]; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Memento/Memento.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Memento 2 | { 3 | public class Memento 4 | { 5 | public Memento(T state) 6 | { 7 | this.State = state; 8 | } 9 | 10 | public T State { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Memento/Originator.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Memento 2 | { 3 | public class Originator 4 | { 5 | public T State { get; set; } 6 | 7 | public void RestoreFromMemento(Memento memento) 8 | { 9 | this.State = memento.State; 10 | } 11 | 12 | public Memento SaveToMemento() 13 | { 14 | return new Memento(this.State); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Memento/Tests/MementoTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Memento.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.Memento; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class MementoTest 9 | { 10 | [Test] 11 | public void TestMemento() 12 | { 13 | var careTaker = new CareTaker(); 14 | var originator = new Originator(); 15 | 16 | originator.State = "State 1"; 17 | careTaker.AddMemento(originator.SaveToMemento()); 18 | 19 | originator.State = "State 2"; 20 | careTaker.AddMemento(originator.SaveToMemento()); 21 | 22 | originator.State = "State 3"; 23 | originator.RestoreFromMemento(careTaker.GetMemento(1)); 24 | 25 | Assert.That(originator.State, Is.EqualTo("State 2")); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Observer/IObserver.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Observer 2 | { 3 | public interface IObserver 4 | { 5 | void Update(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Observer/ISubject.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Observer 2 | { 3 | public interface ISubject 4 | { 5 | void Notify(); 6 | 7 | void Subscribe(IObserver observer); 8 | 9 | void Unsubscribe(IObserver observer); 10 | } 11 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Observer/Observer.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Observer 2 | { 3 | using System; 4 | 5 | public class Observer : IObserver 6 | { 7 | public Observer(string name) 8 | { 9 | this.Name = name; 10 | } 11 | 12 | public string Name { get; } 13 | 14 | public void Update() 15 | { 16 | Console.WriteLine("{0} receieved an update.", this.Name); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Observer/Subject.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Observer 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class Subject : ISubject 6 | { 7 | private readonly List observers = new List(); 8 | 9 | public void Notify() 10 | { 11 | foreach (var observer in this.observers) 12 | { 13 | observer.Update(); 14 | } 15 | } 16 | 17 | public void Subscribe(IObserver observer) 18 | { 19 | this.observers.Add(observer); 20 | } 21 | 22 | public void Unsubscribe(IObserver observer) 23 | { 24 | this.observers.Remove(observer); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Observer/Tests/ObserverTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Observer.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.Observer; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class ObserverTest 9 | { 10 | [Test] 11 | public void TestObserver() 12 | { 13 | var subject = new Subject(); 14 | 15 | var observer1 = new Observer("Observer 1"); 16 | var observer2 = new Observer("Observer 2"); 17 | 18 | subject.Subscribe(observer1); 19 | subject.Subscribe(observer2); 20 | 21 | subject.Notify(); 22 | 23 | // OUTPUT: Observer 1 receieved an update. 24 | 25 | // OUTPUT: Observer 2 receieved an update. 26 | 27 | subject.Unsubscribe(observer2); 28 | 29 | subject.Notify(); 30 | 31 | // OUTPUT: Observer 1 receieved an update. 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/State/GreenLight.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.State 2 | { 3 | using System; 4 | 5 | public class GreenLight : ITrafficLightState 6 | { 7 | public void Change(TrafficLight trafficLight) 8 | { 9 | trafficLight.State = new YellowLight(); 10 | } 11 | 12 | public void ReportState() 13 | { 14 | Console.WriteLine("Green light."); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/State/ITrafficLightState.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.State 2 | { 3 | public interface ITrafficLightState 4 | { 5 | void Change(TrafficLight trafficLight); 6 | 7 | void ReportState(); 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/State/RedLight.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.State 2 | { 3 | using System; 4 | 5 | public class RedLight : ITrafficLightState 6 | { 7 | public void Change(TrafficLight trafficLight) 8 | { 9 | trafficLight.State = new RedYellowLight(); 10 | } 11 | 12 | public void ReportState() 13 | { 14 | Console.WriteLine("Red light."); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/State/RedYellowLight.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.State 2 | { 3 | using System; 4 | 5 | public class RedYellowLight : ITrafficLightState 6 | { 7 | public void Change(TrafficLight trafficLight) 8 | { 9 | trafficLight.State = new GreenLight(); 10 | } 11 | 12 | public void ReportState() 13 | { 14 | Console.WriteLine("Red and yellow light."); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/State/Tests/StateTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.State.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.State; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class StateTest 9 | { 10 | [Test] 11 | public void TestState() 12 | { 13 | var trafficLight = new TrafficLight { State = new RedLight() }; 14 | trafficLight.ReportState(); 15 | 16 | for (var i = 0; i < 8; i++) 17 | { 18 | trafficLight.Change(); 19 | trafficLight.ReportState(); 20 | } 21 | 22 | // OUTPUT: Red light. 23 | 24 | // OUTPUT: Red and yellow light. 25 | 26 | // OUTPUT: Green light. 27 | 28 | // OUTPUT: Yellow light. 29 | 30 | // OUTPUT: Red light. 31 | 32 | // OUTPUT: Red and yellow light. 33 | 34 | // OUTPUT: Green light. 35 | 36 | // OUTPUT: Yellow light. 37 | 38 | // OUTPUT: Red light. 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/State/TrafficLight.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.State 2 | { 3 | public class TrafficLight 4 | { 5 | public ITrafficLightState State { get; set; } 6 | 7 | public void Change() 8 | { 9 | this.State.Change(this); 10 | } 11 | 12 | public void ReportState() 13 | { 14 | this.State.ReportState(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/State/YellowLight.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.State 2 | { 3 | using System; 4 | 5 | public class YellowLight : ITrafficLightState 6 | { 7 | public void Change(TrafficLight trafficLight) 8 | { 9 | trafficLight.State = new RedLight(); 10 | } 11 | 12 | public void ReportState() 13 | { 14 | Console.WriteLine("Yellow light."); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Strategy/ISortStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Strategy 2 | { 3 | using System.Collections.Generic; 4 | 5 | public interface ISortStrategy 6 | { 7 | void Sort(List items); 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Strategy/MergeSort.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Strategy 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | public class MergeSort : ISortStrategy 7 | { 8 | public void Sort(List items) 9 | { 10 | Console.WriteLine("Sorting list using MergeSort."); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Strategy/QuickSort.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Strategy 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | public class QuickSort : ISortStrategy 7 | { 8 | public void Sort(List items) 9 | { 10 | Console.WriteLine("Sorting list using QuickSort."); 11 | items.Sort(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Strategy/ShellSort.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Strategy 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | public class ShellSort : ISortStrategy 7 | { 8 | public void Sort(List items) 9 | { 10 | Console.WriteLine("Sorting list using ShellSort."); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Strategy/SortedList.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Strategy 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class SortedList 6 | { 7 | public List Items { get; } = new List(); 8 | 9 | public ISortStrategy SortStrategy { get; set; } 10 | 11 | public SortedList(ISortStrategy sortStrategy) 12 | { 13 | this.SortStrategy = sortStrategy; 14 | } 15 | 16 | public void Sort() 17 | { 18 | this.SortStrategy.Sort(this.Items); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Strategy/Tests/StrategyTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Strategy.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.Strategy; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class StrategyTest 9 | { 10 | [Test] 11 | public void TestStrategy() 12 | { 13 | var sortingStrategy = new QuickSort(); 14 | var list = new SortedList(sortingStrategy); 15 | 16 | list.Items.AddRange(new[] { "xyz", "abc", "ghi", "def" }); 17 | list.Sort(); 18 | 19 | // OUTPUT: Sorting list using QuickSort. 20 | 21 | list.SortStrategy = new MergeSort(); 22 | list.Sort(); 23 | 24 | // OUTPUT: Sorting list using MergeSort. 25 | 26 | list.SortStrategy = new ShellSort(); 27 | list.Sort(); 28 | 29 | // OUTPUT: Sorting list using ShellSort. 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/TemplateMethod/DataExporter.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.TemplateMethod 2 | { 3 | using System; 4 | 5 | public abstract class DataExporter 6 | { 7 | public abstract void ExportData(); 8 | 9 | public void ExportFormattedData() 10 | { 11 | this.ReadData(); 12 | this.FormatData(); 13 | this.ExportData(); 14 | } 15 | 16 | public void FormatData() 17 | { 18 | Console.WriteLine("Formatting data."); 19 | } 20 | 21 | public void ReadData() 22 | { 23 | Console.WriteLine("Reading data from external source."); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/TemplateMethod/ExcelExporter.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.TemplateMethod 2 | { 3 | using System; 4 | 5 | public class ExcelExporter : DataExporter 6 | { 7 | public override void ExportData() 8 | { 9 | Console.WriteLine("Exporting data to Excel file."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/TemplateMethod/PdfExporter.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.TemplateMethod 2 | { 3 | using System; 4 | 5 | public class PdfExporter : DataExporter 6 | { 7 | public override void ExportData() 8 | { 9 | Console.WriteLine("Exporting data to PDF file."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/TemplateMethod/Tests/TemplateMethodTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.TemplateMethod.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.TemplateMethod; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class TemplateMethodTest 9 | { 10 | [Test] 11 | public void TestTemplateMethod() 12 | { 13 | var excelExporter = new ExcelExporter(); 14 | excelExporter.ExportFormattedData(); 15 | 16 | // OUTPUT: Reading data from external source. 17 | 18 | // OUTPUT: Formatting data. 19 | 20 | // OUTPUT: Exporting data to Excel file. 21 | 22 | var pdfExporter = new PdfExporter(); 23 | pdfExporter.ExportFormattedData(); 24 | 25 | // OUTPUT: Reading data from external source. 26 | 27 | // OUTPUT: Formatting data. 28 | 29 | // OUTPUT: Exporting data to PDF file. 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Visitor/BoldText.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Visitor 2 | { 3 | public class BoldText : DocumentPart 4 | { 5 | public BoldText(string text) : base(text) 6 | { 7 | } 8 | 9 | public override void Accept(IVisitor visitor) 10 | { 11 | visitor.Visit(this); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Visitor/Document.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Visitor 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class Document 6 | { 7 | private readonly List parts = new List(); 8 | 9 | public void Accept(IVisitor visitor) 10 | { 11 | foreach (var part in this.parts) 12 | { 13 | part.Accept(visitor); 14 | } 15 | } 16 | 17 | public void AddPart(DocumentPart documentPart) 18 | { 19 | this.parts.Add(documentPart); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Visitor/DocumentPart.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Visitor 2 | { 3 | public abstract class DocumentPart 4 | { 5 | public DocumentPart(string text) 6 | { 7 | this.Text = text; 8 | } 9 | 10 | public string Text { get; private set; } 11 | 12 | public abstract void Accept(IVisitor visitor); 13 | } 14 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Visitor/HtmlVisitor.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Visitor 2 | { 3 | public class HtmlVisitor : IVisitor 4 | { 5 | public string Output { get; private set; } 6 | 7 | public void Visit(BoldText documentPart) 8 | { 9 | this.Output += "" + documentPart.Text + ""; 10 | } 11 | 12 | public void Visit(Hyperlink documentPart) 13 | { 14 | this.Output += "" + documentPart.Text + ""; 15 | } 16 | 17 | public void Visit(PlainText documentPart) 18 | { 19 | this.Output += documentPart.Text; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Visitor/Hyperlink.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Visitor 2 | { 3 | public class Hyperlink : DocumentPart 4 | { 5 | public Hyperlink(string text, string url) : base(text) 6 | { 7 | this.Url = url; 8 | } 9 | 10 | public string Url { get; private set; } 11 | 12 | public override void Accept(IVisitor visitor) 13 | { 14 | visitor.Visit(this); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Visitor/IVisitor.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Visitor 2 | { 3 | public interface IVisitor 4 | { 5 | void Visit(BoldText documentPart); 6 | 7 | void Visit(Hyperlink documentPart); 8 | 9 | void Visit(PlainText documentPart); 10 | } 11 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Visitor/LatexVisitor.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Visitor 2 | { 3 | public class LatexVisitor : IVisitor 4 | { 5 | public string Output { get; private set; } 6 | 7 | public void Visit(BoldText documentPart) 8 | { 9 | this.Output += "\\textbf{" + documentPart.Text + "}"; 10 | } 11 | 12 | public void Visit(Hyperlink documentPart) 13 | { 14 | this.Output += "\\href{" + documentPart.Url + "}{" + documentPart.Text + "}"; 15 | } 16 | 17 | public void Visit(PlainText documentPart) 18 | { 19 | this.Output += documentPart.Text; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Visitor/PlainText.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Visitor 2 | { 3 | public class PlainText : DocumentPart 4 | { 5 | public PlainText(string text) : base(text) 6 | { 7 | } 8 | 9 | public override void Accept(IVisitor visitor) 10 | { 11 | visitor.Visit(this); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Behavioral/Visitor/Tests/VisitorTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Behavioral.Visitor.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Behavioral.Visitor; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class VisitorTest 9 | { 10 | [Test] 11 | public void TestVisitor() 12 | { 13 | var document = new Document(); 14 | document.AddPart(new BoldText("This is bold text.")); 15 | document.AddPart(new PlainText("This is plain text.")); 16 | document.AddPart(new Hyperlink("This is hyperlink.", "http://www.example.com")); 17 | 18 | var htmlVisitor = new HtmlVisitor(); 19 | document.Accept(htmlVisitor); 20 | 21 | Assert.That( 22 | htmlVisitor.Output, 23 | Is.EqualTo("This is bold text.This is plain text.This is hyperlink.")); 24 | 25 | var latexVisitor = new LatexVisitor(); 26 | document.Accept(latexVisitor); 27 | 28 | Assert.That( 29 | latexVisitor.Output, 30 | Is.EqualTo("\\textbf{This is bold text.}This is plain text.\\href{http://www.example.com}{This is hyperlink.}")); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/IButton.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory 2 | { 3 | public interface IButton 4 | { 5 | void Render(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/IContextMenu.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory 2 | { 3 | public interface IContextMenu 4 | { 5 | void Render(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/IGuiFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory 2 | { 3 | public interface IGuiFactory 4 | { 5 | IButton CreateButton(); 6 | 7 | IContextMenu CreateContextMenu(); 8 | 9 | IWindow CreateWindow(); 10 | } 11 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/IWindow.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory 2 | { 3 | public interface IWindow 4 | { 5 | void Render(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/OSX/Button.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory.OSX 2 | { 3 | using System; 4 | 5 | public class Button : IButton 6 | { 7 | public void Render() 8 | { 9 | Console.WriteLine("Rendering OSX button."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/OSX/ContextMenu.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory.OSX 2 | { 3 | using System; 4 | 5 | public class ContextMenu : IContextMenu 6 | { 7 | public void Render() 8 | { 9 | Console.WriteLine("Rendering OSX context menu."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/OSX/GuiFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory.OSX 2 | { 3 | public class GuiFactory : IGuiFactory 4 | { 5 | public IButton CreateButton() 6 | { 7 | return new Button(); 8 | } 9 | 10 | public IContextMenu CreateContextMenu() 11 | { 12 | return new ContextMenu(); 13 | } 14 | 15 | public IWindow CreateWindow() 16 | { 17 | return new Window(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/OSX/Window.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory.OSX 2 | { 3 | using System; 4 | 5 | public class Window : IWindow 6 | { 7 | public void Render() 8 | { 9 | Console.WriteLine("Rendering OSX window."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/Tests/AbstractFactoryTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Creational.AbstractFactory; 4 | 5 | using NUnit.Framework; 6 | 7 | using OsxGuiFactory = DesignPatterns.GangOfFour.Creational.AbstractFactory.OSX.GuiFactory; 8 | 9 | using WindowsGuiFactory = DesignPatterns.GangOfFour.Creational.AbstractFactory.Windows.GuiFactory; 10 | 11 | [TestFixture] 12 | public class AbstractFactoryTest 13 | { 14 | private static readonly object[] TestCases = 15 | { 16 | new[] { new OsxGuiFactory() }, 17 | new[] { new WindowsGuiFactory() } 18 | }; 19 | 20 | [TestCaseSource(nameof(TestCases))] 21 | public void TestAbstractFactory(IGuiFactory guiFactory) 22 | { 23 | Assert.That(guiFactory.CreateButton(), Is.InstanceOf()); 24 | Assert.That(guiFactory.CreateContextMenu(), Is.InstanceOf()); 25 | Assert.That(guiFactory.CreateWindow(), Is.InstanceOf()); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/Windows/Button.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory.Windows 2 | { 3 | using System; 4 | 5 | public class Button : IButton 6 | { 7 | public void Render() 8 | { 9 | Console.WriteLine("Rendering Windows button."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/Windows/ContextMenu.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory.Windows 2 | { 3 | using System; 4 | 5 | public class ContextMenu : IContextMenu 6 | { 7 | public void Render() 8 | { 9 | Console.WriteLine("Rendering Windows context menu."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/Windows/GuiFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory.Windows 2 | { 3 | public class GuiFactory : IGuiFactory 4 | { 5 | public IButton CreateButton() 6 | { 7 | return new Button(); 8 | } 9 | 10 | public IContextMenu CreateContextMenu() 11 | { 12 | return new ContextMenu(); 13 | } 14 | 15 | public IWindow CreateWindow() 16 | { 17 | return new Window(); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/AbstractFactory/Windows/Window.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.AbstractFactory.Windows 2 | { 3 | using System; 4 | 5 | public class Window : IWindow 6 | { 7 | public void Render() 8 | { 9 | Console.WriteLine("Rendering Windows window."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Builder/AudiA8CarBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Builder 2 | { 3 | public class AudiA8CarBuilder : ICarBuilder 4 | { 5 | private readonly ICar car; 6 | 7 | public AudiA8CarBuilder() 8 | { 9 | this.car = new Car(); 10 | } 11 | 12 | public ICar BuildCar() 13 | { 14 | return this.car; 15 | } 16 | 17 | public ICarBuilder SetColor() 18 | { 19 | this.car.Color = "Blue"; 20 | 21 | return this; 22 | } 23 | 24 | public ICarBuilder SetEngineCapacity() 25 | { 26 | this.car.EngineCapacity = 3000; 27 | 28 | return this; 29 | } 30 | 31 | public ICarBuilder SetName() 32 | { 33 | this.car.Name = "Audi A8"; 34 | 35 | return this; 36 | } 37 | 38 | public ICarBuilder SetNumberOfDoors() 39 | { 40 | this.car.NumberOfDoors = 5; 41 | 42 | return this; 43 | } 44 | 45 | public ICarBuilder SetNumberOfSeats() 46 | { 47 | this.car.NumberOfSeats = 5; 48 | 49 | return this; 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Builder/Car.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Builder 2 | { 3 | using System; 4 | 5 | public class Car : ICar 6 | { 7 | public string Color { get; set; } 8 | 9 | public int EngineCapacity { get; set; } 10 | 11 | public string Name { get; set; } 12 | 13 | public int NumberOfDoors { get; set; } 14 | 15 | public int NumberOfSeats { get; set; } 16 | 17 | public void Drive() 18 | { 19 | Console.WriteLine("Driving common car."); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Builder/CarBuilderDirector.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Builder 2 | { 3 | public class CarBuilderDirector 4 | { 5 | private readonly ICarBuilder carBuilder; 6 | 7 | public CarBuilderDirector(ICarBuilder carBuilder) 8 | { 9 | this.carBuilder = carBuilder; 10 | } 11 | 12 | public ICar BuildCar() 13 | { 14 | return 15 | this.carBuilder.SetColor() 16 | .SetEngineCapacity() 17 | .SetName() 18 | .SetNumberOfDoors() 19 | .SetNumberOfSeats() 20 | .BuildCar(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Builder/ICar.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Builder 2 | { 3 | public interface ICar 4 | { 5 | string Color { get; set; } 6 | 7 | int EngineCapacity { get; set; } 8 | 9 | string Name { get; set; } 10 | 11 | int NumberOfDoors { get; set; } 12 | 13 | int NumberOfSeats { get; set; } 14 | 15 | void Drive(); 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Builder/ICarBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Builder 2 | { 3 | public interface ICarBuilder 4 | { 5 | ICar BuildCar(); 6 | 7 | ICarBuilder SetColor(); 8 | 9 | ICarBuilder SetEngineCapacity(); 10 | 11 | ICarBuilder SetName(); 12 | 13 | ICarBuilder SetNumberOfDoors(); 14 | 15 | ICarBuilder SetNumberOfSeats(); 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Builder/Tests/BuilderTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Builder.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Creational.Builder; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class BuilderTest 9 | { 10 | [Test] 11 | public void TestBuilder() 12 | { 13 | var carBuilderDirector = new CarBuilderDirector(new AudiA8CarBuilder()); 14 | var car = carBuilderDirector.BuildCar(); 15 | 16 | Assert.That(car.Color, Is.EqualTo("Blue")); 17 | Assert.That(car.EngineCapacity, Is.EqualTo(3000)); 18 | Assert.That(car.Name, Is.EqualTo("Audi A8")); 19 | Assert.That(car.NumberOfDoors, Is.EqualTo(5)); 20 | Assert.That(car.NumberOfSeats, Is.EqualTo(5)); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/FactoryMethod/Audi.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.FactoryMethod 2 | { 3 | using System; 4 | 5 | public class Audi : ICar 6 | { 7 | public void Drive() 8 | { 9 | Console.WriteLine("Driving Audi."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/FactoryMethod/AudiFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.FactoryMethod 2 | { 3 | public class AudiFactory : ICarFactory 4 | { 5 | public ICar BuildCar() 6 | { 7 | return new Audi(); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/FactoryMethod/BMWFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.FactoryMethod 2 | { 3 | public class BmwFactory : ICarFactory 4 | { 5 | public ICar BuildCar() 6 | { 7 | return new Bmw(); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/FactoryMethod/Bmw.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.FactoryMethod 2 | { 3 | using System; 4 | 5 | public class Bmw : ICar 6 | { 7 | public void Drive() 8 | { 9 | Console.WriteLine("Driving BMW."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/FactoryMethod/ICar.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.FactoryMethod 2 | { 3 | public interface ICar 4 | { 5 | void Drive(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/FactoryMethod/ICarFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.FactoryMethod 2 | { 3 | public interface ICarFactory 4 | { 5 | ICar BuildCar(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/FactoryMethod/Tests/FactoryMethodTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.FactoryMethod.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Creational.FactoryMethod; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class FactoryMethodTest 9 | { 10 | private static readonly object[] TestCases = 11 | { 12 | new[] { new AudiFactory() }, 13 | new[] { new BmwFactory() } 14 | }; 15 | 16 | [TestCaseSource(nameof(TestCases))] 17 | public void TestFactoryMethod(ICarFactory carFactory) 18 | { 19 | Assert.That(carFactory.BuildCar(), Is.InstanceOf()); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Prototype/ConcretePrototype1.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Prototype 2 | { 3 | public class ConcretePrototype1 : Prototype 4 | { 5 | public ConcretePrototype1(int id) 6 | : base(id) 7 | { 8 | } 9 | 10 | public override Prototype Clone() 11 | { 12 | return (Prototype)this.MemberwiseClone(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Prototype/ConcretePrototype2.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Prototype 2 | { 3 | public class ConcretePrototype2 : Prototype 4 | { 5 | public ConcretePrototype2(int id) 6 | : base(id) 7 | { 8 | } 9 | 10 | public override Prototype Clone() 11 | { 12 | return (Prototype)this.MemberwiseClone(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Prototype/Prototype.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Prototype 2 | { 3 | public abstract class Prototype 4 | { 5 | public Prototype(int id) 6 | { 7 | this.Id = id; 8 | } 9 | 10 | public int Id { get; private set; } 11 | 12 | public abstract Prototype Clone(); 13 | } 14 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Prototype/Tests/PrototypeTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Prototype.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Creational.Prototype; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class PrototypeTest 9 | { 10 | private static readonly object[] TestCases = 11 | { 12 | new[] { new ConcretePrototype1(123) }, 13 | new[] { new ConcretePrototype2(456) } 14 | }; 15 | 16 | [TestCaseSource(nameof(TestCases))] 17 | public void TestPrototype(Prototype prototype) 18 | { 19 | var newInstance = prototype.Clone(); 20 | 21 | Assert.That(newInstance.Id, Is.EqualTo(prototype.Id)); 22 | Assert.That(newInstance, Is.Not.EqualTo(prototype)); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Singleton/Singleton.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Singleton 2 | { 3 | public sealed class Singleton 4 | { 5 | private static Singleton instance; 6 | 7 | private Singleton() 8 | { 9 | } 10 | 11 | public static Singleton Instance 12 | { 13 | get 14 | { 15 | if (instance == null) 16 | { 17 | instance = new Singleton(); 18 | } 19 | 20 | return instance; 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Singleton/Tests/SingletonTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Singleton.Tests 2 | { 3 | using NUnit.Framework; 4 | 5 | [TestFixture] 6 | public class SingletonTest 7 | { 8 | [Test] 9 | public void TestOnlyOneInstanceIsCreated() 10 | { 11 | var instance1 = Singleton.Instance; 12 | var instance2 = Singleton.Instance; 13 | 14 | Assert.That(instance1, Is.EqualTo(instance2)); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Singleton/Tests/ThreadSafeSingletonTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Singleton.Tests 2 | { 3 | using NUnit.Framework; 4 | 5 | [TestFixture] 6 | public class ThreadSafeSingletonTest 7 | { 8 | [Test] 9 | public void TestOnlyOneInstanceIsCreated() 10 | { 11 | var instance1 = ThreadSafeSingleton.Instance; 12 | var instance2 = ThreadSafeSingleton.Instance; 13 | 14 | Assert.That(instance1, Is.EqualTo(instance2)); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Creational/Singleton/ThreadSafeSingleton.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Creational.Singleton 2 | { 3 | using System; 4 | 5 | public sealed class ThreadSafeSingleton 6 | { 7 | private static readonly Lazy Lazy = 8 | new Lazy(() => new ThreadSafeSingleton()); 9 | 10 | private ThreadSafeSingleton() 11 | { 12 | } 13 | 14 | public static ThreadSafeSingleton Instance 15 | { 16 | get 17 | { 18 | return Lazy.Value; 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Adapter/Book.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Adapter 2 | { 3 | using System; 4 | 5 | public class Book : IPaperBook 6 | { 7 | public void Open() 8 | { 9 | Console.WriteLine("Opening the book."); 10 | } 11 | 12 | public void TurnPage() 13 | { 14 | Console.WriteLine("Turning the page."); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Adapter/EBookAdapter.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Adapter 2 | { 3 | public class EbookAdapter : IPaperBook 4 | { 5 | private readonly IEbook ebook; 6 | 7 | public EbookAdapter(IEbook ebook) 8 | { 9 | this.ebook = ebook; 10 | } 11 | 12 | public void Open() 13 | { 14 | this.ebook.PressStart(); 15 | } 16 | 17 | public void TurnPage() 18 | { 19 | this.ebook.PressNext(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Adapter/IEBook.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Adapter 2 | { 3 | public interface IEbook 4 | { 5 | void PressNext(); 6 | 7 | void PressStart(); 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Adapter/IPaperBook.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Adapter 2 | { 3 | public interface IPaperBook 4 | { 5 | void Open(); 6 | 7 | void TurnPage(); 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Adapter/Kindle.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Adapter 2 | { 3 | using System; 4 | 5 | public class Kindle : IEbook 6 | { 7 | public void PressNext() 8 | { 9 | Console.WriteLine("Pressing \"Next page\" button."); 10 | } 11 | 12 | public void PressStart() 13 | { 14 | Console.WriteLine("Pressing \"Start\" button."); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Adapter/Tests/AdapterTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Adapter.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Structural.Adapter; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class AdapterTest 9 | { 10 | private static readonly object[] TestCases = 11 | { 12 | new[] { new Book() }, 13 | new[] { new EbookAdapter(new Kindle()) } 14 | }; 15 | 16 | [TestCaseSource(nameof(TestCases))] 17 | public void TestAdapter(IPaperBook book) 18 | { 19 | book.Open(); 20 | 21 | // OUTPUT: Opening the book. 22 | 23 | // OUTPUT: Pressing "Start" button. 24 | 25 | book.TurnPage(); 26 | 27 | // OUTPUT: Turning the page. 28 | 29 | // OUTPUT: Pressing "Next page" button. 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Bridge/Circle.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Bridge 2 | { 3 | public class Circle : IShape 4 | { 5 | private readonly IDrawingApi drawingAPI; 6 | 7 | private readonly int x; 8 | 9 | private readonly int y; 10 | 11 | private int radius; 12 | 13 | public Circle(int x, int y, int radius, IDrawingApi drawingAPI) 14 | { 15 | this.x = x; 16 | this.y = y; 17 | this.radius = radius; 18 | this.drawingAPI = drawingAPI; 19 | } 20 | 21 | public void Draw() 22 | { 23 | this.drawingAPI.DrawCircle(this.x, this.y, this.radius); 24 | } 25 | 26 | public void ResizeByPercentage(int percentage) 27 | { 28 | this.radius *= percentage; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Bridge/DrawingApi1.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Bridge 2 | { 3 | using System; 4 | 5 | public class DrawingApi1 : IDrawingApi 6 | { 7 | public void DrawCircle(int x, int y, int radius) 8 | { 9 | Console.WriteLine("Drawing circle."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Bridge/DrawingApi2.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Bridge 2 | { 3 | using System; 4 | 5 | public class DrawingApi2 : IDrawingApi 6 | { 7 | public void DrawCircle(int x, int y, int radius) 8 | { 9 | Console.WriteLine("Drawing circle."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Bridge/IDrawingApi.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Bridge 2 | { 3 | public interface IDrawingApi 4 | { 5 | void DrawCircle(int x, int y, int radius); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Bridge/IShape.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Bridge 2 | { 3 | public interface IShape 4 | { 5 | void Draw(); 6 | 7 | void ResizeByPercentage(int percentage); 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Bridge/Tests/BridgeTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Bridge.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Structural.Bridge; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class BridgeTest 9 | { 10 | private static readonly object[] TestCases = 11 | { 12 | new[] { new DrawingApi1() }, 13 | new[] { new DrawingApi2() } 14 | }; 15 | 16 | [TestCaseSource(nameof(TestCases))] 17 | public void TestBridge(IDrawingApi drawingApi) 18 | { 19 | var circle = new Circle(0, 0, 10, drawingApi); 20 | 21 | circle.Draw(); 22 | 23 | // OUTPUT: Drawing circle. 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Composite/Form.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Composite 2 | { 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | public class Form : IFormElement 7 | { 8 | private readonly List elements = new List(); 9 | 10 | public void AddElement(IFormElement element) 11 | { 12 | this.elements.Add(element); 13 | } 14 | 15 | public string Render(int indent = 0) 16 | { 17 | var output = new StringBuilder(); 18 | 19 | output.Append(new string(' ', indent) + "
\r\n"); 20 | 21 | foreach (var element in this.elements) 22 | { 23 | output.Append(element.Render(indent + 4)); 24 | } 25 | 26 | output.Append(new string(' ', indent) + "
\r\n"); 27 | 28 | return output.ToString(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Composite/IFormElement.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Composite 2 | { 3 | public interface IFormElement 4 | { 5 | string Render(int indent = 0); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Composite/InputElement.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Composite 2 | { 3 | public class InputElement : IFormElement 4 | { 5 | public string Render(int indent = 0) 6 | { 7 | return new string(' ', indent) + "\r\n"; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Composite/Tests/CompositeTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Composite.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Structural.Composite; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class CompositeTest 9 | { 10 | [Test] 11 | public void TestComposite() 12 | { 13 | var form = new Form(); 14 | form.AddElement(new InputElement()); 15 | form.AddElement(new TextElement()); 16 | 17 | var embeddedForm = new Form(); 18 | embeddedForm.AddElement(new InputElement()); 19 | embeddedForm.AddElement(new TextElement()); 20 | 21 | form.AddElement(embeddedForm); 22 | 23 | const string ExpectedOutput = "
\r\n" + 24 | " \r\n" + 25 | " Text element\r\n" + 26 | " \r\n" + 27 | " \r\n" + 28 | " Text element\r\n" + 29 | "
\r\n" + 30 | "\r\n"; 31 | 32 | Assert.That(form.Render(), Is.EqualTo(ExpectedOutput)); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Composite/TextElement.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Composite 2 | { 3 | public class TextElement : IFormElement 4 | { 5 | public string Render(int indent = 0) 6 | { 7 | return new string(' ', indent) + "Text element\r\n"; 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Decorator/HorizontalScrollBarDecorator .cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Decorator 2 | { 3 | using System; 4 | 5 | public class HorizontalScrollBarDecorator : WindowDecorator 6 | { 7 | public HorizontalScrollBarDecorator(IWindow window) 8 | : base(window) 9 | { 10 | } 11 | 12 | public override string Description 13 | { 14 | get 15 | { 16 | return base.Description + ", including horizontal scroll bar"; 17 | } 18 | } 19 | 20 | public override void Draw() 21 | { 22 | base.Draw(); 23 | this.DrawHorizontalScrollBar(); 24 | } 25 | 26 | private void DrawHorizontalScrollBar() 27 | { 28 | Console.WriteLine("Drawing horizontal scroll bar."); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Decorator/IWindow.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Decorator 2 | { 3 | public interface IWindow 4 | { 5 | string Description { get; set; } 6 | 7 | void Draw(); 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Decorator/SimpleWindow.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Decorator 2 | { 3 | using System; 4 | 5 | public class SimpleWindow : IWindow 6 | { 7 | public string Description { get; set; } = "Simple window"; 8 | 9 | public void Draw() 10 | { 11 | Console.WriteLine("Drawing simple window."); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Decorator/Tests/DecoratorTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Decorator.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Structural.Decorator; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class DecoratorTest 9 | { 10 | [Test] 11 | public void TestDecorator() 12 | { 13 | var decoratedWindow = 14 | new VerticalScrollBarDecorator( 15 | new HorizontalScrollBarDecorator( 16 | new SimpleWindow())); 17 | 18 | Assert.That( 19 | decoratedWindow.Description, 20 | Is.EqualTo("Simple window, including horizontal scroll bar, including vertical scroll bar")); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Decorator/VerticalScrollBarDecorator.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Decorator 2 | { 3 | using System; 4 | 5 | public class VerticalScrollBarDecorator : WindowDecorator 6 | { 7 | public VerticalScrollBarDecorator(IWindow window) 8 | : base(window) 9 | { 10 | } 11 | 12 | public override string Description 13 | { 14 | get 15 | { 16 | return base.Description + ", including vertical scroll bar"; 17 | } 18 | } 19 | 20 | public override void Draw() 21 | { 22 | base.Draw(); 23 | this.DrawVerticalScrollBar(); 24 | } 25 | 26 | private void DrawVerticalScrollBar() 27 | { 28 | Console.WriteLine("Drawing vertical scroll bar."); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Decorator/WindowDecorator.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Decorator 2 | { 3 | public abstract class WindowDecorator : IWindow 4 | { 5 | private readonly IWindow window; 6 | 7 | public WindowDecorator(IWindow window) 8 | { 9 | this.window = window; 10 | } 11 | 12 | public virtual string Description 13 | { 14 | get 15 | { 16 | return this.window.Description; 17 | } 18 | 19 | set 20 | { 21 | this.window.Description = value; 22 | } 23 | } 24 | 25 | public virtual void Draw() 26 | { 27 | this.window.Draw(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Facade/Computer.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Facade 2 | { 3 | public class Computer 4 | { 5 | private readonly IBios bios; 6 | 7 | private readonly IOs os; 8 | 9 | public Computer(IBios bios, IOs os) 10 | { 11 | this.bios = bios; 12 | this.os = os; 13 | } 14 | 15 | public void TurnOff() 16 | { 17 | this.os.Halt(); 18 | this.bios.PowerDown(); 19 | } 20 | 21 | public void TurnOn() 22 | { 23 | this.bios.Execute(); 24 | this.bios.WaitForKeyPress(); 25 | this.bios.Launch(this.os); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Facade/IBios.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Facade 2 | { 3 | public interface IBios 4 | { 5 | void Execute(); 6 | 7 | void Launch(IOs os); 8 | 9 | void PowerDown(); 10 | 11 | void WaitForKeyPress(); 12 | } 13 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Facade/IOs.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Facade 2 | { 3 | public interface IOs 4 | { 5 | void Halt(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Facade/Tests/FacadeTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Facade.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Structural.Facade; 4 | 5 | using Moq; 6 | 7 | using NUnit.Framework; 8 | 9 | [TestFixture] 10 | public class FacadeTest 11 | { 12 | [Test] 13 | public void TestTurnOff() 14 | { 15 | var bios = new Mock(); 16 | var os = new Mock(); 17 | var computer = new Computer(bios.Object, os.Object); 18 | 19 | computer.TurnOff(); 20 | 21 | os.Verify(o => o.Halt()); 22 | bios.Verify(b => b.PowerDown()); 23 | } 24 | 25 | [Test] 26 | public void TestTurnOn() 27 | { 28 | var bios = new Mock(); 29 | var os = new Mock(); 30 | var computer = new Computer(bios.Object, os.Object); 31 | 32 | computer.TurnOn(); 33 | 34 | bios.Verify(b => b.Execute()); 35 | bios.Verify(b => b.WaitForKeyPress()); 36 | bios.Verify(b => b.Launch(os.Object)); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Flyweight/Circle.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Flyweight 2 | { 3 | using System; 4 | 5 | public class Circle : IShape 6 | { 7 | private string color; 8 | 9 | private int radius; 10 | 11 | public Circle(int radius, string color) 12 | { 13 | this.radius = radius; 14 | this.color = color; 15 | } 16 | 17 | public int X { get; set; } 18 | 19 | public int Y { get; set; } 20 | 21 | public void Draw() 22 | { 23 | Console.WriteLine("Drawing circle."); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Flyweight/CircleFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Flyweight 2 | { 3 | using System.Collections.Generic; 4 | 5 | public static class CircleFactory 6 | { 7 | public static Dictionary Circles { get; } = new Dictionary(); 8 | 9 | public static Circle GetCircle(int x, int y, int radius, string color) 10 | { 11 | const string CircleName = nameof(Circle); 12 | var hash = new { radius, color, circleName = CircleName }.GetHashCode(); 13 | 14 | Circle circle; 15 | 16 | if (!Circles.TryGetValue(hash, out circle)) 17 | { 18 | circle = new Circle(radius, color); 19 | Circles.Add(hash, circle); 20 | } 21 | 22 | circle.X = x; 23 | circle.Y = y; 24 | 25 | return circle; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Flyweight/IShape.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Flyweight 2 | { 3 | public interface IShape 4 | { 5 | void Draw(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Flyweight/Tests/FlyweightTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Flyweight.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Structural.Flyweight; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class FlyweightTest 9 | { 10 | [SetUp] 11 | public void SetUp() 12 | { 13 | CircleFactory.Circles.Clear(); 14 | } 15 | 16 | [Test] 17 | public void TestGetCircleReturnsDifferentCirclesForDifferentColor() 18 | { 19 | CircleFactory.GetCircle(0, 0, 10, "Red"); 20 | CircleFactory.GetCircle(0, 0, 10, "Blue"); 21 | 22 | Assert.That(CircleFactory.Circles.Count, Is.EqualTo(2)); 23 | } 24 | 25 | [Test] 26 | public void TestGetCircleReturnsDifferentCirclesForDifferentRadius() 27 | { 28 | CircleFactory.GetCircle(0, 0, 10, "Red"); 29 | CircleFactory.GetCircle(0, 0, 11, "Red"); 30 | 31 | Assert.That(CircleFactory.Circles.Count, Is.EqualTo(2)); 32 | } 33 | 34 | [Test] 35 | public void TestGetCircleReturnsSameCircleForSameRadiusAndColor() 36 | { 37 | CircleFactory.GetCircle(0, 0, 10, "Red"); 38 | CircleFactory.GetCircle(0, 0, 10, "Red"); 39 | CircleFactory.GetCircle(10, 10, 10, "Red"); 40 | CircleFactory.GetCircle(10, 10, 10, "Red"); 41 | 42 | Assert.That(CircleFactory.Circles.Count, Is.EqualTo(1)); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Proxy/Car.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Proxy 2 | { 3 | using System; 4 | 5 | public class Car : ICar 6 | { 7 | public void Drive() 8 | { 9 | Console.WriteLine("Driving car."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Proxy/CarProxy.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Proxy 2 | { 3 | using System; 4 | 5 | public class CarProxy : ICar 6 | { 7 | private readonly ICar car; 8 | 9 | private readonly Driver driver; 10 | 11 | public CarProxy(Driver driver) 12 | { 13 | this.driver = driver; 14 | this.car = new Car(); 15 | } 16 | 17 | public void Drive() 18 | { 19 | if (this.driver.Age < 18) 20 | { 21 | throw new ArgumentException("The driver is too young to drive."); 22 | } 23 | 24 | this.car.Drive(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Proxy/Driver.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Proxy 2 | { 3 | public class Driver 4 | { 5 | public Driver(int age) 6 | { 7 | this.Age = age; 8 | } 9 | 10 | public int Age { get; private set; } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Proxy/ICar.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Proxy 2 | { 3 | public interface ICar 4 | { 5 | void Drive(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/GangOfFour/Structural/Proxy/Tests/ProxyTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.GangOfFour.Structural.Proxy.Tests 2 | { 3 | using DesignPatterns.GangOfFour.Structural.Proxy; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class ProxyTest 9 | { 10 | [Test] 11 | public void TestDriveWithAdultDriver() 12 | { 13 | var carProxy = new CarProxy(new Driver(21)); 14 | 15 | carProxy.Drive(); 16 | 17 | // OUTPUT: Driving car. 18 | } 19 | 20 | [Test] 21 | public void TestDriveWithYoungDriverThrowsInvalidArgumentException() 22 | { 23 | var carProxy = new CarProxy(new Driver(16)); 24 | 25 | Assert.That(() => carProxy.Drive(), Throws.ArgumentException); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/NullObject/ConsoleLogger.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.NullObject 2 | { 3 | using System; 4 | 5 | public class ConsoleLogger : ILogger 6 | { 7 | public void Log(string message) 8 | { 9 | Console.WriteLine(message); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/NullObject/ILogger.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.NullObject 2 | { 3 | public interface ILogger 4 | { 5 | void Log(string message); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/NullObject/NullLogger.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.NullObject 2 | { 3 | public class NullLogger : ILogger 4 | { 5 | public void Log(string message) 6 | { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/NullObject/Service.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.NullObject 2 | { 3 | public class Service 4 | { 5 | private readonly ILogger logger; 6 | 7 | public Service(ILogger logger) 8 | { 9 | this.logger = logger; 10 | } 11 | 12 | public void PerformOperation() 13 | { 14 | this.logger.Log("Performing operation."); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/NullObject/Tests/NullLoggerTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.NullObject.Tests 2 | { 3 | using DesignPatterns.Other.Behavioral.NullObject; 4 | using NUnit.Framework; 5 | 6 | [TestFixture] 7 | public class NullLoggerTest 8 | { 9 | [Test] 10 | public void TestNullLogger() 11 | { 12 | var logger = new ConsoleLogger(); 13 | var service1 = new Service(logger); 14 | 15 | service1.PerformOperation(); 16 | 17 | // OUTPUT: Performing operation. 18 | 19 | var nullLogger = new NullLogger(); 20 | var service2 = new Service(nullLogger); 21 | 22 | service2.PerformOperation(); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/Base/AndNotSpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification.Base 2 | { 3 | public class AndNotSpecification : CompositeSpecification 4 | { 5 | private readonly ISpecification left; 6 | 7 | private readonly ISpecification right; 8 | 9 | public AndNotSpecification(ISpecification left, ISpecification right) 10 | { 11 | this.left = left; 12 | this.right = right; 13 | } 14 | 15 | public override bool IsSatisfiedBy(T entity) 16 | { 17 | return this.left.IsSatisfiedBy(entity) && !this.right.IsSatisfiedBy(entity); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/Base/AndSpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification.Base 2 | { 3 | public class AndSpecification : CompositeSpecification 4 | { 5 | private readonly ISpecification left; 6 | 7 | private readonly ISpecification right; 8 | 9 | public AndSpecification(ISpecification left, ISpecification right) 10 | { 11 | this.left = left; 12 | this.right = right; 13 | } 14 | 15 | public override bool IsSatisfiedBy(T entity) 16 | { 17 | return this.left.IsSatisfiedBy(entity) && this.right.IsSatisfiedBy(entity); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/Base/CompositeSpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification.Base 2 | { 3 | public abstract class CompositeSpecification : ISpecification 4 | { 5 | public ISpecification And(ISpecification other) 6 | { 7 | return new AndSpecification(this, other); 8 | } 9 | 10 | public ISpecification AndNot(ISpecification other) 11 | { 12 | return new AndNotSpecification(this, other); 13 | } 14 | 15 | public abstract bool IsSatisfiedBy(T entity); 16 | 17 | public ISpecification Not() 18 | { 19 | return new NotSpecification(this); 20 | } 21 | 22 | public ISpecification Or(ISpecification other) 23 | { 24 | return new OrSpecification(this, other); 25 | } 26 | 27 | public ISpecification OrNot(ISpecification other) 28 | { 29 | return new OrNotSpecification(this, other); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/Base/ISpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification.Base 2 | { 3 | public interface ISpecification 4 | { 5 | ISpecification And(ISpecification other); 6 | 7 | ISpecification AndNot(ISpecification other); 8 | 9 | bool IsSatisfiedBy(T entity); 10 | 11 | ISpecification Not(); 12 | 13 | ISpecification Or(ISpecification other); 14 | 15 | ISpecification OrNot(ISpecification other); 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/Base/NotSpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification.Base 2 | { 3 | public class NotSpecification : CompositeSpecification 4 | { 5 | private readonly ISpecification other; 6 | 7 | public NotSpecification(ISpecification other) 8 | { 9 | this.other = other; 10 | } 11 | 12 | public override bool IsSatisfiedBy(T entity) 13 | { 14 | return !this.other.IsSatisfiedBy(entity); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/Base/OrNotSpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification.Base 2 | { 3 | public class OrNotSpecification : CompositeSpecification 4 | { 5 | private readonly ISpecification left; 6 | 7 | private readonly ISpecification right; 8 | 9 | public OrNotSpecification(ISpecification left, ISpecification right) 10 | { 11 | this.left = left; 12 | this.right = right; 13 | } 14 | 15 | public override bool IsSatisfiedBy(T entity) 16 | { 17 | return this.left.IsSatisfiedBy(entity) && !this.right.IsSatisfiedBy(entity); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/Base/OrSpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification.Base 2 | { 3 | public class OrSpecification : CompositeSpecification 4 | { 5 | private readonly ISpecification left; 6 | 7 | private readonly ISpecification right; 8 | 9 | public OrSpecification(ISpecification left, ISpecification right) 10 | { 11 | this.left = left; 12 | this.right = right; 13 | } 14 | 15 | public override bool IsSatisfiedBy(T entity) 16 | { 17 | return this.left.IsSatisfiedBy(entity) || this.right.IsSatisfiedBy(entity); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/InCollectionSpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification 2 | { 3 | using DesignPatterns.Other.Behavioral.Specification.Base; 4 | 5 | public class NoticeSentSpecification : CompositeSpecification 6 | { 7 | public override bool IsSatisfiedBy(Invoice invoice) 8 | { 9 | return invoice.NoticeCount >= 3; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/Invoice.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification 2 | { 3 | using System; 4 | 5 | public class Invoice 6 | { 7 | public Invoice(int id, decimal amount, DateTime dueDate) 8 | { 9 | this.Id = id; 10 | this.Amount = amount; 11 | this.DueDate = dueDate; 12 | } 13 | 14 | public decimal Amount { get; set; } 15 | 16 | public DateTime DueDate { get; set; } 17 | 18 | public int Id { get; set; } 19 | 20 | public int NoticeCount { get; set; } 21 | 22 | public bool SentToCollectionAgency { get; set; } 23 | 24 | public void SendToCollection() 25 | { 26 | this.SentToCollectionAgency = true; 27 | 28 | Console.WriteLine("Invoice {0} was sent to collection.", this.Id); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/NoticeSentSpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification 2 | { 3 | using DesignPatterns.Other.Behavioral.Specification.Base; 4 | 5 | public class InCollectionSpecification : CompositeSpecification 6 | { 7 | public override bool IsSatisfiedBy(Invoice invoice) 8 | { 9 | return invoice.SentToCollectionAgency; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/OverDueSpecification.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification 2 | { 3 | using System; 4 | 5 | using DesignPatterns.Other.Behavioral.Specification.Base; 6 | 7 | public class OverDueSpecification : CompositeSpecification 8 | { 9 | public override bool IsSatisfiedBy(Invoice invoice) 10 | { 11 | return (DateTime.Now - invoice.DueDate).Days >= 30; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Behavioral/Specification/Tests/SpecificationTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Behavioral.Specification.Tests 2 | { 3 | using System; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class SpecificationTest 9 | { 10 | [Test] 11 | public void TestSpecification() 12 | { 13 | var invoices = new[] 14 | { 15 | new Invoice(1, 199, DateTime.Now), 16 | new Invoice(2, 99, new DateTime(2010, 01, 24)) { NoticeCount = 3 } 17 | }; 18 | 19 | var sendToCollectionSpecification = 20 | new OverDueSpecification() 21 | .And(new NoticeSentSpecification()) 22 | .And(new InCollectionSpecification().Not()); 23 | 24 | foreach (var invoice in invoices) 25 | { 26 | if (sendToCollectionSpecification.IsSatisfiedBy(invoice)) 27 | { 28 | invoice.SendToCollection(); 29 | } 30 | } 31 | 32 | // OUTPUT: Invoice 2 was sent to collection. 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /DesignPatterns/Other/Creational/ObjectPool/Pool.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Creational.ObjectPool 2 | { 3 | using System.Collections.Generic; 4 | 5 | public static class Pool 6 | where T : PooledObject, new() 7 | { 8 | private static readonly List Available = new List(); 9 | 10 | private static readonly List InUse = new List(); 11 | 12 | public static T GetObject() 13 | { 14 | lock (Available) 15 | { 16 | if (Available.Count > 0) 17 | { 18 | var obj = Available[0]; 19 | Available.RemoveAt(0); 20 | InUse.Add(obj); 21 | 22 | return obj; 23 | } 24 | else 25 | { 26 | var obj = new T(); 27 | InUse.Add(obj); 28 | 29 | return obj; 30 | } 31 | } 32 | } 33 | 34 | public static void ReleaseObject(T obj) 35 | { 36 | lock (Available) 37 | { 38 | obj.Cleanup(); 39 | InUse.Remove(obj); 40 | Available.Add(obj); 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Creational/ObjectPool/PooledObject.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Creational.ObjectPool 2 | { 3 | public abstract class PooledObject 4 | { 5 | public abstract void Cleanup(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Creational/ObjectPool/Tests/ObjectPoolTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Creational.ObjectPool.Tests 2 | { 3 | using DesignPatterns.Other.Creational.ObjectPool; 4 | 5 | using NUnit.Framework; 6 | 7 | [TestFixture] 8 | public class ObjectPoolTest 9 | { 10 | [Test] 11 | public void TestPoolReturnsNewObjectWhenNotReleased() 12 | { 13 | var obj1 = Pool.GetObject(); 14 | var obj2 = Pool.GetObject(); 15 | 16 | Assert.That(obj1, Is.Not.EqualTo(obj2)); 17 | } 18 | 19 | [Test] 20 | public void TestPoolReturnsSameObjectWhenReleased() 21 | { 22 | var obj1 = Pool.GetObject(); 23 | Pool.ReleaseObject(obj1); 24 | var obj2 = Pool.GetObject(); 25 | 26 | Assert.That(obj1, Is.EqualTo(obj2)); 27 | } 28 | 29 | private class ConcretePooledObject : PooledObject 30 | { 31 | public override void Cleanup() 32 | { 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Creational/SimpleFactory/Audi.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Creational.SimpleFactory 2 | { 3 | using System; 4 | 5 | public class Audi : ICar 6 | { 7 | public void Drive() 8 | { 9 | Console.WriteLine("Driving Audi."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Creational/SimpleFactory/Bmw.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Creational.SimpleFactory 2 | { 3 | using System; 4 | 5 | public class Bmw : ICar 6 | { 7 | public void Drive() 8 | { 9 | Console.WriteLine("Driving BMW."); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Creational/SimpleFactory/CarFactory.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Creational.SimpleFactory 2 | { 3 | using System; 4 | 5 | public class CarFactory 6 | { 7 | public enum Cars 8 | { 9 | Audi, 10 | 11 | Bmw 12 | } 13 | 14 | public static ICar BuildCar(Cars carName) 15 | { 16 | switch (carName) 17 | { 18 | case Cars.Audi: 19 | return new Audi(); 20 | case Cars.Bmw: 21 | return new Bmw(); 22 | default: 23 | throw new ArgumentException(); 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Creational/SimpleFactory/ICar.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Creational.SimpleFactory 2 | { 3 | public interface ICar 4 | { 5 | void Drive(); 6 | } 7 | } -------------------------------------------------------------------------------- /DesignPatterns/Other/Creational/SimpleFactory/Tests/SimpleFactoryTest.cs: -------------------------------------------------------------------------------- 1 | namespace DesignPatterns.Other.Creational.SimpleFactory.Tests 2 | { 3 | using System; 4 | 5 | using DesignPatterns.Other.Creational.SimpleFactory; 6 | 7 | using NUnit.Framework; 8 | 9 | [TestFixture] 10 | public class SimpleFactoryTest 11 | { 12 | [TestCase(CarFactory.Cars.Audi, typeof(Audi))] 13 | [TestCase(CarFactory.Cars.Bmw, typeof(Bmw))] 14 | public void TestSimpleFactoryBuildsCar(CarFactory.Cars carName, Type carType) 15 | { 16 | var car = CarFactory.BuildCar(carName); 17 | 18 | Assert.That(car.GetType(), Is.EqualTo(carType)); 19 | } 20 | 21 | [Test] 22 | public void TestSimpleFactoryThrowsException() 23 | { 24 | Assert.That(() => CarFactory.BuildCar((CarFactory.Cars)100), Throws.ArgumentException); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /DesignPatterns/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("DesignPatterns")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("DesignPatterns")] 12 | [assembly: AssemblyCopyright("Copyright © 2016")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("b75365e6-b18a-4b81-957e-0863db236d69")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // Major Version 26 | // Minor Version 27 | // Build Number 28 | // Revision 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyVersion("1.0.0.0")] 33 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /DesignPatterns/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Łukasz Krzyszczak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Design Patterns C# # 2 | A collection of "Gang of Four" and other design patterns implemented in C#. The goal of this project was to gain ultimate 3 | knowledge of popular design patterns. The code was inspired by 4 | examples found in the web. It was written with minimalistic approach in mind in order to keep it as small as possible, 5 | while still achieving the goal of clearly presenting the patterns. 6 | 7 | Please note, that tests are not meant to be pure unit tests, but rather serve to show the patterns usage. 8 | 9 | ## Usage 10 | The project can be compiled and run using Visual Studio 2015. 11 | 12 | ## Gang of Four patterns 13 | 14 | ### Behavioral 15 | 16 | * [ChainOfResponsibility](DesignPatterns/GangOfFour/Behavioral/ChainOfResponsibility) - delegates commands to a chain of processing objects. 17 | * [Command](DesignPatterns/GangOfFour/Behavioral/Command) - creates objects which encapsulate actions and parameters. 18 | * [Interpreter](DesignPatterns/GangOfFour/Behavioral/Interpreter) - implements a specialized language. 19 | * [Iterator](DesignPatterns/GangOfFour/Behavioral/Iterator) - accesses the elements of an object sequentially without exposing its underlying representation. 20 | * [Mediator](DesignPatterns/GangOfFour/Behavioral/Mediator) - allows loose coupling between classes by being the only class that has detailed knowledge of their methods. 21 | * [Memento](DesignPatterns/GangOfFour/Behavioral/Memento) - provides the ability to restore an object to its previous state (undo). 22 | * [Observer](DesignPatterns/GangOfFour/Behavioral/Observer) - is a publish/subscribe pattern which allows a number of observer objects to see an event. 23 | * [State](DesignPatterns/GangOfFour/Behavioral/State) - allows an object to alter its behavior when its internal state changes. 24 | * [Strategy](DesignPatterns/GangOfFour/Behavioral/Strategy) - allows one of a family of algorithms to be selected on-the-fly at runtime. 25 | * [TemplateMethod](DesignPatterns/GangOfFour/Behavioral/TemplateMethod) - defines the skeleton of an algorithm as an abstract class, allowing its subclasses to provide concrete behavior. 26 | * [Visitor](DesignPatterns/GangOfFour/Behavioral/Visitor) - separates an algorithm from an object structure by moving the hierarchy of methods into one object. 27 | 28 | ### Creational 29 | 30 | * [AbstractFactory](DesignPatterns/GangOfFour/Creational/AbstractFactory) - groups object factories that have a common theme. 31 | * [Builder](DesignPatterns/GangOfFour/Creational/Builder) - constructs complex objects by separating construction and representation. 32 | * [FactoryMethod](DesignPatterns/GangOfFour/Creational/FactoryMethod) - creates objects without specifying the exact class to create. 33 | * [Prototype](DesignPatterns/GangOfFour/Creational/Prototype) - creates objects by cloning an existing object. 34 | * [Singleton](DesignPatterns/GangOfFour/Creational/Singleton) - restricts object creation for a class to only one instance. 35 | 36 | ### Structural 37 | 38 | * [Adapter](DesignPatterns/GangOfFour/Structural/Adapter) - allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class. 39 | * [Bridge](DesignPatterns/GangOfFour/Structural/Bridge) - decouples an abstraction from its implementation so that the two can vary independently. 40 | * [Composite](DesignPatterns/GangOfFour/Structural/Composite) - composes zero-or-more similar objects so that they can be manipulated as one object. 41 | * [Decorator](DesignPatterns/GangOfFour/Structural/Decorator) - dynamically adds/overrides behaviour in an existing method of an object. 42 | * [Facade](DesignPatterns/GangOfFour/Structural/Facade) - provides a simplified interface to a large body of code. 43 | * [Flyweight](DesignPatterns/GangOfFour/Structural/Flyweight) - reduces the cost of creating and manipulating a large number of similar objects. 44 | * [Proxy](DesignPatterns/GangOfFour/Structural/Proxy) - provides a placeholder for another object to control access, reduce cost, and reduce complexity. 45 | 46 | ## Other patterns 47 | 48 | ### Behavioral 49 | 50 | * [NullObject](DesignPatterns/Other/Behavioral/NullObject) - encapsulates the absence of an object by providing a substitutable alternative, that offers suitable default "do nothing" behavior. 51 | * [Specification](DesignPatterns/Other/Behavioral/Specification) - allows defining business rules as classes, combining them and checking against. 52 | 53 | ### Creational 54 | 55 | * [ObjectPool](DesignPatterns/Other/Creational/ObjectPool) - avoids expensive acquisition and release of resources by recycling objects that are no longer in use. 56 | * [SimpleFactory](DesignPatterns/Other/Creational/SimpleFactory) - creates objects without specifying the exact class to create. 57 | --------------------------------------------------------------------------------