├── .gitignore ├── ChainConstructors ├── ChainConstructors.csproj ├── InitialCode │ ├── CapitalStrategy.cs │ ├── Loan.cs │ ├── RevolvingTermROC.cs │ └── TermROC.cs ├── MyWork │ ├── CapitalStrategy.cs │ ├── Loan.cs │ ├── RevolvingTermROC.cs │ └── TermROC.cs └── Properties │ └── AssemblyInfo.cs ├── ComposeMethod ├── ComposeMethod.csproj ├── InitialCode │ └── List.cs ├── MyWork │ └── List.cs └── Properties │ └── AssemblyInfo.cs ├── EncapsulateClassesWithFactory ├── EncapsulateClassesWithFactory.csproj ├── InitialCode │ ├── Descriptors │ │ ├── AttributeDescriptor.cs │ │ ├── BooleanDescriptor.cs │ │ ├── DefaultDescriptor.cs │ │ └── ReferenceDescriptor.cs │ ├── Domain │ │ └── User.cs │ └── Mappers │ │ └── DescriptorMapper.cs └── MyWork │ ├── Descriptors │ ├── AttributeDescriptor.cs │ ├── BooleanDescriptor.cs │ ├── DefaultDescriptor.cs │ └── ReferenceDescriptor.cs │ ├── Domain │ └── User.cs │ └── Mappers │ └── DescriptorMapper.cs ├── EncapsulateCompositeWithBuilder ├── EncapsulateCompositeWithBuilder.csproj ├── InitialCode │ └── TagNode.cs ├── MyWork │ └── TagNode.cs └── Properties │ └── AssemblyInfo.cs ├── ExtractComposite ├── ExtractComposite.csproj ├── InitialCode │ ├── FormTag.cs │ ├── LabelTag.cs │ ├── LinkTag.cs │ ├── Node.cs │ ├── StringNode.cs │ └── Tag.cs ├── MyWork │ ├── FormTag.cs │ ├── LabelTag.cs │ ├── LinkTag.cs │ ├── Node.cs │ ├── StringNode.cs │ └── Tag.cs └── Properties │ └── AssemblyInfo.cs ├── FormTemplateMethod ├── FormTemplateMethod.csproj ├── InitialCode │ ├── CapitalStrategy.cs │ ├── CapitalStrategyAdvisedLine.cs │ ├── CapitalStrategyRevolver.cs │ ├── CapitalStrategyTermLoan.cs │ ├── Loan.cs │ ├── Payment.cs │ ├── RiskFactor.cs │ └── UnusedRiskFactors.cs ├── MyWork │ ├── CapitalStrategy.cs │ ├── CapitalStrategyAdvisedLine.cs │ ├── CapitalStrategyRevolver.cs │ ├── CapitalStrategyTermLoan.cs │ ├── Loan.cs │ ├── Payment.cs │ ├── RiskFactor.cs │ └── UnusedRiskFactors.cs └── Properties │ └── AssemblyInfo.cs ├── MoveAccumulationToCollectingParameter ├── InitialCode │ └── TagNode.cs ├── MoveAccumulationToCollectingParameter.csproj ├── MyWork │ └── TagNode.cs └── Properties │ └── AssemblyInfo.cs ├── PolymorphicCreationWithFactoryMethod ├── InitialCode │ ├── DOMBuilder.cs │ ├── DOMBuilderTest.cs │ ├── OutputBuilder.cs │ ├── RuntimeException.cs │ ├── TestCase.cs │ ├── XMLBuilder.cs │ └── XMLBuilderTest.cs ├── MyWork │ ├── DOMBuilder.cs │ ├── DOMBuilderTest.cs │ ├── OutputBuilder.cs │ ├── RuntimeException.cs │ ├── TestCase.cs │ ├── XMLBuilder.cs │ └── XMLBuilderTest.cs ├── PolymorphicCreationWithFactoryMethod.csproj └── Properties │ └── AssemblyInfo.cs ├── README.md ├── RefactoringToPatterns.Tests ├── ChainConstructors │ ├── InitialCode │ │ └── CapitalCalculationTests.cs │ └── MyWork │ │ └── CapitalCalculationTests.cs ├── ComposeMethod │ ├── InitialCode │ │ └── ListTests.cs │ └── MyWork │ │ └── ListTests.cs ├── EncapsulateClassesWithFactory │ ├── InitialCode │ │ └── Mappers │ │ │ └── DescriptorMapperTests.cs │ └── MyWork │ │ └── Mappers │ │ └── DescriptorMapperTests.cs ├── EncapsulateCompositeWithBuilder │ ├── InitialCode │ │ └── TagNodeTests.cs │ └── MyWork │ │ └── TagNodeTests.cs ├── ExtractComposite │ ├── InitialCode │ │ ├── FormTagTests.cs │ │ ├── LabelTagTests.cs │ │ └── LinkTagTests.cs │ └── MyWork │ │ ├── FormTagTests.cs │ │ ├── LabelTagTests.cs │ │ └── LinkTagTests.cs ├── FormTemplateMethod │ ├── InitialCode │ │ ├── AdvisedLineStrategyTests.cs │ │ ├── PaymentTests.cs │ │ ├── RevolverStrategyTests.cs │ │ └── TermLoanStrategyTests.cs │ └── MyWork │ │ ├── AdvisedLineStrategyTests.cs │ │ ├── PaymentTests.cs │ │ ├── RevolverStrategyTests.cs │ │ └── TermLoanStrategyTests.cs ├── MoveAccumulationToCollectingParameter │ ├── InitialCode │ │ ├── AccumulationAcrossMethodsTests.cs │ │ └── TagNodeTests.cs │ └── MyWork │ │ ├── AccumulationAcrossMethodsTests.cs │ │ └── TagNodeTests.cs ├── PolymorphicCreationWithFactoryMethod │ ├── InitialCode │ │ ├── DomBuilderTestTests.cs │ │ └── XMLBuilderTestTests.cs │ └── MyWork │ │ ├── DomBuilderTestTests.cs │ │ └── XMLBuilderTestTests.cs ├── RefactoringToPatterns.Tests.csproj ├── ReplaceConditionalLogicWithStrategy │ ├── InitialCode │ │ ├── LoanTests.cs │ │ └── PaymentTests.cs │ └── MyWork │ │ ├── LoanTests.cs │ │ └── PaymentTests.cs ├── ReplaceConstructorsWithCreationMethods │ ├── InitialCode │ │ └── CapitalCalculationTests.cs │ └── MyWork │ │ └── CapitalCalculationTests.cs ├── ReplaceImplicitTreeWithComposite │ ├── InitialCode │ │ └── OrdersWriterWithOrdersTests.cs │ └── MyWork │ │ └── OrdersWriterWithOrdersTests.cs └── packages.config ├── RefactoringToPatterns.sln ├── ReplaceConditionalLogicWithStrategy ├── InitialCode │ ├── Loan.cs │ ├── Payment.cs │ ├── RiskFactor.cs │ └── UnusedRiskFactors.cs ├── MyWork │ ├── Loan.cs │ ├── Payment.cs │ ├── RiskFactor.cs │ └── UnusedRiskFactors.cs ├── Properties │ └── AssemblyInfo.cs └── ReplaceConditionalLogicWithStrategy.csproj ├── ReplaceConstructorsWithCreationMethods ├── InitialCode │ ├── CapitalStrategy.cs │ ├── CapitalStrategyRCTL.cs │ ├── CapitalStrategyRevolver.cs │ ├── CapitalStrategyTermLoan.cs │ ├── Loan.cs │ └── RiskAdjustedCapitalStrategy.cs ├── MyWork │ ├── CapitalStrategy.cs │ ├── CapitalStrategyRCTL.cs │ ├── CapitalStrategyRevolver.cs │ ├── CapitalStrategyTermLoan.cs │ ├── Loan.cs │ └── RiskAdjustedCapitalStrategy.cs ├── Properties │ └── AssemblyInfo.cs └── ReplaceConstructorsWithCreationMethods.csproj └── ReplaceImplicitTreeWithComposite ├── InitialCode ├── Order.cs ├── Orders.cs ├── OrdersWriter.cs ├── Product.cs └── ProductSize.cs ├── MyWork ├── Order.cs ├── Orders.cs ├── OrdersWriter.cs ├── Product.cs └── ProductSize.cs ├── Properties └── AssemblyInfo.cs └── ReplaceImplicitTreeWithComposite.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | # Autosave files 2 | *~ 3 | 4 | # build 5 | [Oo]bj/ 6 | [Bb]in/ 7 | packages/ 8 | TestResults/ 9 | 10 | # globs 11 | Makefile.in 12 | *.DS_Store 13 | *.sln.cache 14 | *.suo 15 | *.cache 16 | *.pidb 17 | *.userprefs 18 | *.usertasks 19 | config.log 20 | config.make 21 | config.status 22 | aclocal.m4 23 | install-sh 24 | autom4te.cache/ 25 | *.user 26 | *.tar.gz 27 | tarballs/ 28 | test-results/ 29 | Thumbs.db 30 | .vs/ 31 | 32 | # Mac bundle stuff 33 | *.dmg 34 | *.app 35 | 36 | # resharper 37 | *_Resharper.* 38 | *.Resharper 39 | 40 | # dotCover 41 | *.dotCover 42 | 43 | # node 44 | node_modules 45 | npm-debug.log 46 | 47 | # WebStorm 48 | .idea 49 | -------------------------------------------------------------------------------- /ChainConstructors/ChainConstructors.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {1CB60E44-2BCF-426A-9A1C-64598F2BF93E} 7 | Library 8 | ChainConstructors 9 | ChainConstructors 10 | v4.8 11 | 9 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /ChainConstructors/InitialCode/CapitalStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace ChainConstructors.InitialCode 2 | { 3 | public class CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ChainConstructors/InitialCode/Loan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ChainConstructors.InitialCode 4 | { 5 | public class Loan 6 | { 7 | private readonly CapitalStrategy _strategy; 8 | private float _notional; 9 | private float _outstanding; 10 | private int _rating; 11 | private DateTime _expiry; 12 | private DateTime _maturity; 13 | 14 | public Loan(float notional, float outstanding, int rating, DateTime expiry) 15 | { 16 | this._strategy = new TermROC(); 17 | this._notional = notional; 18 | this._outstanding = outstanding; 19 | this._rating = rating; 20 | this._expiry = expiry; 21 | } 22 | 23 | public Loan(float notional, float outstanding, int rating, DateTime expiry, DateTime maturity) 24 | { 25 | this._strategy = new RevolvingTermROC(); 26 | this._notional = notional; 27 | this._outstanding = outstanding; 28 | this._rating = rating; 29 | this._expiry = expiry; 30 | this._maturity = maturity; 31 | } 32 | 33 | public Loan(CapitalStrategy strategy, float notional, float outstanding, 34 | int rating, DateTime expiry, DateTime maturity) 35 | { 36 | this._strategy = strategy; 37 | this._notional = notional; 38 | this._outstanding = outstanding; 39 | this._rating = rating; 40 | this._expiry = expiry; 41 | this._maturity = maturity; 42 | } 43 | 44 | public CapitalStrategy CapitalStrategy 45 | { 46 | get 47 | { 48 | return _strategy; 49 | } 50 | } 51 | 52 | } 53 | } -------------------------------------------------------------------------------- /ChainConstructors/InitialCode/RevolvingTermROC.cs: -------------------------------------------------------------------------------- 1 | namespace ChainConstructors.InitialCode 2 | { 3 | public class RevolvingTermROC : CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ChainConstructors/InitialCode/TermROC.cs: -------------------------------------------------------------------------------- 1 | namespace ChainConstructors.InitialCode 2 | { 3 | public class TermROC: CapitalStrategy 4 | { 5 | public TermROC() 6 | { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /ChainConstructors/MyWork/CapitalStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace ChainConstructors.MyWork 2 | { 3 | public class CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ChainConstructors/MyWork/Loan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ChainConstructors.MyWork 4 | { 5 | public class Loan 6 | { 7 | private readonly CapitalStrategy _strategy; 8 | private float _notional; 9 | private float _outstanding; 10 | private int _rating; 11 | private DateTime _expiry; 12 | private DateTime _maturity; 13 | 14 | public Loan(float notional, float outstanding, int rating, DateTime expiry) 15 | { 16 | this._strategy = new TermROC(); 17 | this._notional = notional; 18 | this._outstanding = outstanding; 19 | this._rating = rating; 20 | this._expiry = expiry; 21 | } 22 | 23 | public Loan(float notional, float outstanding, int rating, DateTime expiry, DateTime maturity) 24 | { 25 | this._strategy = new RevolvingTermROC(); 26 | this._notional = notional; 27 | this._outstanding = outstanding; 28 | this._rating = rating; 29 | this._expiry = expiry; 30 | this._maturity = maturity; 31 | } 32 | 33 | public Loan(CapitalStrategy strategy, float notional, float outstanding, 34 | int rating, DateTime expiry, DateTime maturity) 35 | { 36 | this._strategy = strategy; 37 | this._notional = notional; 38 | this._outstanding = outstanding; 39 | this._rating = rating; 40 | this._expiry = expiry; 41 | this._maturity = maturity; 42 | } 43 | 44 | public CapitalStrategy CapitalStrategy 45 | { 46 | get 47 | { 48 | return _strategy; 49 | } 50 | } 51 | 52 | } 53 | } -------------------------------------------------------------------------------- /ChainConstructors/MyWork/RevolvingTermROC.cs: -------------------------------------------------------------------------------- 1 | namespace ChainConstructors.MyWork 2 | { 3 | public class RevolvingTermROC : CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ChainConstructors/MyWork/TermROC.cs: -------------------------------------------------------------------------------- 1 | namespace ChainConstructors.MyWork 2 | { 3 | public class TermROC: CapitalStrategy 4 | { 5 | public TermROC() 6 | { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /ChainConstructors/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("ChainConstructors")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /ComposeMethod/ComposeMethod.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {DB582B2C-1FED-426E-8DBC-9618ECA07843} 7 | Library 8 | ComposeMethod 9 | ComposeMethod 10 | v4.8 11 | 9 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /ComposeMethod/InitialCode/List.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ComposeMethod.InitialCode 4 | { 5 | public class List 6 | { 7 | private bool _readOnly; 8 | private int _size; 9 | private Object[] _elements = new Object[]{}; 10 | 11 | public void Add(Object element) { 12 | if(!_readOnly) { 13 | int newSize = _size + 1; 14 | 15 | if(newSize > _elements.Length) { 16 | Object[] newElements = new Object[_elements.Length + 10]; 17 | 18 | for (int i = 0; i < _size; i++) 19 | newElements[i] = _elements[i]; 20 | 21 | _elements = newElements; 22 | } 23 | 24 | _elements[_size++] = element; 25 | } 26 | } 27 | 28 | public int Count 29 | { 30 | get 31 | { 32 | return _size; 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ComposeMethod/MyWork/List.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ComposeMethod.MyWork 4 | { 5 | public class List 6 | { 7 | private bool _readOnly; 8 | private int _size; 9 | private Object[] _elements = new Object[] { }; 10 | 11 | public void Add(Object element) 12 | { 13 | if (!_readOnly) 14 | { 15 | int newSize = _size + 1; 16 | 17 | if (newSize > _elements.Length) 18 | { 19 | Object[] newElements = new Object[_elements.Length + 10]; 20 | 21 | for (int i = 0; i < _size; i++) 22 | newElements[i] = _elements[i]; 23 | 24 | _elements = newElements; 25 | } 26 | 27 | _elements[_size++] = element; 28 | } 29 | } 30 | 31 | public int Count 32 | { 33 | get 34 | { 35 | return _size; 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ComposeMethod/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("ComposeMethod")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/EncapsulateClassesWithFactory.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {F2D41130-D1A6-4F83-8408-F02D6AAF279C} 7 | Library 8 | EncapsulateClassesWithFactory 9 | EncapsulateClassesWithFactory 10 | v4.8 11 | 9 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | 22 | 23 | true 24 | bin\Release 25 | prompt 26 | 4 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/InitialCode/Descriptors/AttributeDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EncapsulateClassesWithFactory.InitialCode.Descriptors 4 | { 5 | public abstract class AttributeDescriptor 6 | { 7 | readonly string descriptorName; 8 | readonly Type mapperType; 9 | readonly Type forType; 10 | 11 | protected AttributeDescriptor(string descriptorName, Type mapperType, Type forType) 12 | { 13 | this.descriptorName = descriptorName; 14 | this.mapperType = mapperType; 15 | this.forType = forType; 16 | } 17 | 18 | public string DescriptorName => descriptorName; 19 | } 20 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/InitialCode/Descriptors/BooleanDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EncapsulateClassesWithFactory.InitialCode.Descriptors 4 | { 5 | public class BooleanDescriptor : AttributeDescriptor 6 | { 7 | 8 | public BooleanDescriptor(string descriptorName, Type mapperType, Type forType) 9 | : base(descriptorName, mapperType, forType) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/InitialCode/Descriptors/DefaultDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EncapsulateClassesWithFactory.InitialCode.Descriptors 4 | { 5 | public class DefaultDescriptor : AttributeDescriptor 6 | { 7 | 8 | public DefaultDescriptor(string descriptorName, Type mapperType, Type forType) 9 | : base(descriptorName, mapperType, forType) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/InitialCode/Descriptors/ReferenceDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EncapsulateClassesWithFactory.InitialCode.Descriptors 4 | { 5 | public class ReferenceDescriptor: AttributeDescriptor 6 | { 7 | 8 | public ReferenceDescriptor(string descriptorName, Type mapperType, Type forType) 9 | : base(descriptorName, mapperType, forType) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/InitialCode/Domain/User.cs: -------------------------------------------------------------------------------- 1 | namespace EncapsulateClassesWithFactory.InitialCode.Domain 2 | { 3 | public class User 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/InitialCode/Mappers/DescriptorMapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using EncapsulateClassesWithFactory.InitialCode.Descriptors; 4 | using EncapsulateClassesWithFactory.InitialCode.Domain; 5 | 6 | namespace EncapsulateClassesWithFactory.InitialCode.Mappers 7 | { 8 | public class DescriptorMapper 9 | { 10 | protected List CreateAttributeDescriptors() { 11 | var result = new List(); 12 | 13 | result.Add(new DefaultDescriptor("remoteId", GetClass(), typeof(int))); 14 | result.Add(new DefaultDescriptor("createdDate", GetClass(), typeof(DateTime))); 15 | result.Add(new DefaultDescriptor("lastChangedDate", GetClass(), typeof(DateTime))); 16 | result.Add(new ReferenceDescriptor("createdBy", GetClass(), typeof(User))); 17 | result.Add(new ReferenceDescriptor("lastChangedBy", GetClass(), typeof(User))); 18 | result.Add(new DefaultDescriptor("optimisticLockVersion", GetClass(), typeof(int))); 19 | return result; 20 | } 21 | 22 | private Type GetClass() 23 | { 24 | return typeof(DescriptorMapper); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/MyWork/Descriptors/AttributeDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EncapsulateClassesWithFactory.MyWork.Descriptors 4 | { 5 | public abstract class AttributeDescriptor 6 | { 7 | readonly string descriptorName; 8 | readonly Type mapperType; 9 | readonly Type forType; 10 | 11 | protected AttributeDescriptor(string descriptorName, Type mapperType, Type forType) 12 | { 13 | this.descriptorName = descriptorName; 14 | this.mapperType = mapperType; 15 | this.forType = forType; 16 | } 17 | 18 | public string DescriptorName => descriptorName; 19 | } 20 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/MyWork/Descriptors/BooleanDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EncapsulateClassesWithFactory.MyWork.Descriptors 4 | { 5 | public class BooleanDescriptor : AttributeDescriptor 6 | { 7 | 8 | 9 | public BooleanDescriptor(string descriptorName, Type mapperType, Type forType) 10 | : base(descriptorName, mapperType, forType) 11 | { 12 | 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/MyWork/Descriptors/DefaultDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EncapsulateClassesWithFactory.MyWork.Descriptors 4 | { 5 | public class DefaultDescriptor : AttributeDescriptor 6 | { 7 | 8 | public DefaultDescriptor(string descriptorName, Type mapperType, Type forType) 9 | : base(descriptorName, mapperType, forType) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/MyWork/Descriptors/ReferenceDescriptor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace EncapsulateClassesWithFactory.MyWork.Descriptors 4 | { 5 | public class ReferenceDescriptor: AttributeDescriptor 6 | { 7 | 8 | public ReferenceDescriptor(string descriptorName, Type mapperType, Type forType) 9 | : base(descriptorName, mapperType, forType) 10 | { 11 | 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/MyWork/Domain/User.cs: -------------------------------------------------------------------------------- 1 | namespace EncapsulateClassesWithFactory.MyWork.Domain 2 | { 3 | public class User 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /EncapsulateClassesWithFactory/MyWork/Mappers/DescriptorMapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using EncapsulateClassesWithFactory.MyWork.Descriptors; 4 | using EncapsulateClassesWithFactory.MyWork.Domain; 5 | 6 | namespace EncapsulateClassesWithFactory.MyWork.Mappers 7 | { 8 | public class DescriptorMapper 9 | { 10 | protected List CreateAttributeDescriptors() { 11 | var result = new List(); 12 | 13 | result.Add(new DefaultDescriptor("remoteId", GetClass(), typeof(int))); 14 | result.Add(new DefaultDescriptor("createdDate", GetClass(), typeof(DateTime))); 15 | result.Add(new DefaultDescriptor("lastChangedDate", GetClass(), typeof(DateTime))); 16 | result.Add(new ReferenceDescriptor("createdBy", GetClass(), typeof(User))); 17 | result.Add(new ReferenceDescriptor("lastChangedBy", GetClass(), typeof(User))); 18 | result.Add(new DefaultDescriptor("optimisticLockVersion", GetClass(), typeof(int))); 19 | return result; 20 | } 21 | 22 | private Type GetClass() 23 | { 24 | return typeof(DescriptorMapper); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /EncapsulateCompositeWithBuilder/EncapsulateCompositeWithBuilder.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {9CA5D6B8-43D4-4325-9E7D-BF7E1E2D4C51} 7 | Library 8 | EncapsulateCompositeWithBuilder 9 | EncapsulateCompositeWithBuilder 10 | v4.8 11 | 9 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /EncapsulateCompositeWithBuilder/InitialCode/TagNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | 4 | namespace EncapsulateCompositeWithBuilder.InitialCode 5 | { 6 | public class TagNode 7 | { 8 | private StringBuilder attributes; 9 | private IList children = new List(); 10 | private string name; 11 | private string value = string.Empty; 12 | 13 | public TagNode(string name) 14 | { 15 | this.name = name; 16 | this.attributes = new StringBuilder(); 17 | } 18 | 19 | public void Add(TagNode tagNode) 20 | { 21 | this.children.Add(tagNode); 22 | } 23 | 24 | public void AddAttribute(string attribute, string value) 25 | { 26 | this.attributes.Append(" "); 27 | this.attributes.Append(attribute); 28 | this.attributes.Append("='"); 29 | this.attributes.Append(value); 30 | this.attributes.Append("'"); 31 | } 32 | 33 | public void AddValue(string value) 34 | { 35 | this.value = value; 36 | } 37 | 38 | public override string ToString() 39 | { 40 | var result = 41 | "<" + this.name + this.attributes + ">"; 42 | 43 | foreach (TagNode tagNode in this.children) 44 | { 45 | result += tagNode.ToString(); 46 | } 47 | 48 | result += this.value + 49 | ""; 50 | return result; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /EncapsulateCompositeWithBuilder/MyWork/TagNode.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | 4 | namespace EncapsulateCompositeWithBuilder.MyWork 5 | { 6 | public class TagNode 7 | { 8 | private StringBuilder attributes; 9 | private IList children = new List(); 10 | private string name; 11 | private string value = string.Empty; 12 | 13 | public TagNode(string name) 14 | { 15 | this.name = name; 16 | this.attributes = new StringBuilder(); 17 | } 18 | 19 | public void Add(TagNode tagNode) 20 | { 21 | this.children.Add(tagNode); 22 | } 23 | 24 | public void AddAttribute(string attribute, string value) 25 | { 26 | this.attributes.Append(" "); 27 | this.attributes.Append(attribute); 28 | this.attributes.Append("='"); 29 | this.attributes.Append(value); 30 | this.attributes.Append("'"); 31 | } 32 | 33 | public void AddValue(string value) 34 | { 35 | this.value = value; 36 | } 37 | 38 | public override string ToString() 39 | { 40 | var result = 41 | "<" + this.name + this.attributes + ">"; 42 | 43 | foreach (TagNode tagNode in this.children) 44 | { 45 | result += tagNode.ToString(); 46 | } 47 | 48 | result += this.value + 49 | ""; 50 | return result; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /EncapsulateCompositeWithBuilder/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("EncapsulateCompositeWithBuilder")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /ExtractComposite/ExtractComposite.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EA0BAF76-F1E5-45F5-B4C7-8B2C8E005249} 8 | Library 9 | Properties 10 | ExtractComposite 11 | ExtractComposite 12 | v4.8 13 | 512 14 | 9 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /ExtractComposite/InitialCode/FormTag.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ExtractComposite.InitialCode 4 | { 5 | public class FormTag: Tag 6 | { 7 | private readonly List _allNodesList = new List(); 8 | 9 | public FormTag() : base("
", "
") 10 | { 11 | 12 | } 13 | 14 | public void AddChild(Tag tag) 15 | { 16 | _allNodesList.Add(tag); 17 | } 18 | 19 | public string ToPlainTextString() 20 | { 21 | var stringRepresentation = string.Empty; 22 | GetAllNodesList().ForEach(node => stringRepresentation += node.ToPlainTextString()); 23 | return stringRepresentation; 24 | } 25 | 26 | private List GetAllNodesList() 27 | { 28 | return _allNodesList; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /ExtractComposite/InitialCode/LabelTag.cs: -------------------------------------------------------------------------------- 1 | namespace ExtractComposite.InitialCode 2 | { 3 | public class LabelTag: Tag 4 | { 5 | private StringNode _labelText; 6 | public LabelTag(StringNode labelText): base("") 7 | { 8 | _labelText = labelText; 9 | } 10 | 11 | public override string ToPlainTextString() 12 | { 13 | return _labelText.ToPlainTextString(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /ExtractComposite/InitialCode/LinkTag.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ExtractComposite.InitialCode 4 | { 5 | public class LinkTag: Tag 6 | { 7 | private readonly List _nodeList = new List(); 8 | 9 | public LinkTag(): base("","") 10 | { 11 | 12 | } 13 | 14 | public override string ToPlainTextString() 15 | { 16 | 17 | var buffer = string.Empty; 18 | LinkData().ForEach(node => buffer += node.ToPlainTextString()); 19 | return buffer; 20 | } 21 | 22 | public void AddChild(Node child) 23 | { 24 | _nodeList.Add(child); 25 | } 26 | 27 | private List LinkData() 28 | { 29 | return _nodeList; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ExtractComposite/InitialCode/Node.cs: -------------------------------------------------------------------------------- 1 | namespace ExtractComposite.InitialCode 2 | { 3 | public abstract class Node 4 | { 5 | public abstract string ToPlainTextString(); 6 | } 7 | } -------------------------------------------------------------------------------- /ExtractComposite/InitialCode/StringNode.cs: -------------------------------------------------------------------------------- 1 | namespace ExtractComposite.InitialCode 2 | { 3 | public class StringNode : Node 4 | { 5 | private readonly string _text; 6 | 7 | public StringNode(string text) 8 | { 9 | this._text = text; 10 | } 11 | 12 | public override string ToPlainTextString() 13 | { 14 | return _text; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /ExtractComposite/InitialCode/Tag.cs: -------------------------------------------------------------------------------- 1 | namespace ExtractComposite.InitialCode 2 | { 3 | public class Tag : Node 4 | { 5 | protected string _openingTag = string.Empty; 6 | protected string _closingTag= string.Empty; 7 | 8 | protected Tag(string openingTag, string closingTag) 9 | { 10 | _openingTag = openingTag; 11 | _closingTag = closingTag; 12 | } 13 | 14 | public override string ToPlainTextString() 15 | { 16 | return string.Empty; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ExtractComposite/MyWork/FormTag.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ExtractComposite.MyWork 4 | { 5 | public class FormTag: Tag 6 | { 7 | private readonly List _allNodesList = new List(); 8 | 9 | public FormTag() : base("
", "
") 10 | { 11 | 12 | } 13 | 14 | public void AddChild(Tag tag) 15 | { 16 | _allNodesList.Add(tag); 17 | } 18 | 19 | public string ToPlainTextString() 20 | { 21 | var stringRepresentation = string.Empty; 22 | GetAllNodesList().ForEach(node => stringRepresentation += node.ToPlainTextString()); 23 | return stringRepresentation; 24 | } 25 | 26 | private List GetAllNodesList() 27 | { 28 | return _allNodesList; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /ExtractComposite/MyWork/LabelTag.cs: -------------------------------------------------------------------------------- 1 | namespace ExtractComposite.MyWork 2 | { 3 | public class LabelTag: Tag 4 | { 5 | private StringNode _labelText; 6 | public LabelTag(StringNode labelText): base("") 7 | { 8 | _labelText = labelText; 9 | } 10 | 11 | public override string ToPlainTextString() 12 | { 13 | return _labelText.ToPlainTextString(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /ExtractComposite/MyWork/LinkTag.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ExtractComposite.MyWork 4 | { 5 | public class LinkTag: Tag 6 | { 7 | private readonly List _nodeList = new List(); 8 | 9 | public LinkTag(): base("","") 10 | { 11 | 12 | } 13 | 14 | public override string ToPlainTextString() 15 | { 16 | 17 | var buffer = string.Empty; 18 | LinkData().ForEach(node => buffer += node.ToPlainTextString()); 19 | return buffer; 20 | } 21 | 22 | public void AddChild(Node child) 23 | { 24 | _nodeList.Add(child); 25 | } 26 | 27 | private List LinkData() 28 | { 29 | return _nodeList; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ExtractComposite/MyWork/Node.cs: -------------------------------------------------------------------------------- 1 | namespace ExtractComposite.MyWork 2 | { 3 | public abstract class Node 4 | { 5 | public abstract string ToPlainTextString(); 6 | } 7 | } -------------------------------------------------------------------------------- /ExtractComposite/MyWork/StringNode.cs: -------------------------------------------------------------------------------- 1 | namespace ExtractComposite.MyWork 2 | { 3 | public class StringNode : Node 4 | { 5 | private readonly string _text; 6 | 7 | public StringNode(string text) 8 | { 9 | this._text = text; 10 | } 11 | 12 | public override string ToPlainTextString() 13 | { 14 | return _text; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /ExtractComposite/MyWork/Tag.cs: -------------------------------------------------------------------------------- 1 | namespace ExtractComposite.MyWork 2 | { 3 | public class Tag : Node 4 | { 5 | protected string _openingTag = string.Empty; 6 | protected string _closingTag= string.Empty; 7 | 8 | protected Tag(string openingTag, string closingTag) 9 | { 10 | _openingTag = openingTag; 11 | _closingTag = closingTag; 12 | } 13 | 14 | public override string ToPlainTextString() 15 | { 16 | return string.Empty; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ExtractComposite/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("ExtractComposite")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("ExtractComposite")] 12 | [assembly: AssemblyCopyright("Copyright © 2021")] 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("EA0BAF76-F1E5-45F5-B4C7-8B2C8E005249")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /FormTemplateMethod/FormTemplateMethod.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {F1231A49-7229-47D8-B19F-197683E3A829} 7 | Library 8 | FormTemplateMethod 9 | FormTemplateMethod 10 | v4.8 11 | 9 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /FormTemplateMethod/InitialCode/CapitalStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace FormTemplateMethod.InitialCode 3 | { 4 | public abstract class CapitalStrategy 5 | { 6 | 7 | private long MILLIS_PER_DAY = 86400000; 8 | private long DAYS_PER_YEAR = 365; 9 | 10 | public abstract double Capital(Loan loan); 11 | 12 | protected double RiskFactorFor(Loan loan) 13 | { 14 | return RiskFactor.GetFactors().ForRating(loan.GetRiskRating()); 15 | } 16 | 17 | private double UnusedRiskFactorFor(Loan loan) 18 | { 19 | return UnusedRiskFactors.GetFactors().ForRating(loan.GetRiskRating()); 20 | } 21 | 22 | public virtual double Duration(Loan loan) 23 | { 24 | return YearsTo(loan.GetExpiry(), loan); 25 | } 26 | 27 | protected double YearsTo(DateTime? endDate, Loan loan) 28 | { 29 | DateTime? beginDate = (loan.GetToday() == null ? loan.GetStart() : loan.GetToday()); 30 | return (double)((endDate?.Ticks - beginDate?.Ticks) / MILLIS_PER_DAY / DAYS_PER_YEAR); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /FormTemplateMethod/InitialCode/CapitalStrategyAdvisedLine.cs: -------------------------------------------------------------------------------- 1 | namespace FormTemplateMethod.InitialCode 2 | { 3 | public class CapitalStrategyAdvisedLine : CapitalStrategy 4 | { 5 | public override double Capital(Loan loan) 6 | { 7 | return loan.GetCommitment() * loan.GetUnusedPercentage() * Duration(loan) * RiskFactorFor(loan); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /FormTemplateMethod/InitialCode/CapitalStrategyRevolver.cs: -------------------------------------------------------------------------------- 1 | namespace FormTemplateMethod.InitialCode 2 | { 3 | public class CapitalStrategyRevolver : CapitalStrategy 4 | { 5 | public override double Capital(Loan loan) 6 | { 7 | return (loan.OutstandingRiskAmount() * Duration(loan) * RiskFactorFor(loan)) 8 | + (loan.UnusedRiskAmount() * Duration(loan) * UnusedRiskFactorFor(loan)); 9 | } 10 | 11 | private double UnusedRiskFactorFor(Loan loan) 12 | { 13 | return UnusedRiskFactors.GetFactors().ForRating(loan.GetRiskRating()); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /FormTemplateMethod/InitialCode/CapitalStrategyTermLoan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace FormTemplateMethod.InitialCode 3 | { 4 | public class CapitalStrategyTermLoan : CapitalStrategy 5 | { 6 | private readonly double EPSILON = 0.001; 7 | 8 | public override double Capital(Loan loan) 9 | { 10 | return loan.GetCommitment() * Duration(loan) * RiskFactorFor(loan); 11 | } 12 | 13 | public override double Duration(Loan loan) 14 | { 15 | return WeightedAverageDuration(loan); 16 | } 17 | 18 | private double WeightedAverageDuration(Loan loan) 19 | { 20 | double duration = 0.0; 21 | double weightedAverage = 0.0; 22 | double sumOfPayments = 0.0; 23 | 24 | foreach (var payment in loan.Payments()) 25 | { 26 | sumOfPayments += payment.Amount; 27 | weightedAverage += YearsTo(payment.Date, loan) * payment.Amount; 28 | } 29 | 30 | if (Math.Abs(loan.GetCommitment()) > EPSILON) 31 | { 32 | duration = weightedAverage / sumOfPayments; 33 | } 34 | 35 | return duration; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /FormTemplateMethod/InitialCode/Loan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FormTemplateMethod.InitialCode 5 | { 6 | public class Loan 7 | { 8 | double _commitment = 1.0; 9 | private DateTime? _expiry; 10 | private DateTime? _maturity; 11 | private double _outstanding; 12 | IList _payments = new List(); 13 | private DateTime? _today = DateTime.Now; 14 | private DateTime _start; 15 | private long MILLIS_PER_DAY = 86400000; 16 | private long DAYS_PER_YEAR = 365; 17 | private double _riskRating; 18 | private double _unusedPercentage; 19 | private CapitalStrategy _capitalStrategy; 20 | 21 | public Loan(double commitment, 22 | double notSureWhatThisIs, 23 | DateTime start, 24 | DateTime? expiry, 25 | DateTime? maturity, 26 | int riskRating, 27 | CapitalStrategy capitalStrategy) 28 | { 29 | this._expiry = expiry; 30 | this._commitment = commitment; 31 | this._today = null; 32 | this._start = start; 33 | this._maturity = maturity; 34 | this._riskRating = riskRating; 35 | this._unusedPercentage = 1.0; 36 | this._capitalStrategy = capitalStrategy; 37 | } 38 | 39 | public static Loan NewTermLoan(double commitment, DateTime start, DateTime maturity, int riskRating) 40 | { 41 | return new Loan(commitment, commitment, start, null, 42 | maturity, riskRating, new CapitalStrategyTermLoan()); 43 | } 44 | 45 | public static Loan NewRevolver(double commitment, DateTime start, DateTime expiry, int riskRating) 46 | { 47 | return new Loan(commitment, 0, start, expiry, 48 | null, riskRating, new CapitalStrategyRevolver()); 49 | } 50 | 51 | public static Loan NewAdvisedLine(double commitment, DateTime start, DateTime expiry, int riskRating) 52 | { 53 | if (riskRating > 3) return null; 54 | Loan advisedLine = new Loan(commitment, 0, start, expiry, 55 | null, riskRating, new CapitalStrategyAdvisedLine()); 56 | advisedLine.SetUnusedPercentage(0.1); 57 | return advisedLine; 58 | } 59 | 60 | public DateTime? GetExpiry() 61 | { 62 | return _expiry; 63 | } 64 | 65 | public double GetCommitment() 66 | { 67 | return _commitment; 68 | } 69 | 70 | public DateTime? GetMaturity() 71 | { 72 | return _maturity; 73 | } 74 | 75 | public double GetRiskRating() 76 | { 77 | return _riskRating; 78 | } 79 | 80 | public void Payment(double amount, DateTime paymentDate) 81 | { 82 | _payments.Add(new Payment(amount, paymentDate)); 83 | } 84 | 85 | public double Capital() 86 | { 87 | return _capitalStrategy.Capital(this); 88 | } 89 | 90 | public DateTime? GetToday() 91 | { 92 | return _today; 93 | } 94 | 95 | public DateTime? GetStart() 96 | { 97 | return _start; 98 | } 99 | 100 | public IList Payments() 101 | { 102 | return _payments; 103 | } 104 | 105 | public double GetUnusedPercentage() 106 | { 107 | return _unusedPercentage; 108 | } 109 | 110 | public void SetUnusedPercentage(double unusedPercentage) 111 | { 112 | _unusedPercentage = unusedPercentage; 113 | } 114 | 115 | public double UnusedRiskAmount() 116 | { 117 | return (_commitment - _outstanding); 118 | } 119 | 120 | public double OutstandingRiskAmount() 121 | { 122 | return _outstanding; 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /FormTemplateMethod/InitialCode/Payment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FormTemplateMethod.InitialCode 4 | 5 | { 6 | public class Payment 7 | { 8 | private double _amount; 9 | private DateTime _date; 10 | 11 | public Payment() 12 | { 13 | _amount = 0.0; 14 | _date = new DateTime(); 15 | } 16 | 17 | public Payment(double amount, DateTime date) 18 | { 19 | Amount = amount; 20 | Date = date; 21 | } 22 | 23 | public double Amount 24 | { 25 | get { return _amount; } 26 | 27 | private set { _amount = value; } 28 | } 29 | 30 | public DateTime Date 31 | { 32 | get { return _date; } 33 | 34 | private set { _date = value; } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /FormTemplateMethod/InitialCode/RiskFactor.cs: -------------------------------------------------------------------------------- 1 | namespace FormTemplateMethod.InitialCode 2 | { 3 | public class RiskFactor 4 | { 5 | private RiskFactor() 6 | { 7 | 8 | } 9 | 10 | public static RiskFactor GetFactors() 11 | { 12 | return new RiskFactor(); 13 | } 14 | 15 | public double ForRating(double riskRating) 16 | { 17 | return 0.03; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /FormTemplateMethod/InitialCode/UnusedRiskFactors.cs: -------------------------------------------------------------------------------- 1 | namespace FormTemplateMethod.InitialCode 2 | { 3 | public class UnusedRiskFactors 4 | { 5 | private UnusedRiskFactors() 6 | { 7 | 8 | } 9 | 10 | public static UnusedRiskFactors GetFactors() 11 | { 12 | return new UnusedRiskFactors(); 13 | } 14 | 15 | public double ForRating(double riskRating) 16 | { 17 | return 0.01; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /FormTemplateMethod/MyWork/CapitalStrategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace FormTemplateMethod.MyWork 3 | { 4 | public abstract class CapitalStrategy 5 | { 6 | 7 | private long MILLIS_PER_DAY = 86400000; 8 | private long DAYS_PER_YEAR = 365; 9 | 10 | public abstract double Capital(Loan loan); 11 | 12 | protected double RiskFactorFor(Loan loan) 13 | { 14 | return RiskFactor.GetFactors().ForRating(loan.GetRiskRating()); 15 | } 16 | 17 | private double UnusedRiskFactorFor(Loan loan) 18 | { 19 | return UnusedRiskFactors.GetFactors().ForRating(loan.GetRiskRating()); 20 | } 21 | 22 | public virtual double Duration(Loan loan) 23 | { 24 | return YearsTo(loan.GetExpiry(), loan); 25 | } 26 | 27 | protected double YearsTo(DateTime? endDate, Loan loan) 28 | { 29 | DateTime? beginDate = (loan.GetToday() == null ? loan.GetStart() : loan.GetToday()); 30 | return (double)((endDate?.Ticks - beginDate?.Ticks) / MILLIS_PER_DAY / DAYS_PER_YEAR); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /FormTemplateMethod/MyWork/CapitalStrategyAdvisedLine.cs: -------------------------------------------------------------------------------- 1 | namespace FormTemplateMethod.MyWork 2 | { 3 | public class CapitalStrategyAdvisedLine : CapitalStrategy 4 | { 5 | public override double Capital(Loan loan) 6 | { 7 | return loan.GetCommitment() * loan.GetUnusedPercentage() * Duration(loan) * RiskFactorFor(loan); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /FormTemplateMethod/MyWork/CapitalStrategyRevolver.cs: -------------------------------------------------------------------------------- 1 | namespace FormTemplateMethod.MyWork 2 | { 3 | public class CapitalStrategyRevolver : CapitalStrategy 4 | { 5 | public override double Capital(Loan loan) 6 | { 7 | return (loan.OutstandingRiskAmount() * Duration(loan) * RiskFactorFor(loan)) 8 | + (loan.UnusedRiskAmount() * Duration(loan) * UnusedRiskFactorFor(loan)); 9 | } 10 | 11 | private double UnusedRiskFactorFor(Loan loan) 12 | { 13 | return UnusedRiskFactors.GetFactors().ForRating(loan.GetRiskRating()); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /FormTemplateMethod/MyWork/CapitalStrategyTermLoan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace FormTemplateMethod.MyWork 3 | { 4 | public class CapitalStrategyTermLoan : CapitalStrategy 5 | { 6 | private readonly double EPSILON = 0.001; 7 | 8 | public override double Capital(Loan loan) 9 | { 10 | return loan.GetCommitment() * Duration(loan) * RiskFactorFor(loan); 11 | } 12 | 13 | public override double Duration(Loan loan) 14 | { 15 | return WeightedAverageDuration(loan); 16 | } 17 | 18 | private double WeightedAverageDuration(Loan loan) 19 | { 20 | double duration = 0.0; 21 | double weightedAverage = 0.0; 22 | double sumOfPayments = 0.0; 23 | 24 | foreach (var payment in loan.Payments()) 25 | { 26 | sumOfPayments += payment.Amount; 27 | weightedAverage += YearsTo(payment.Date, loan) * payment.Amount; 28 | } 29 | 30 | if (Math.Abs(loan.GetCommitment()) > EPSILON) 31 | { 32 | duration = weightedAverage / sumOfPayments; 33 | } 34 | 35 | return duration; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /FormTemplateMethod/MyWork/Loan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FormTemplateMethod.MyWork 5 | { 6 | public class Loan 7 | { 8 | double _commitment = 1.0; 9 | private DateTime? _expiry; 10 | private DateTime? _maturity; 11 | private double _outstanding; 12 | IList _payments = new List(); 13 | private DateTime? _today = DateTime.Now; 14 | private DateTime _start; 15 | private long MILLIS_PER_DAY = 86400000; 16 | private long DAYS_PER_YEAR = 365; 17 | private double _riskRating; 18 | private double _unusedPercentage; 19 | private CapitalStrategy _capitalStrategy; 20 | 21 | public Loan(double commitment, 22 | double notSureWhatThisIs, 23 | DateTime start, 24 | DateTime? expiry, 25 | DateTime? maturity, 26 | int riskRating, 27 | CapitalStrategy capitalStrategy) 28 | { 29 | this._expiry = expiry; 30 | this._commitment = commitment; 31 | this._today = null; 32 | this._start = start; 33 | this._maturity = maturity; 34 | this._riskRating = riskRating; 35 | this._unusedPercentage = 1.0; 36 | this._capitalStrategy = capitalStrategy; 37 | } 38 | 39 | public static Loan NewTermLoan(double commitment, DateTime start, DateTime maturity, int riskRating) 40 | { 41 | return new Loan(commitment, commitment, start, null, 42 | maturity, riskRating, new CapitalStrategyTermLoan()); 43 | } 44 | 45 | public static Loan NewRevolver(double commitment, DateTime start, DateTime expiry, int riskRating) 46 | { 47 | return new Loan(commitment, 0, start, expiry, 48 | null, riskRating, new CapitalStrategyRevolver()); 49 | } 50 | 51 | public static Loan NewAdvisedLine(double commitment, DateTime start, DateTime expiry, int riskRating) 52 | { 53 | if (riskRating > 3) return null; 54 | Loan advisedLine = new Loan(commitment, 0, start, expiry, 55 | null, riskRating, new CapitalStrategyAdvisedLine()); 56 | advisedLine.SetUnusedPercentage(0.1); 57 | return advisedLine; 58 | } 59 | 60 | public DateTime? GetExpiry() 61 | { 62 | return _expiry; 63 | } 64 | 65 | public double GetCommitment() 66 | { 67 | return _commitment; 68 | } 69 | 70 | public DateTime? GetMaturity() 71 | { 72 | return _maturity; 73 | } 74 | 75 | public double GetRiskRating() 76 | { 77 | return _riskRating; 78 | } 79 | 80 | public void Payment(double amount, DateTime paymentDate) 81 | { 82 | _payments.Add(new Payment(amount, paymentDate)); 83 | } 84 | 85 | public double Capital() 86 | { 87 | return _capitalStrategy.Capital(this); 88 | } 89 | 90 | public DateTime? GetToday() 91 | { 92 | return _today; 93 | } 94 | 95 | public DateTime? GetStart() 96 | { 97 | return _start; 98 | } 99 | 100 | public IList Payments() 101 | { 102 | return _payments; 103 | } 104 | 105 | public double GetUnusedPercentage() 106 | { 107 | return _unusedPercentage; 108 | } 109 | 110 | public void SetUnusedPercentage(double unusedPercentage) 111 | { 112 | _unusedPercentage = unusedPercentage; 113 | } 114 | 115 | public double UnusedRiskAmount() 116 | { 117 | return (_commitment - _outstanding); 118 | } 119 | 120 | public double OutstandingRiskAmount() 121 | { 122 | return _outstanding; 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /FormTemplateMethod/MyWork/Payment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FormTemplateMethod.MyWork 4 | 5 | { 6 | public class Payment 7 | { 8 | private double _amount; 9 | private DateTime _date; 10 | 11 | public Payment() 12 | { 13 | _amount = 0.0; 14 | _date = new DateTime(); 15 | } 16 | 17 | public Payment(double amount, DateTime date) 18 | { 19 | Amount = amount; 20 | Date = date; 21 | } 22 | 23 | public double Amount 24 | { 25 | get { return _amount; } 26 | 27 | private set { _amount = value; } 28 | } 29 | 30 | public DateTime Date 31 | { 32 | get { return _date; } 33 | 34 | private set { _date = value; } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /FormTemplateMethod/MyWork/RiskFactor.cs: -------------------------------------------------------------------------------- 1 | namespace FormTemplateMethod.MyWork 2 | { 3 | public class RiskFactor 4 | { 5 | private RiskFactor() 6 | { 7 | 8 | } 9 | 10 | public static RiskFactor GetFactors() 11 | { 12 | return new RiskFactor(); 13 | } 14 | 15 | public double ForRating(double riskRating) 16 | { 17 | return 0.03; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /FormTemplateMethod/MyWork/UnusedRiskFactors.cs: -------------------------------------------------------------------------------- 1 | namespace FormTemplateMethod.MyWork 2 | { 3 | public class UnusedRiskFactors 4 | { 5 | private UnusedRiskFactors() 6 | { 7 | 8 | } 9 | 10 | public static UnusedRiskFactors GetFactors() 11 | { 12 | return new UnusedRiskFactors(); 13 | } 14 | 15 | public double ForRating(double riskRating) 16 | { 17 | return 0.01; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /FormTemplateMethod/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("FormTemplateMethod")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /MoveAccumulationToCollectingParameter/InitialCode/TagNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MoveAccumulationToCollectingParameter.InitialCode 5 | { 6 | public class TagNode 7 | { 8 | private string _tagName; 9 | private string _attributes; 10 | private readonly string _value; 11 | private List _children; 12 | 13 | public TagNode(string tagName, string attributes, string value) 14 | { 15 | _attributes = attributes; 16 | _value = value; 17 | _tagName = tagName; 18 | _children = new List(); 19 | } 20 | 21 | public void Add(TagNode childNode) 22 | { 23 | _children.Add(childNode); 24 | } 25 | 26 | public override string ToString() 27 | { 28 | string result = String.Empty; 29 | 30 | result += "<" + _tagName + " " + _attributes + ">"; 31 | 32 | if (!_value.Equals("")) 33 | { 34 | result += _value; 35 | } 36 | 37 | foreach (TagNode child in _children) 38 | { 39 | result += child.ToString(); 40 | } 41 | 42 | result += ""; 43 | return result; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /MoveAccumulationToCollectingParameter/MoveAccumulationToCollectingParameter.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E55105E2-9A9C-4C43-9E98-EF308663F77D} 8 | Library 9 | Properties 10 | MoveAccumulationToCollectingParameter 11 | MoveAccumulationToCollectingParameter 12 | v4.8 13 | 512 14 | 9 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /MoveAccumulationToCollectingParameter/MyWork/TagNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace MoveAccumulationToCollectingParameter.MyWork 5 | { 6 | public class TagNode 7 | { 8 | private string _tagName; 9 | private string _attributes; 10 | private readonly string _value; 11 | private List _children; 12 | 13 | public TagNode(string tagName, string attributes, string value) 14 | { 15 | _attributes = attributes; 16 | _value = value; 17 | _tagName = tagName; 18 | _children = new List(); 19 | } 20 | 21 | public void Add(TagNode childNode) 22 | { 23 | _children.Add(childNode); 24 | } 25 | 26 | public override string ToString() 27 | { 28 | string result = String.Empty; 29 | 30 | result += "<" + _tagName + " " + _attributes + ">"; 31 | 32 | if (!_value.Equals("")) 33 | { 34 | result += _value; 35 | } 36 | 37 | foreach (TagNode child in _children) 38 | { 39 | result += child.ToString(); 40 | } 41 | 42 | result += ""; 43 | return result; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /MoveAccumulationToCollectingParameter/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("MoveAccumulationToCollectingParameter")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("MoveAccumulationToCollectingParameter")] 12 | [assembly: AssemblyCopyright("Copyright © 2020")] 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("E55105E2-9A9C-4C43-9E98-EF308663F77D")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/InitialCode/DOMBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.InitialCode 2 | { 3 | public class DOMBuilder : OutputBuilder 4 | { 5 | public DOMBuilder(string root) 6 | { 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/InitialCode/DOMBuilderTest.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.InitialCode 2 | { 3 | public class DOMBuilderTest: TestCase 4 | { 5 | public OutputBuilder Builder { get; private set; } 6 | 7 | public void TestAddAboveRoot() 8 | { 9 | string invalidResult = 10 | "" + 11 | "" + 12 | "" + 13 | "" + 14 | "" + 15 | ""; 16 | 17 | Builder = new DOMBuilder("orders"); 18 | 19 | Builder.AddBelow("order"); 20 | 21 | try 22 | { 23 | Builder.AddAbove("customer"); 24 | Fail("expecting RuntimeException"); 25 | } 26 | catch (RuntimeException ignored) 27 | { 28 | 29 | } 30 | } 31 | 32 | private void Fail(string failureMessage) 33 | { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/InitialCode/OutputBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.InitialCode 2 | { 3 | public class OutputBuilder 4 | { 5 | public void AddBelow(string v) 6 | { 7 | } 8 | 9 | public void AddAbove(string v) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/InitialCode/RuntimeException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace PolymorphicCreationWithFactoryMethod.InitialCode 5 | { 6 | [Serializable] 7 | public class RuntimeException : Exception 8 | { 9 | public RuntimeException() 10 | { 11 | } 12 | 13 | public RuntimeException(string message) : base(message) 14 | { 15 | } 16 | 17 | public RuntimeException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | protected RuntimeException(SerializationInfo info, StreamingContext context) : base(info, context) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/InitialCode/TestCase.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.InitialCode 2 | { 3 | public class TestCase 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/InitialCode/XMLBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.InitialCode 2 | { 3 | public class XMLBuilder : OutputBuilder 4 | { 5 | public XMLBuilder(string root) 6 | { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/InitialCode/XMLBuilderTest.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.InitialCode 2 | { 3 | public class XMLBuilderTest: TestCase 4 | { 5 | public OutputBuilder Builder { get; private set; } 6 | 7 | public void TestAddAboveRoot() 8 | { 9 | string invalidResult = 10 | "" + 11 | "" + 12 | "" + 13 | "" + 14 | "" + 15 | ""; 16 | 17 | Builder = new XMLBuilder("orders"); 18 | 19 | Builder.AddBelow("order"); 20 | 21 | try 22 | { 23 | Builder.AddAbove("customer"); 24 | Fail("expecting RuntimeException"); 25 | } 26 | catch (RuntimeException ignored) 27 | { 28 | 29 | } 30 | } 31 | 32 | private void Fail(string failureMessage) 33 | { 34 | 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/MyWork/DOMBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.MyWork 2 | { 3 | public class DOMBuilder : OutputBuilder 4 | { 5 | public DOMBuilder(string root) 6 | { 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/MyWork/DOMBuilderTest.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.MyWork 2 | { 3 | public class DOMBuilderTest: TestCase 4 | { 5 | public OutputBuilder Builder { get; private set; } 6 | 7 | public void TestAddAboveRoot() 8 | { 9 | string invalidResult = 10 | "" + 11 | "" + 12 | "" + 13 | "" + 14 | "" + 15 | ""; 16 | 17 | Builder = new DOMBuilder("orders"); 18 | 19 | Builder.AddBelow("order"); 20 | 21 | try 22 | { 23 | Builder.AddAbove("customer"); 24 | Fail("expecting RuntimeException"); 25 | } 26 | catch (RuntimeException ignored) 27 | { 28 | 29 | } 30 | } 31 | 32 | private void Fail(string failureMessage) 33 | { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/MyWork/OutputBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.MyWork 2 | { 3 | public class OutputBuilder 4 | { 5 | public void AddBelow(string v) 6 | { 7 | } 8 | 9 | public void AddAbove(string v) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/MyWork/RuntimeException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace PolymorphicCreationWithFactoryMethod.MyWork 5 | { 6 | [Serializable] 7 | public class RuntimeException : Exception 8 | { 9 | public RuntimeException() 10 | { 11 | } 12 | 13 | public RuntimeException(string message) : base(message) 14 | { 15 | } 16 | 17 | public RuntimeException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | protected RuntimeException(SerializationInfo info, StreamingContext context) : base(info, context) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/MyWork/TestCase.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.MyWork 2 | { 3 | public class TestCase 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/MyWork/XMLBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.MyWork 2 | { 3 | public class XMLBuilder : OutputBuilder 4 | { 5 | public XMLBuilder(string root) 6 | { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/MyWork/XMLBuilderTest.cs: -------------------------------------------------------------------------------- 1 | namespace PolymorphicCreationWithFactoryMethod.MyWork 2 | { 3 | public class XMLBuilderTest: TestCase 4 | { 5 | public OutputBuilder Builder { get; private set; } 6 | 7 | public void TestAddAboveRoot() 8 | { 9 | string invalidResult = 10 | "" + 11 | "" + 12 | "" + 13 | "" + 14 | "" + 15 | ""; 16 | 17 | Builder = new XMLBuilder("orders"); 18 | 19 | Builder.AddBelow("order"); 20 | 21 | try 22 | { 23 | Builder.AddAbove("customer"); 24 | Fail("expecting RuntimeException"); 25 | } 26 | catch (RuntimeException ignored) 27 | { 28 | 29 | } 30 | } 31 | 32 | private void Fail(string failureMessage) 33 | { 34 | 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/PolymorphicCreationWithFactoryMethod.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {632ABCBD-B56E-427B-B00B-ECFCEFFEF0D5} 7 | Library 8 | PolymorphicCreationWithFactoryMethod 9 | PolymorphicCreationWithFactoryMethod 10 | v4.8 11 | 9 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /PolymorphicCreationWithFactoryMethod/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("PolymorphicCreationWithFactoryMethod")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Refactoring To Patterns 2 | A place to practice Refactoring To Patterns that Kerievsky wrote about in his book. 3 | 4 | This repo contains source code that very closely or exactly matches that which is found in Joshua Kerievsky's book [Refactoring to Patterns](https://www.amazon.com/Refactoring-Patterns-Joshua-Kerievsky/dp/0321213351). 5 | 6 | Have to say thank you to Joshua for putting all of these patterns together and for making them easily consumable. If you have landed here and are interested in other things [Joshua](https://www.industriallogic.com/people/joshua) has put out, I encourage you to check out the following links: 7 | 8 | * [Industrial Logic](https://www.industriallogic.com/) - His consultancy and source of some great e-Learnin. 9 | * [Modern Agile](http://modernagile.org/) - A community for people interested in better ways of building software. 10 | * [Modern Agile Show](https://www.youtube.com/channel/UCMwCSEyUk59V8IQADpdn5PA) - Vids of him speaking about Modern Agile. 11 | 12 | # Getting Around 13 | 14 | ## Language && IDE Concerns 15 | All code samples are written in C#, and therefor will follow C# coding conventions (versus any Java coding conventions you might see in the book). 16 | 17 | I have tested running this code in the following IDE's, and all seems to work fine: 18 | * [Visual Studio 2015 (on Windows)](https://www.visualstudio.com/vs/older-downloads/) 19 | * [Visual Studio Community 2017 (for Mac)](https://www.visualstudio.com/vs/visual-studio-mac/) 20 | * [Rider EAP versions (on Windows)](https://www.jetbrains.com/rider/) 21 | 22 | There might be an issue with Visual Studio 2017 (on Windows), but I've not been able to dig into it as of yet. 23 | 24 | ### Other Language Implementations 25 | 26 | A big thank you to several friends that have converted this repo to other languages. 27 | 28 | * [Java](https://github.com/dillius/RefactoringToPatternsJava) 29 | * [JavaScript](https://github.com/TonyAshworth/patterns-workgroup) 30 | 31 | ## What you'll find here 32 | Each refactoring that he walks through has it's own project. For example, you will notice that there is a project titled "ReplaceConstructorsWithCreationMethods". This project corresponds to code he offers up on p. 57 in his section titled "Replace Constructors with Creation Methods" 33 | 34 | ### IntialCode folder 35 | You will also notice that within the "ReplaceConstructorsWithCreationMethods" there is a folder titled "InitialCode". This folder is intended to contain working code that demonstrates the problem as he initially presents it in the book. 36 | 37 | ### MyWork folder 38 | There is also a folder titled "MyWork". This folder initially carries an exact copy of what's in the "InitialCode" folder. However, the intention of the "MyWork" folder is that it is a place for you to experiment with in implementing the refactoring. In this way, once you have implemented the refactoring, you have the ability to look at both the initial problem and the refactored solution and weigh the benefits of one pattern (or lack thereof) and the code refactored to or towards a pattern. 39 | 40 | ### RefactoringToPatterns.Tests Project 41 | 42 | This project also contains sections for each refactoring, but it differs from what I meantioned before in that it has unit tests that in 43 | some way excercise the code found in the implemented code project. 44 | 45 | For example, if you look in the RefactoringToPatterns.Tests project you will see a section for "ReplaceConstructorsWithCreationMethods". This should sound familiar as I mentioned it before. This section of the tests project also has an "InitialCode" section and a "MyWork" section. Each of these sections contains unit tests linking out to the actual implmentations. Like before, your "MyWork" section is a place for you to experiment with as you move through the refactoring as it's discussed in the book. 46 | 47 | ## Conclusion 48 | 49 | Take a look around. If anything doesn't make sense once you peek at it, please just create an Issue here in GitHub where we 50 | can discuss it. Like any system, if you want to understand how it works, go look at the tests as they are a great durrable source of low level documentation. 51 | 52 | ## On a Personal Note 53 | 54 | I've put all of my work on a branch with my name on it [corywheeler](https://github.com/corywheeler/refactoringtopatterns/tree/corywheeler). There you'll see the refactorings implemented such that the MyWork folders will differ from the Initial Code folders so you can see the solution in before and after states. 55 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ChainConstructors/InitialCode/CapitalCalculationTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using ChainConstructors.InitialCode; 3 | using System; 4 | 5 | namespace RefactoringToPatterns.ChainConstructors.InitialCode 6 | { 7 | [TestFixture] 8 | public class CapitalCalculationTests 9 | { 10 | [SetUp] 11 | public void Init() 12 | { 13 | } 14 | 15 | [Test] 16 | public void four_parameter_constructor_yields_loan_with_TermROC_strategy() 17 | { 18 | Loan loan = new Loan(1.0f, 2.0f, 4, new DateTime()); 19 | Assert.IsInstanceOf(typeof(TermROC), loan.CapitalStrategy); 20 | } 21 | 22 | [Test] 23 | public void five_parameter_constructor_yields_revolving_TermROC_strategy() 24 | { 25 | Loan loan = new Loan(1.0f, 2.0f, 4, new DateTime(), new DateTime()); 26 | Assert.IsInstanceOf(typeof(RevolvingTermROC), loan.CapitalStrategy); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ChainConstructors/MyWork/CapitalCalculationTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using ChainConstructors.MyWork; 3 | using System; 4 | 5 | namespace RefactoringToPatterns.ChainConstructors.MyWork 6 | { 7 | [TestFixture] 8 | public class CapitalCalculationTests 9 | { 10 | [SetUp] 11 | public void Init() 12 | { 13 | } 14 | 15 | [Test] 16 | public void four_parameter_constructor_yields_loan_with_TermROC_strategy() 17 | { 18 | Loan loan = new Loan(1.0f, 2.0f, 4, new DateTime()); 19 | Assert.IsInstanceOf(typeof(TermROC), loan.CapitalStrategy); 20 | } 21 | 22 | [Test] 23 | public void five_parameter_constructor_yields_revolving_TermROC_strategy() 24 | { 25 | Loan loan = new Loan(1.0f, 2.0f, 4, new DateTime(), new DateTime()); 26 | Assert.IsInstanceOf(typeof(RevolvingTermROC), loan.CapitalStrategy); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ComposeMethod/InitialCode/ListTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using List = ComposeMethod.InitialCode.List; 3 | 4 | namespace RefactoringToPatterns.ComposeMethod.InitialCode 5 | { 6 | [TestFixture()] 7 | public class ListTests 8 | { 9 | [Test()] 10 | public void it_tells_the_count_of_how_many_things_it_contains() 11 | { 12 | var list = new List(); 13 | list.Add(new {}); 14 | Assert.AreEqual(1, list.Count); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ComposeMethod/MyWork/ListTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using List = ComposeMethod.MyWork.List; 3 | 4 | namespace RefactoringToPatterns.ComposeMethod.MyWork 5 | { 6 | [TestFixture()] 7 | public class ListTests 8 | { 9 | [Test()] 10 | public void it_tells_the_count_of_how_many_things_it_contains() 11 | { 12 | var list = new List(); 13 | list.Add(new {}); 14 | Assert.AreEqual(1, list.Count); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/EncapsulateClassesWithFactory/InitialCode/Mappers/DescriptorMapperTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using EncapsulateClassesWithFactory.InitialCode.Descriptors; 3 | using EncapsulateClassesWithFactory.InitialCode.Mappers; 4 | using System.Collections.Generic; 5 | 6 | namespace RefactoringToPatterns.EncapsulateClassesWithFactory.InitialCode.Mappers 7 | { 8 | [TestFixture] 9 | public class DescriptorMapperTests 10 | { 11 | TestingDescriptorMapper testDescriptorMapper; 12 | 13 | [SetUp] 14 | public void Init() 15 | { 16 | testDescriptorMapper = new TestingDescriptorMapper(); 17 | } 18 | 19 | [Test] 20 | public void it_maps_remoteId_descriptor_as_DefaultDescriptor() 21 | { 22 | var remoteIdDescriptor = 23 | testDescriptorMapper.GetMappedDescriptorFor("remoteId"); 24 | 25 | Assert.IsInstanceOf(typeof(DefaultDescriptor),remoteIdDescriptor); 26 | } 27 | 28 | [Test] 29 | public void it_maps_createdDate_descriptor_as_DefaultDescriptor() 30 | { 31 | var createdDateDescriptor = 32 | testDescriptorMapper.GetMappedDescriptorFor("createdDate"); 33 | 34 | Assert.IsInstanceOf(typeof(DefaultDescriptor), createdDateDescriptor); 35 | } 36 | 37 | [Test] 38 | public void it_maps_lastChangedDate_descriptor_as_DefaultDescriptor() 39 | { 40 | var lastChangedDateDescriptor = 41 | testDescriptorMapper.GetMappedDescriptorFor("lastChangedDate"); 42 | 43 | Assert.IsInstanceOf(typeof(DefaultDescriptor), lastChangedDateDescriptor); 44 | } 45 | 46 | [Test] 47 | public void it_maps_createdBy_descriptor_as_ReferenceDescriptor() 48 | { 49 | var createdByDescriptor = 50 | testDescriptorMapper.GetMappedDescriptorFor("createdBy"); 51 | 52 | Assert.IsInstanceOf(typeof(ReferenceDescriptor), createdByDescriptor); 53 | } 54 | 55 | [Test] 56 | public void it_maps_lastChangedBy_descriptor_ReferenceDescriptor() 57 | { 58 | var lastChangedByDescriptor = 59 | testDescriptorMapper.GetMappedDescriptorFor("lastChangedBy"); 60 | 61 | Assert.IsInstanceOf(typeof(ReferenceDescriptor), lastChangedByDescriptor); 62 | } 63 | 64 | [Test] 65 | public void it_maps_optimisticLockVersion_descriptor_as_DefaultDescriptor() 66 | { 67 | var optimisticLockVersionDescriptor = 68 | testDescriptorMapper.GetMappedDescriptorFor("optimisticLockVersion"); 69 | 70 | Assert.IsInstanceOf(typeof(DefaultDescriptor), optimisticLockVersionDescriptor); 71 | } 72 | 73 | [Test] 74 | public void it_does_not_map_unknown_descriptors() 75 | { 76 | var unknownDescriptor = 77 | testDescriptorMapper.GetMappedDescriptorFor("unknown"); 78 | 79 | Assert.Null(unknownDescriptor); 80 | } 81 | } 82 | 83 | internal class TestingDescriptorMapper : DescriptorMapper { 84 | List descriptors; 85 | 86 | public TestingDescriptorMapper() { 87 | descriptors = CreateAttributeDescriptors(); 88 | } 89 | 90 | public AttributeDescriptor GetMappedDescriptorFor(string descriptorName) 91 | { 92 | return descriptors.Find(descriptor => descriptor.DescriptorName == descriptorName); 93 | } 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/EncapsulateClassesWithFactory/MyWork/Mappers/DescriptorMapperTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using EncapsulateClassesWithFactory.MyWork.Descriptors; 3 | using EncapsulateClassesWithFactory.MyWork.Mappers; 4 | using System.Collections.Generic; 5 | 6 | namespace RefactoringToPatterns.EncapsulateClassesWithFactory.MyWork.Mappers 7 | { 8 | [TestFixture] 9 | public class DescriptorMapperTests 10 | { 11 | TestingDescriptorMapper testDescriptorMapper; 12 | 13 | [SetUp] 14 | public void Init() 15 | { 16 | testDescriptorMapper = new TestingDescriptorMapper(); 17 | } 18 | 19 | [Test] 20 | public void it_maps_remoteId_descriptor_as_DefaultDescriptor() 21 | { 22 | var remoteIdDescriptor = 23 | testDescriptorMapper.GetMappedDescriptorFor("remoteId"); 24 | 25 | Assert.IsInstanceOf(typeof(DefaultDescriptor),remoteIdDescriptor); 26 | } 27 | 28 | [Test] 29 | public void it_maps_createdDate_descriptor_as_DefaultDescriptor() 30 | { 31 | var createdDateDescriptor = 32 | testDescriptorMapper.GetMappedDescriptorFor("createdDate"); 33 | 34 | Assert.IsInstanceOf(typeof(DefaultDescriptor), createdDateDescriptor); 35 | } 36 | 37 | [Test] 38 | public void it_maps_lastChangedDate_descriptor_as_DefaultDescriptor() 39 | { 40 | var lastChangedDateDescriptor = 41 | testDescriptorMapper.GetMappedDescriptorFor("lastChangedDate"); 42 | 43 | Assert.IsInstanceOf(typeof(DefaultDescriptor), lastChangedDateDescriptor); 44 | } 45 | 46 | [Test] 47 | public void it_maps_createdBy_descriptor_as_ReferenceDescriptor() 48 | { 49 | var createdByDescriptor = 50 | testDescriptorMapper.GetMappedDescriptorFor("createdBy"); 51 | 52 | Assert.IsInstanceOf(typeof(ReferenceDescriptor), createdByDescriptor); 53 | } 54 | 55 | [Test] 56 | public void it_maps_lastChangedBy_descriptor_ReferenceDescriptor() 57 | { 58 | var lastChangedByDescriptor = 59 | testDescriptorMapper.GetMappedDescriptorFor("lastChangedBy"); 60 | 61 | Assert.IsInstanceOf(typeof(ReferenceDescriptor), lastChangedByDescriptor); 62 | } 63 | 64 | [Test] 65 | public void it_maps_optimisticLockVersion_descriptor_as_DefaultDescriptor() 66 | { 67 | var optimisticLockVersionDescriptor = 68 | testDescriptorMapper.GetMappedDescriptorFor("optimisticLockVersion"); 69 | 70 | Assert.IsInstanceOf(typeof(DefaultDescriptor), optimisticLockVersionDescriptor); 71 | } 72 | 73 | [Test] 74 | public void it_does_not_map_unknown_descriptors() 75 | { 76 | var unknownDescriptor = 77 | testDescriptorMapper.GetMappedDescriptorFor("unknown"); 78 | 79 | Assert.Null(unknownDescriptor); 80 | } 81 | } 82 | 83 | internal class TestingDescriptorMapper : DescriptorMapper { 84 | List descriptors; 85 | 86 | public TestingDescriptorMapper() { 87 | descriptors = CreateAttributeDescriptors(); 88 | } 89 | 90 | public AttributeDescriptor GetMappedDescriptorFor(string descriptorName) 91 | { 92 | return descriptors.Find(descriptor => descriptor.DescriptorName == descriptorName); 93 | } 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/EncapsulateCompositeWithBuilder/InitialCode/TagNodeTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using EncapsulateCompositeWithBuilder.InitialCode; 3 | 4 | namespace RefactoringToPatterns.EncapsulateCompositeWithBuilder.InitialCode 5 | { 6 | [TestFixture] 7 | public class TagNodeTests 8 | { 9 | private const string SamplePrice = "2.39"; 10 | 11 | [Test] 12 | public void TestSimpleTagWithOneAttributeAndValue() 13 | { 14 | var expected = 15 | "" + 19 | SamplePrice + 20 | ""; 21 | 22 | TagNode priceTag = new TagNode("price"); 23 | priceTag.AddAttribute("currency", "USD"); 24 | priceTag.AddValue(SamplePrice); 25 | Assert.AreEqual(expected, priceTag.ToString()); 26 | } 27 | 28 | [Test] 29 | public void TestCompositeTagoneChild() 30 | { 31 | var expected = 32 | "" + 33 | "" + 34 | "" + 35 | ""; 36 | 37 | TagNode productTag = new TagNode("product"); 38 | productTag.Add(new TagNode("price")); 39 | 40 | Assert.AreEqual(expected, productTag.ToString()); 41 | } 42 | 43 | [Test] 44 | public void TestAddingChildrenAndGrandChildren() 45 | { 46 | var expected = 47 | "" + 48 | "" + 49 | "" + 50 | "" + 51 | "" + 52 | ""; 53 | 54 | TagNode ordersTag = new TagNode("orders"); 55 | TagNode orderTag = new TagNode("order"); 56 | orderTag.Add(new TagNode("product")); 57 | ordersTag.Add(orderTag); 58 | 59 | Assert.AreEqual(expected, ordersTag.ToString()); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/EncapsulateCompositeWithBuilder/MyWork/TagNodeTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using EncapsulateCompositeWithBuilder.MyWork; 3 | 4 | namespace RefactoringToPatterns.EncapsulateCompositeWithBuilder.MyWork 5 | { 6 | [TestFixture] 7 | public class TagNodeTests 8 | { 9 | private const string SamplePrice = "2.39"; 10 | 11 | [Test] 12 | public void TestSimpleTagWithOneAttributeAndValue() 13 | { 14 | var expected = 15 | "" + 19 | SamplePrice + 20 | ""; 21 | 22 | TagNode priceTag = new TagNode("price"); 23 | priceTag.AddAttribute("currency", "USD"); 24 | priceTag.AddValue(SamplePrice); 25 | Assert.AreEqual(expected, priceTag.ToString()); 26 | } 27 | 28 | [Test] 29 | public void TestCompositeTagoneChild() 30 | { 31 | var expected = 32 | "" + 33 | "" + 34 | "" + 35 | ""; 36 | 37 | TagNode productTag = new TagNode("product"); 38 | productTag.Add(new TagNode("price")); 39 | 40 | Assert.AreEqual(expected, productTag.ToString()); 41 | } 42 | 43 | [Test] 44 | public void TestAddingChildrenAndGrandChildren() 45 | { 46 | var expected = 47 | "" + 48 | "" + 49 | "" + 50 | "" + 51 | "" + 52 | ""; 53 | 54 | TagNode ordersTag = new TagNode("orders"); 55 | TagNode orderTag = new TagNode("order"); 56 | orderTag.Add(new TagNode("product")); 57 | ordersTag.Add(orderTag); 58 | 59 | Assert.AreEqual(expected, ordersTag.ToString()); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ExtractComposite/InitialCode/FormTagTests.cs: -------------------------------------------------------------------------------- 1 | using ExtractComposite.InitialCode; 2 | using NUnit.Framework; 3 | 4 | namespace RefactoringToPatterns.ExtractComposite.InitialCode 5 | { 6 | [TestFixture] 7 | public class FormTagTests 8 | { 9 | private FormTag _formTag; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _formTag = new FormTag(); 15 | } 16 | 17 | [Test] 18 | public void it_should_output_a_non_html_formatted_text_representation() 19 | { 20 | _formTag.AddChild(new LabelTag(new StringNode("Hi, I'm A Label."))); 21 | _formTag.AddChild(new LabelTag(new StringNode("You're not the only one, I'm a Label too!"))); 22 | 23 | Assert.AreEqual("Hi, I'm A Label.You're not the only one, I'm a Label too!",_formTag.ToPlainTextString()); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ExtractComposite/InitialCode/LabelTagTests.cs: -------------------------------------------------------------------------------- 1 | using ExtractComposite.InitialCode; 2 | using NUnit.Framework; 3 | 4 | namespace RefactoringToPatterns.ExtractComposite.InitialCode 5 | { 6 | [TestFixture] 7 | public class LabelTagTests 8 | { 9 | private LabelTag _labelTag; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _labelTag = new LabelTag(new StringNode("Name:")); 15 | } 16 | 17 | [Test] 18 | public void it_should_output_a_non_html_formatted_text_representation() 19 | { 20 | Assert.AreEqual("Name:", _labelTag.ToPlainTextString()); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ExtractComposite/InitialCode/LinkTagTests.cs: -------------------------------------------------------------------------------- 1 | using ExtractComposite.InitialCode; 2 | using NUnit.Framework; 3 | 4 | namespace RefactoringToPatterns.ExtractComposite.InitialCode 5 | { 6 | [TestFixture] 7 | public class LinkTagTests 8 | { 9 | LinkTag _linkTag; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _linkTag = new LinkTag(); 15 | } 16 | 17 | [Test] 18 | public void it_should_output_a_non_html_formatted_text_representation() 19 | { 20 | _linkTag.AddChild(new StringNode("Hi, I'm Link.")); 21 | _linkTag.AddChild(new StringNode("My text becomes a link!")); 22 | 23 | Assert.AreEqual("Hi, I'm Link.My text becomes a link!",_linkTag.ToPlainTextString()); 24 | } 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ExtractComposite/MyWork/FormTagTests.cs: -------------------------------------------------------------------------------- 1 | using ExtractComposite.MyWork; 2 | using NUnit.Framework; 3 | 4 | namespace RefactoringToPatterns.ExtractComposite.MyWork 5 | { 6 | [TestFixture] 7 | public class FormTagTests 8 | { 9 | private FormTag _formTag; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _formTag = new FormTag(); 15 | } 16 | 17 | [Test] 18 | public void it_should_output_a_non_html_formatted_text_representation() 19 | { 20 | _formTag.AddChild(new LabelTag(new StringNode("Hi, I'm A Label."))); 21 | _formTag.AddChild(new LabelTag(new StringNode("You're not the only one, I'm a Label too!"))); 22 | 23 | Assert.AreEqual("Hi, I'm A Label.You're not the only one, I'm a Label too!",_formTag.ToPlainTextString()); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ExtractComposite/MyWork/LabelTagTests.cs: -------------------------------------------------------------------------------- 1 | using ExtractComposite.MyWork; 2 | using NUnit.Framework; 3 | 4 | namespace RefactoringToPatterns.ExtractComposite.MyWork 5 | { 6 | [TestFixture] 7 | public class LabelTagTests 8 | { 9 | private LabelTag _labelTag; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _labelTag = new LabelTag(new StringNode("Name:")); 15 | } 16 | 17 | [Test] 18 | public void it_should_output_a_non_html_formatted_text_representation() 19 | { 20 | Assert.AreEqual("Name:", _labelTag.ToPlainTextString()); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ExtractComposite/MyWork/LinkTagTests.cs: -------------------------------------------------------------------------------- 1 | using ExtractComposite.MyWork; 2 | using NUnit.Framework; 3 | 4 | namespace RefactoringToPatterns.ExtractComposite.MyWork 5 | { 6 | [TestFixture] 7 | public class LinkTagTests 8 | { 9 | LinkTag _linkTag; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _linkTag = new LinkTag(); 15 | } 16 | 17 | [Test] 18 | public void it_should_output_a_non_html_formatted_text_representation() 19 | { 20 | _linkTag.AddChild(new StringNode("Hi, I'm Link.")); 21 | _linkTag.AddChild(new StringNode("My text becomes a link!")); 22 | 23 | Assert.AreEqual("Hi, I'm Link.My text becomes a link!",_linkTag.ToPlainTextString()); 24 | } 25 | 26 | } 27 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/FormTemplateMethod/InitialCode/AdvisedLineStrategyTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using FormTemplateMethod.InitialCode; 4 | 5 | namespace RefactoringToPatterns.FormTemplateMethod.InitialCode 6 | { 7 | [TestFixture()] 8 | public class AdvisedLineStrategyTests 9 | { 10 | private readonly int LOW_RISK_TAKING = 2; 11 | private readonly double LOAN_AMOUNT = 10000.00; 12 | private readonly double TWO_DIGIT_PRECISION = 0.001; 13 | 14 | [Test()] 15 | public void test_advised_line_loan_same_payments() 16 | { 17 | var advisedLineStrategy = new CapitalStrategyAdvisedLine(); 18 | DateTime start = November(20, 2003); 19 | DateTime maturity = November(20, 2006); 20 | DateTime expiry = November(20, 2007); 21 | 22 | Loan advisedLineLoan = Loan.NewAdvisedLine(LOAN_AMOUNT, start, expiry, LOW_RISK_TAKING); 23 | advisedLineLoan.Payment(1000.00, November(20, 2004)); 24 | advisedLineLoan.Payment(1000.00, November(20, 2005)); 25 | advisedLineLoan.Payment(1000.00, November(20, 2006)); 26 | 27 | Assert.AreEqual(40027, advisedLineStrategy.Duration(advisedLineLoan), TWO_DIGIT_PRECISION); 28 | Assert.AreEqual(1200810, advisedLineStrategy.Capital(advisedLineLoan), TWO_DIGIT_PRECISION); 29 | } 30 | 31 | private static DateTime November(int dayOfMonth, int year) 32 | { 33 | return new DateTime(year, 11, dayOfMonth); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/FormTemplateMethod/InitialCode/PaymentTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using FormTemplateMethod.InitialCode; 4 | 5 | namespace RefactoringToPatterns.FormTemplateMethod.InitialCode 6 | { 7 | [TestFixture()] 8 | public class PaymentTests 9 | { 10 | private Payment _payment; 11 | private DateTime _christmasDay; 12 | 13 | [SetUp] 14 | public void Init() 15 | { 16 | _christmasDay = new DateTime(2010, 12, 25); 17 | _payment = new Payment(1000.0, _christmasDay); 18 | } 19 | 20 | [Test()] 21 | public void payment_is_constructed_correctly() 22 | { 23 | 24 | Assert.Multiple(() => { 25 | Assert.AreEqual(1000, _payment.Amount); 26 | Assert.AreEqual(_christmasDay, _payment.Date); 27 | }); 28 | 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/FormTemplateMethod/InitialCode/RevolverStrategyTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using FormTemplateMethod.InitialCode; 4 | 5 | namespace RefactoringToPatterns.FormTemplateMethod.InitialCode 6 | { 7 | [TestFixture()] 8 | public class RevolverStrategyTests 9 | { 10 | private readonly int HIGH_RISK_TAKING = 5; 11 | private readonly double LOAN_AMOUNT = 10000.00; 12 | private readonly double TWO_DIGIT_PRECISION = 0.001; 13 | 14 | [Test()] 15 | public void test_revolver_loan_same_payments() 16 | { 17 | var revolverStrategy = new CapitalStrategyRevolver(); 18 | DateTime start = November(20, 2003); 19 | DateTime expiry = November(20, 2007); 20 | 21 | Loan revolverLoan = Loan.NewRevolver(LOAN_AMOUNT, start, expiry, HIGH_RISK_TAKING); 22 | revolverLoan.Payment(1000.00, November(20, 2004)); 23 | revolverLoan.Payment(1000.00, November(20, 2005)); 24 | revolverLoan.Payment(1000.00, November(20, 2006)); 25 | 26 | Assert.Multiple(() => { 27 | Assert.AreEqual(40027, revolverStrategy.Duration(revolverLoan), TWO_DIGIT_PRECISION); 28 | Assert.AreEqual(4002700, revolverStrategy.Capital(revolverLoan), TWO_DIGIT_PRECISION); 29 | }); 30 | } 31 | 32 | private static DateTime November(int dayOfMonth, int year) 33 | { 34 | return new DateTime(year, 11, dayOfMonth); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/FormTemplateMethod/InitialCode/TermLoanStrategyTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using FormTemplateMethod.InitialCode; 4 | 5 | namespace RefactoringToPatterns.FormTemplateMethod.InitialCode 6 | { 7 | [TestFixture()] 8 | public class TermLoanStrategy 9 | { 10 | private readonly int HIGH_RISK_TAKING = 5; 11 | private readonly double LOAN_AMOUNT = 10000.00; 12 | private readonly double TWO_DIGIT_PRECISION = 0.001; 13 | 14 | [Test()] 15 | public void test_term_loan_same_payments() 16 | { 17 | DateTime start = November(20, 2003); 18 | DateTime maturity = November(20, 2006); 19 | 20 | Loan termLoan = Loan.NewTermLoan(LOAN_AMOUNT, start, maturity, HIGH_RISK_TAKING); 21 | termLoan.Payment(1000.00, November(20, 2004)); 22 | termLoan.Payment(1000.00, November(20, 2005)); 23 | termLoan.Payment(1000.00, November(20, 2006)); 24 | 25 | var termStrategy = new CapitalStrategyTermLoan(); 26 | 27 | Assert.Multiple(() => { 28 | Assert.AreEqual(20027, termStrategy.Duration(termLoan), TWO_DIGIT_PRECISION); 29 | Assert.AreEqual(6008100, termStrategy.Capital(termLoan), TWO_DIGIT_PRECISION); 30 | }); 31 | } 32 | 33 | private static DateTime November(int dayOfMonth, int year) 34 | { 35 | return new DateTime(year, 11, dayOfMonth); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/FormTemplateMethod/MyWork/AdvisedLineStrategyTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using FormTemplateMethod.MyWork; 4 | 5 | namespace RefactoringToPatterns.FormTemplateMethod.MyWork 6 | { 7 | [TestFixture()] 8 | public class AdvisedLineStrategyTests 9 | { 10 | private readonly int LOW_RISK_TAKING = 2; 11 | private readonly double LOAN_AMOUNT = 10000.00; 12 | private readonly double TWO_DIGIT_PRECISION = 0.001; 13 | 14 | [Test()] 15 | public void test_advised_line_loan_same_payments() 16 | { 17 | var advisedLineStrategy = new CapitalStrategyAdvisedLine(); 18 | DateTime start = November(20, 2003); 19 | DateTime maturity = November(20, 2006); 20 | DateTime expiry = November(20, 2007); 21 | 22 | Loan advisedLineLoan = Loan.NewAdvisedLine(LOAN_AMOUNT, start, expiry, LOW_RISK_TAKING); 23 | advisedLineLoan.Payment(1000.00, November(20, 2004)); 24 | advisedLineLoan.Payment(1000.00, November(20, 2005)); 25 | advisedLineLoan.Payment(1000.00, November(20, 2006)); 26 | 27 | Assert.AreEqual(40027, advisedLineStrategy.Duration(advisedLineLoan), TWO_DIGIT_PRECISION); 28 | Assert.AreEqual(1200810, advisedLineStrategy.Capital(advisedLineLoan), TWO_DIGIT_PRECISION); 29 | } 30 | 31 | private static DateTime November(int dayOfMonth, int year) 32 | { 33 | return new DateTime(year, 11, dayOfMonth); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/FormTemplateMethod/MyWork/PaymentTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using FormTemplateMethod.MyWork; 4 | 5 | namespace RefactoringToPatterns.FormTemplateMethod.MyWork 6 | { 7 | [TestFixture()] 8 | public class PaymentTests 9 | { 10 | private Payment _payment; 11 | private DateTime _christmasDay; 12 | 13 | [SetUp] 14 | public void Init() 15 | { 16 | _christmasDay = new DateTime(2010, 12, 25); 17 | _payment = new Payment(1000.0, _christmasDay); 18 | } 19 | 20 | [Test()] 21 | public void payment_is_constructed_correctly() 22 | { 23 | 24 | Assert.Multiple(() => { 25 | Assert.AreEqual(1000, _payment.Amount); 26 | Assert.AreEqual(_christmasDay, _payment.Date); 27 | }); 28 | 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/FormTemplateMethod/MyWork/RevolverStrategyTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using FormTemplateMethod.MyWork; 4 | 5 | namespace RefactoringToPatterns.FormTemplateMethod.MyWork 6 | { 7 | [TestFixture()] 8 | public class RevolverStrategyTests 9 | { 10 | private readonly int HIGH_RISK_TAKING = 5; 11 | private readonly double LOAN_AMOUNT = 10000.00; 12 | private readonly double TWO_DIGIT_PRECISION = 0.001; 13 | 14 | [Test()] 15 | public void test_revolver_loan_same_payments() 16 | { 17 | var revolverStrategy = new CapitalStrategyRevolver(); 18 | DateTime start = November(20, 2003); 19 | DateTime expiry = November(20, 2007); 20 | 21 | Loan revolverLoan = Loan.NewRevolver(LOAN_AMOUNT, start, expiry, HIGH_RISK_TAKING); 22 | revolverLoan.Payment(1000.00, November(20, 2004)); 23 | revolverLoan.Payment(1000.00, November(20, 2005)); 24 | revolverLoan.Payment(1000.00, November(20, 2006)); 25 | 26 | Assert.Multiple(() => { 27 | Assert.AreEqual(40027, revolverStrategy.Duration(revolverLoan), TWO_DIGIT_PRECISION); 28 | Assert.AreEqual(4002700, revolverStrategy.Capital(revolverLoan), TWO_DIGIT_PRECISION); 29 | }); 30 | } 31 | 32 | private static DateTime November(int dayOfMonth, int year) 33 | { 34 | return new DateTime(year, 11, dayOfMonth); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/FormTemplateMethod/MyWork/TermLoanStrategyTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using FormTemplateMethod.MyWork; 4 | 5 | namespace RefactoringToPatterns.FormTemplateMethod.MyWork 6 | { 7 | [TestFixture()] 8 | public class TermLoanStrategy 9 | { 10 | private readonly int HIGH_RISK_TAKING = 5; 11 | private readonly double LOAN_AMOUNT = 10000.00; 12 | private readonly double TWO_DIGIT_PRECISION = 0.001; 13 | 14 | [Test()] 15 | public void test_term_loan_same_payments() 16 | { 17 | DateTime start = November(20, 2003); 18 | DateTime maturity = November(20, 2006); 19 | 20 | Loan termLoan = Loan.NewTermLoan(LOAN_AMOUNT, start, maturity, HIGH_RISK_TAKING); 21 | termLoan.Payment(1000.00, November(20, 2004)); 22 | termLoan.Payment(1000.00, November(20, 2005)); 23 | termLoan.Payment(1000.00, November(20, 2006)); 24 | 25 | var termStrategy = new CapitalStrategyTermLoan(); 26 | 27 | Assert.Multiple(() => { 28 | Assert.AreEqual(20027, termStrategy.Duration(termLoan), TWO_DIGIT_PRECISION); 29 | Assert.AreEqual(6008100, termStrategy.Capital(termLoan), TWO_DIGIT_PRECISION); 30 | }); 31 | } 32 | 33 | private static DateTime November(int dayOfMonth, int year) 34 | { 35 | return new DateTime(year, 11, dayOfMonth); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/MoveAccumulationToCollectingParameter/InitialCode/AccumulationAcrossMethodsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using NUnit.Framework; 4 | 5 | /* 6 | * On page 315 Joshua makes the statement that Java's String would not allow you to accumulate results across methods. 7 | * I was pretty sure of what he meant, and was also pretty certain that was the case with C# as well... but I wanted to 8 | * check it so I wrote this small test class to explore that. 9 | * 10 | * I've left a failing test in here, Accumulate_With_String_Does_Not_Work_Across_Method_Calls. This shows that passing 11 | * a String into a method, and then seemingly mutating that string inside of that method... does not mutate the original 12 | * String passed in. 13 | * 14 | * This is not the case with the second test that uses a StringBuilder, 15 | * Accumulate_With_StringBuilder_Does_Work_Accross_Method_Calls. 16 | * 17 | * This shows the difference in how these types are passed. You may say... of course! I wanted to leave this behind 18 | * for anyone that hit that part of the book and maybe didn't have an understanding of what Joshua was talking about. 19 | */ 20 | 21 | namespace RefactoringToPatterns.MoveAccumulationToCollectingParameter.InitialCode 22 | { 23 | [TestFixture] 24 | public class AccumulationAcrossMethodsTests 25 | { 26 | 27 | [Test] 28 | public void Accumulate_With_String_Does_Not_Work_Across_Method_Calls() 29 | { 30 | string expectedFullName = "Cory Wheeler"; 31 | string notMyFullName = "Cory"; 32 | 33 | AccumulateWithString(notMyFullName); 34 | 35 | Assert.AreNotEqual(expectedFullName, notMyFullName); 36 | } 37 | 38 | [Test] 39 | public void Accumulate_With_StringBuilder_Does_Work_Accross_Method_Calls() 40 | { 41 | string expectedFullName = "Cory Wheeler"; 42 | StringBuilder myFullName = new StringBuilder("Cory"); 43 | 44 | AccumulateWithStringBuffer(myFullName); 45 | 46 | Assert.AreEqual(expectedFullName, myFullName.ToString()); 47 | } 48 | 49 | public void AccumulateWithString(string accumulator) 50 | { 51 | accumulator += " " + "Wheeler"; 52 | 53 | Console.WriteLine(accumulator); 54 | } 55 | 56 | public void AccumulateWithStringBuffer(StringBuilder accumulator) 57 | { 58 | accumulator.Append(" "); 59 | accumulator.Append("Wheeler"); 60 | 61 | Console.WriteLine(accumulator); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/MoveAccumulationToCollectingParameter/InitialCode/TagNodeTests.cs: -------------------------------------------------------------------------------- 1 | using MoveAccumulationToCollectingParameter.InitialCode; 2 | using NUnit.Framework; 3 | 4 | namespace RefactoringToPatterns.MoveAccumulationToCollectingParameter.InitialCode 5 | { 6 | [TestFixture] 7 | public class TagNodeTests 8 | { 9 | private TagNode _tagNode; 10 | 11 | [SetUp] 12 | public void Context() 13 | { 14 | _tagNode = new TagNode("parent", "gender='female'", "Jennifer"); 15 | } 16 | 17 | [Test] 18 | public void Should_Give_A_String_Representation() 19 | { 20 | var expected = "Jennifer"; 21 | 22 | Assert.AreEqual(expected, _tagNode.ToString()); 23 | } 24 | 25 | [Test] 26 | public void Adding_A_Child_Node_Should_Get_Included_In_Its_String_Representation() 27 | { 28 | var expected = "Jennifer" + 29 | "John" + 30 | ""; 31 | _tagNode.Add(new TagNode("child", "gender='male'", "John")); 32 | 33 | Assert.AreEqual(expected, _tagNode.ToString()); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/MoveAccumulationToCollectingParameter/MyWork/AccumulationAcrossMethodsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using NUnit.Framework; 4 | 5 | /* 6 | * On page 315 Joshua makes the statement that Java's String would not allow you to accumulate results across methods. 7 | * I was pretty sure of what he meant, and was also pretty certain that was the case with C# as well... but I wanted to 8 | * check it so I wrote this small test class to explore that. 9 | * 10 | * I've left a failing test in here, Accumulate_With_String_Does_Not_Work_Across_Method_Calls. This shows that passing 11 | * a String into a method, and then seemingly mutating that string inside of that method... does not mutate the original 12 | * String passed in. 13 | * 14 | * This is not the case with the second test that uses a StringBuilder, 15 | * Accumulate_With_StringBuilder_Does_Work_Accross_Method_Calls. 16 | * 17 | * This shows the difference in how these types are passed. You may say... of course! I wanted to leave this behind 18 | * for anyone that hit that part of the book and maybe didn't have an understanding of what Joshua was talking about. 19 | */ 20 | 21 | namespace RefactoringToPatterns.MoveAccumulationToCollectingParameter.MyWork 22 | { 23 | [TestFixture] 24 | public class AccumulationAcrossMethodsTests 25 | { 26 | 27 | [Test] 28 | public void Accumulate_With_String_Does_Not_Work_Across_Method_Calls() 29 | { 30 | string expectedFullName = "Cory Wheeler"; 31 | string notMyFullName = "Cory"; 32 | 33 | AccumulateWithString(notMyFullName); 34 | 35 | Assert.AreNotEqual(expectedFullName, notMyFullName); 36 | } 37 | 38 | [Test] 39 | public void Accumulate_With_StringBuilder_Does_Work_Accross_Method_Calls() 40 | { 41 | string expectedFullName = "Cory Wheeler"; 42 | StringBuilder myFullName = new StringBuilder("Cory"); 43 | 44 | AccumulateWithStringBuffer(myFullName); 45 | 46 | Assert.AreEqual(expectedFullName, myFullName.ToString()); 47 | } 48 | 49 | public void AccumulateWithString(string accumulator) 50 | { 51 | accumulator += " " + "Wheeler"; 52 | 53 | Console.WriteLine(accumulator); 54 | } 55 | 56 | public void AccumulateWithStringBuffer(StringBuilder accumulator) 57 | { 58 | accumulator.Append(" "); 59 | accumulator.Append("Wheeler"); 60 | 61 | Console.WriteLine(accumulator); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/MoveAccumulationToCollectingParameter/MyWork/TagNodeTests.cs: -------------------------------------------------------------------------------- 1 | using MoveAccumulationToCollectingParameter.MyWork; 2 | using NUnit.Framework; 3 | 4 | namespace RefactoringToPatterns.MoveAccumulationToCollectingParameter.MyWork 5 | { 6 | [TestFixture] 7 | public class TagNodeTests 8 | { 9 | private TagNode _tagNode; 10 | 11 | [SetUp] 12 | public void Context() 13 | { 14 | _tagNode = new TagNode("parent", "gender='female'", "Jennifer"); 15 | } 16 | 17 | [Test] 18 | public void Should_Give_A_String_Representation() 19 | { 20 | var expected = "Jennifer"; 21 | 22 | Assert.AreEqual(expected, _tagNode.ToString()); 23 | } 24 | 25 | [Test] 26 | public void Adding_A_Child_Node_Should_Get_Included_In_Its_String_Representation() 27 | { 28 | var expected = "Jennifer" + 29 | "John" + 30 | ""; 31 | _tagNode.Add(new TagNode("child", "gender='male'", "John")); 32 | 33 | Assert.AreEqual(expected, _tagNode.ToString()); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/PolymorphicCreationWithFactoryMethod/InitialCode/DomBuilderTestTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using PolymorphicCreationWithFactoryMethod.InitialCode; 3 | 4 | namespace RefactoringToPatterns.PolymorphicCreationWithFactoryMethod.InitialCode 5 | { 6 | [TestFixture] 7 | public class DOMBuilderTestTests 8 | { 9 | DOMBuilderTest _domBuilderTest; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _domBuilderTest = new DOMBuilderTest(); 15 | _domBuilderTest.TestAddAboveRoot(); 16 | } 17 | 18 | [Test] 19 | public void test_DOMBuilderTest_has_a_DOMBuilder() 20 | { 21 | Assert.IsInstanceOf(typeof(DOMBuilder), _domBuilderTest.Builder); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/PolymorphicCreationWithFactoryMethod/InitialCode/XMLBuilderTestTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using PolymorphicCreationWithFactoryMethod.InitialCode; 3 | 4 | namespace RefactoringToPatterns.PolymorphicCreationWithFactoryMethod.InitialCode 5 | { 6 | [TestFixture()] 7 | public class XMLBuilderTestTests 8 | { 9 | XMLBuilderTest _xmlBuilderTest; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _xmlBuilderTest = new XMLBuilderTest(); 15 | _xmlBuilderTest.TestAddAboveRoot(); 16 | } 17 | 18 | [Test] 19 | public void test_XMLBuilderTest_has_an_XMLBuilder() 20 | { 21 | Assert.IsInstanceOf(typeof(XMLBuilder), _xmlBuilderTest.Builder); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/PolymorphicCreationWithFactoryMethod/MyWork/DomBuilderTestTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using PolymorphicCreationWithFactoryMethod.MyWork; 3 | 4 | namespace RefactoringToPatterns.PolymorphicCreationWithFactoryMethod.MyWork 5 | { 6 | [TestFixture] 7 | public class DOMBuilderTestTests 8 | { 9 | DOMBuilderTest _domBuilderTest; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _domBuilderTest = new DOMBuilderTest(); 15 | _domBuilderTest.TestAddAboveRoot(); 16 | } 17 | 18 | [Test] 19 | public void test_DOMBuilderTest_has_a_DOMBuilder() 20 | { 21 | Assert.IsInstanceOf(typeof(DOMBuilder), _domBuilderTest.Builder); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/PolymorphicCreationWithFactoryMethod/MyWork/XMLBuilderTestTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using PolymorphicCreationWithFactoryMethod.MyWork; 3 | 4 | namespace RefactoringToPatterns.PolymorphicCreationWithFactoryMethod.MyWork 5 | { 6 | [TestFixture()] 7 | public class XMLBuilderTestTests 8 | { 9 | XMLBuilderTest _xmlBuilderTest; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | _xmlBuilderTest = new XMLBuilderTest(); 15 | _xmlBuilderTest.TestAddAboveRoot(); 16 | } 17 | 18 | [Test] 19 | public void test_XMLBuilderTest_has_an_XMLBuilder() 20 | { 21 | Assert.IsInstanceOf(typeof(XMLBuilder), _xmlBuilderTest.Builder); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/RefactoringToPatterns.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6E49F4DC-8D6A-4DED-970C-D9C4DDD43A40} 8 | Library 9 | RefactoringToPatterns.Tests 10 | RefactoringToPatterns.Tests 11 | v4.8 12 | 9 13 | 14 | 15 | true 16 | full 17 | false 18 | bin\Debug 19 | DEBUG; 20 | prompt 21 | 4 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | 29 | 30 | 31 | ..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll 32 | True 33 | 34 | 35 | 36 | 37 | 38 | 39 | ..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll 40 | True 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 | {ea0baf76-f1e5-45f5-b4c7-8b2c8e005249} 89 | ExtractComposite 90 | 91 | 92 | {e55105e2-9a9c-4c43-9e98-ef308663f77d} 93 | MoveAccumulationToCollectingParameter 94 | 95 | 96 | {62ECDEAE-B8A4-4CD1-ACF5-E11965928B4B} 97 | ReplaceConstructorsWithCreationMethods 98 | 99 | 100 | {1CB60E44-2BCF-426A-9A1C-64598F2BF93E} 101 | ChainConstructors 102 | 103 | 104 | {F2D41130-D1A6-4F83-8408-F02D6AAF279C} 105 | EncapsulateClassesWithFactory 106 | 107 | 108 | {632ABCBD-B56E-427B-B00B-ECFCEFFEF0D5} 109 | PolymorphicCreationWithFactoryMethod 110 | 111 | 112 | {ABA760CB-DC75-4C05-9CD7-DE2D19B5E64F} 113 | ReplaceConditionalLogicWithStrategy 114 | 115 | 116 | {F1231A49-7229-47D8-B19F-197683E3A829} 117 | FormTemplateMethod 118 | 119 | 120 | {DB582B2C-1FED-426E-8DBC-9618ECA07843} 121 | ComposeMethod 122 | 123 | 124 | {DA8504D9-4160-43FB-AEE5-E6DDC9368A91} 125 | ReplaceImplicitTreeWithComposite 126 | 127 | 128 | {9CA5D6B8-43D4-4325-9E7D-BF7E1E2D4C51} 129 | EncapsulateCompositeWithBuilder 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 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ReplaceConditionalLogicWithStrategy/InitialCode/LoanTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using ReplaceConditionalLogicWithStrategy.InitialCode; 4 | 5 | namespace RefactoringToPatterns.ReplaceConditionalLogicWithStrategy.InitialCode 6 | { 7 | [TestFixture()] 8 | public class LoanTests 9 | { 10 | private readonly int LOW_RISK_TAKING = 2; 11 | private readonly int HIGH_RISK_TAKING = 5; 12 | private readonly double LOAN_AMOUNT = 10000.00; 13 | private readonly double TWO_DIGIT_PRECISION = 0.001; 14 | 15 | [SetUp] 16 | public void Init() { 17 | 18 | } 19 | 20 | [Test()] 21 | public void test_term_loan_same_payments() 22 | { 23 | DateTime start = November(20, 2003); 24 | DateTime maturity = November(20, 2006); 25 | 26 | Loan termLoan = Loan.NewTermLoan(LOAN_AMOUNT, start, maturity, HIGH_RISK_TAKING); 27 | termLoan.Payment(1000.00, November(20, 2004)); 28 | termLoan.Payment(1000.00, November(20, 2005)); 29 | termLoan.Payment(1000.00, November(20, 2006)); 30 | 31 | Assert.Multiple(() => { 32 | Assert.AreEqual(20027, termLoan.Duration(), TWO_DIGIT_PRECISION); 33 | Assert.AreEqual(6008100, termLoan.Capital(), TWO_DIGIT_PRECISION); 34 | }); 35 | } 36 | 37 | [Test()] 38 | public void test_revolver_loan_same_payments() 39 | { 40 | DateTime start = November(20, 2003); 41 | DateTime expiry = November(20, 2007); 42 | 43 | Loan revolverLoan = Loan.NewRevolver(LOAN_AMOUNT, start, expiry, HIGH_RISK_TAKING); 44 | revolverLoan.Payment(1000.00, November(20, 2004)); 45 | revolverLoan.Payment(1000.00, November(20, 2005)); 46 | revolverLoan.Payment(1000.00, November(20, 2006)); 47 | 48 | Assert.Multiple(() => { 49 | Assert.AreEqual(40027, revolverLoan.Duration(), TWO_DIGIT_PRECISION); 50 | Assert.AreEqual(4002700, revolverLoan.Capital(), TWO_DIGIT_PRECISION); 51 | }); 52 | } 53 | 54 | [Test()] 55 | public void test_advised_line_loan_same_payments() 56 | { 57 | DateTime start = November(20, 2003); 58 | DateTime maturity = November(20, 2006); 59 | DateTime expiry = November(20, 2007); 60 | 61 | Loan advisedLineLoan = Loan.NewAdvisedLine(LOAN_AMOUNT, start, expiry, LOW_RISK_TAKING); 62 | advisedLineLoan.Payment(1000.00, November(20, 2004)); 63 | advisedLineLoan.Payment(1000.00, November(20, 2005)); 64 | advisedLineLoan.Payment(1000.00, November(20, 2006)); 65 | 66 | Assert.Multiple(() => { 67 | Assert.AreEqual(40027, advisedLineLoan.Duration(), TWO_DIGIT_PRECISION); 68 | Assert.AreEqual(1200810, advisedLineLoan.Capital(), TWO_DIGIT_PRECISION); 69 | }); 70 | } 71 | 72 | private static DateTime November(int dayOfMonth, int year) 73 | { 74 | return new DateTime(year, 11, dayOfMonth); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ReplaceConditionalLogicWithStrategy/InitialCode/PaymentTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using ReplaceConditionalLogicWithStrategy.InitialCode; 4 | 5 | namespace RefactoringToPatterns.ReplaceConditionalLogicWithStrategy.InitialCode 6 | { 7 | [TestFixture()] 8 | public class PaymentTests 9 | { 10 | private Payment _payment; 11 | private DateTime _christmasDay; 12 | 13 | [SetUp] 14 | public void Init() 15 | { 16 | _christmasDay = new DateTime(2010, 12, 25); 17 | _payment = new Payment(1000.0, _christmasDay); 18 | } 19 | 20 | [Test()] 21 | public void payment_is_constructed_correctly() 22 | { 23 | 24 | Assert.Multiple(() => { 25 | Assert.AreEqual(1000, _payment.Amount); 26 | Assert.AreEqual(_christmasDay, _payment.Date); 27 | }); 28 | 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ReplaceConditionalLogicWithStrategy/MyWork/LoanTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using ReplaceConditionalLogicWithStrategy.MyWork; 4 | 5 | namespace RefactoringToPatterns.ReplaceConditionalLogicWithStrategy.MyWork 6 | { 7 | [TestFixture()] 8 | public class LoanTests 9 | { 10 | private readonly int LOW_RISK_TAKING = 2; 11 | private readonly int HIGH_RISK_TAKING = 5; 12 | private readonly double LOAN_AMOUNT = 10000.00; 13 | private readonly double TWO_DIGIT_PRECISION = 0.001; 14 | 15 | [SetUp] 16 | public void Init() { 17 | 18 | } 19 | 20 | [Test()] 21 | public void test_term_loan_same_payments() 22 | { 23 | DateTime start = November(20, 2003); 24 | DateTime maturity = November(20, 2006); 25 | 26 | Loan termLoan = Loan.NewTermLoan(LOAN_AMOUNT, start, maturity, HIGH_RISK_TAKING); 27 | termLoan.Payment(1000.00, November(20, 2004)); 28 | termLoan.Payment(1000.00, November(20, 2005)); 29 | termLoan.Payment(1000.00, November(20, 2006)); 30 | 31 | Assert.Multiple(() => { 32 | Assert.AreEqual(20027, termLoan.Duration(), TWO_DIGIT_PRECISION); 33 | Assert.AreEqual(6008100, termLoan.Capital(), TWO_DIGIT_PRECISION); 34 | }); 35 | } 36 | 37 | [Test()] 38 | public void test_revolver_loan_same_payments() 39 | { 40 | DateTime start = November(20, 2003); 41 | DateTime expiry = November(20, 2007); 42 | 43 | Loan revolverLoan = Loan.NewRevolver(LOAN_AMOUNT, start, expiry, HIGH_RISK_TAKING); 44 | revolverLoan.Payment(1000.00, November(20, 2004)); 45 | revolverLoan.Payment(1000.00, November(20, 2005)); 46 | revolverLoan.Payment(1000.00, November(20, 2006)); 47 | 48 | Assert.Multiple(() => { 49 | Assert.AreEqual(40027, revolverLoan.Duration(), TWO_DIGIT_PRECISION); 50 | Assert.AreEqual(4002700, revolverLoan.Capital(), TWO_DIGIT_PRECISION); 51 | }); 52 | } 53 | 54 | [Test()] 55 | public void test_advised_line_loan_same_payments() 56 | { 57 | DateTime start = November(20, 2003); 58 | DateTime maturity = November(20, 2006); 59 | DateTime expiry = November(20, 2007); 60 | 61 | Loan advisedLineLoan = Loan.NewAdvisedLine(LOAN_AMOUNT, start, expiry, LOW_RISK_TAKING); 62 | advisedLineLoan.Payment(1000.00, November(20, 2004)); 63 | advisedLineLoan.Payment(1000.00, November(20, 2005)); 64 | advisedLineLoan.Payment(1000.00, November(20, 2006)); 65 | 66 | Assert.Multiple(() => { 67 | Assert.AreEqual(40027, advisedLineLoan.Duration(), TWO_DIGIT_PRECISION); 68 | Assert.AreEqual(1200810, advisedLineLoan.Capital(), TWO_DIGIT_PRECISION); 69 | }); 70 | } 71 | 72 | private static DateTime November(int dayOfMonth, int year) 73 | { 74 | return new DateTime(year, 11, dayOfMonth); 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ReplaceConditionalLogicWithStrategy/MyWork/PaymentTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using ReplaceConditionalLogicWithStrategy.MyWork; 4 | 5 | namespace RefactoringToPatterns.ReplaceConditionalLogicWithStrategy.MyWork 6 | { 7 | [TestFixture()] 8 | public class PaymentTests 9 | { 10 | private Payment _payment; 11 | private DateTime _christmasDay; 12 | 13 | [SetUp] 14 | public void Init() 15 | { 16 | _christmasDay = new DateTime(2010, 12, 25); 17 | _payment = new Payment(1000.0, _christmasDay); 18 | } 19 | 20 | [Test()] 21 | public void payment_is_constructed_correctly() 22 | { 23 | 24 | Assert.Multiple(() => { 25 | Assert.AreEqual(1000, _payment.Amount); 26 | Assert.AreEqual(_christmasDay, _payment.Date); 27 | }); 28 | 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ReplaceConstructorsWithCreationMethods/InitialCode/CapitalCalculationTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using ReplaceConstructorsWithCreationMethods.InitialCode; 4 | 5 | namespace RefactoringToPatterns.ReplaceConstructorsWithCreationMethods.InitialCode 6 | { 7 | [TestFixture] 8 | public class CapitalCalculationTests 9 | { 10 | private readonly DateTime? _maturity = new DateTime(2020, 10, 2); 11 | private readonly DateTime? _expiry = new DateTime(2021, 10, 2); 12 | 13 | private const double Commitment = 3.0; 14 | private const double Outstanding = 12.9; 15 | private RiskAdjustedCapitalStrategy _riskAdjustedCapitalStrategy = 16 | new RiskAdjustedCapitalStrategy(); 17 | const int RiskRating = 5; 18 | 19 | [SetUp] 20 | public void Init() 21 | { 22 | } 23 | 24 | [Test] 25 | public void test_term_loan_no_payments() 26 | { 27 | Loan loan = new Loan(Commitment, RiskRating, _maturity); 28 | Assert.IsInstanceOf(typeof(CapitalStrategyTermLoan), loan.CapitalStrategy); 29 | } 30 | 31 | [Test] 32 | public void test_term_loan_one_payment() 33 | { 34 | Loan loan = new Loan(Commitment, RiskRating, _maturity); 35 | Assert.IsInstanceOf(typeof(CapitalStrategyTermLoan), loan.CapitalStrategy); 36 | } 37 | 38 | [Test] 39 | public void test_revolver_loan_no_payments() 40 | { 41 | Loan loan = new Loan(Commitment, RiskRating, null, _expiry); 42 | Assert.IsInstanceOf(typeof(CapitalStrategyRevolver), loan.CapitalStrategy); 43 | } 44 | 45 | [Test] 46 | public void test_RCTL_loan_one_payment() 47 | { 48 | Loan loan = new Loan(Commitment, Outstanding, RiskRating, _maturity, _expiry); 49 | Assert.IsInstanceOf(typeof(CapitalStrategyRCTL), loan.CapitalStrategy); 50 | } 51 | 52 | [Test] 53 | public void test_term_loan_with_risk_adjusted_capital_strategy() { 54 | Loan loan = new Loan(_riskAdjustedCapitalStrategy, 55 | Commitment, Outstanding, RiskRating, 56 | _maturity, null); 57 | 58 | Assert.IsInstanceOf(typeof(RiskAdjustedCapitalStrategy), loan.CapitalStrategy); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ReplaceConstructorsWithCreationMethods/MyWork/CapitalCalculationTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using System; 3 | using ReplaceConstructorsWithCreationMethods.MyWork; 4 | 5 | namespace RefactoringToPatterns.ReplaceConstructorsWithCreationMethods.MyWork 6 | { 7 | [TestFixture] 8 | public class CapitalCalculationTests 9 | { 10 | private readonly DateTime? _maturity = new DateTime(2020, 10, 2); 11 | private readonly DateTime? _expiry = new DateTime(2021, 10, 2); 12 | 13 | private const double Commitment = 3.0; 14 | private const double Outstanding = 12.9; 15 | private RiskAdjustedCapitalStrategy _riskAdjustedCapitalStrategy = 16 | new RiskAdjustedCapitalStrategy(); 17 | const int RiskRating = 5; 18 | 19 | [SetUp] 20 | public void Init() 21 | { 22 | } 23 | 24 | [Test] 25 | public void test_term_loan_no_payments() 26 | { 27 | Loan loan = new Loan(Commitment, RiskRating, _maturity); 28 | Assert.IsInstanceOf(typeof(CapitalStrategyTermLoan), loan.CapitalStrategy); 29 | } 30 | 31 | [Test] 32 | public void test_term_loan_one_payment() 33 | { 34 | Loan loan = new Loan(Commitment, RiskRating, _maturity); 35 | Assert.IsInstanceOf(typeof(CapitalStrategyTermLoan), loan.CapitalStrategy); 36 | } 37 | 38 | [Test] 39 | public void test_revolver_loan_no_payments() 40 | { 41 | Loan loan = new Loan(Commitment, RiskRating, null, _expiry); 42 | Assert.IsInstanceOf(typeof(CapitalStrategyRevolver), loan.CapitalStrategy); 43 | } 44 | 45 | [Test] 46 | public void test_RCTL_loan_one_payment() 47 | { 48 | Loan loan = new Loan(Commitment, Outstanding, RiskRating, _maturity, _expiry); 49 | Assert.IsInstanceOf(typeof(CapitalStrategyRCTL), loan.CapitalStrategy); 50 | } 51 | 52 | [Test] 53 | public void test_term_loan_with_risk_adjusted_capital_strategy() { 54 | Loan loan = new Loan(_riskAdjustedCapitalStrategy, 55 | Commitment, Outstanding, RiskRating, 56 | _maturity, null); 57 | 58 | Assert.IsInstanceOf(typeof(RiskAdjustedCapitalStrategy), loan.CapitalStrategy); 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ReplaceImplicitTreeWithComposite/InitialCode/OrdersWriterWithOrdersTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using ReplaceImplicitTreeWithComposite.InitialCode; 3 | 4 | namespace RefactoringToPatterns.ReplaceImplicitTreeWithComposite.InitialCode 5 | { 6 | [TestFixture()] 7 | public class OrdersWriterWithOrdersTests 8 | { 9 | private OrdersWriter ordersWriter; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | var orders = new Orders(); 15 | var order = new Order(1234); 16 | order.Add(new Product(4321, "T-Shirt", ProductSize.Medium, "21.00")); 17 | order.Add(new Product(6789, "Socks", ProductSize.Medium, "8.00")); 18 | orders.Add(order); 19 | 20 | this.ordersWriter = new OrdersWriter(orders); 21 | } 22 | 23 | [Test] 24 | public void GetContents_produces_all_orders() 25 | { 26 | var expectedOrder = 27 | "" + 28 | "" + 29 | "" + 30 | "" + 31 | "21.00" + 32 | "" + 33 | "T-Shirt" + 34 | "" + 35 | "" + 36 | "" + 37 | "8.00" + 38 | "" + 39 | "Socks" + 40 | "" + 41 | "" + 42 | ""; 43 | Assert.AreEqual(expectedOrder, this.ordersWriter.GetContents()); 44 | } 45 | } 46 | 47 | [TestFixture] 48 | public class OrdersWriterWithNoOrdersTests 49 | { 50 | private OrdersWriter ordersWriter; 51 | 52 | [SetUp] 53 | public void Init() 54 | { 55 | var orders = new Orders(); 56 | this.ordersWriter = new OrdersWriter(orders); 57 | } 58 | 59 | [Test] 60 | public void GetContents_produces_no_orders() 61 | { 62 | var expectedOrder = 63 | "" + 64 | ""; 65 | 66 | Assert.AreEqual(expectedOrder, this.ordersWriter.GetContents()); 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/ReplaceImplicitTreeWithComposite/MyWork/OrdersWriterWithOrdersTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using ReplaceImplicitTreeWithComposite.MyWork; 3 | 4 | namespace RefactoringToPatterns.ReplaceImplicitTreeWithComposite.MyWork 5 | { 6 | [TestFixture()] 7 | public class OrdersWriterWithOrdersTests 8 | { 9 | private OrdersWriter ordersWriter; 10 | 11 | [SetUp] 12 | public void Init() 13 | { 14 | var orders = new Orders(); 15 | var order = new Order(1234); 16 | order.Add(new Product(4321, "T-Shirt", ProductSize.Medium, "21.00")); 17 | order.Add(new Product(6789, "Socks", ProductSize.Medium, "8.00")); 18 | orders.Add(order); 19 | 20 | this.ordersWriter = new OrdersWriter(orders); 21 | } 22 | 23 | [Test] 24 | public void GetContents_produces_all_orders() 25 | { 26 | var expectedOrder = 27 | "" + 28 | "" + 29 | "" + 30 | "" + 31 | "21.00" + 32 | "" + 33 | "T-Shirt" + 34 | "" + 35 | "" + 36 | "" + 37 | "8.00" + 38 | "" + 39 | "Socks" + 40 | "" + 41 | "" + 42 | ""; 43 | Assert.AreEqual(expectedOrder, this.ordersWriter.GetContents()); 44 | } 45 | } 46 | 47 | [TestFixture] 48 | public class OrdersWriterWithNoOrdersTests 49 | { 50 | private OrdersWriter ordersWriter; 51 | 52 | [SetUp] 53 | public void Init() 54 | { 55 | var orders = new Orders(); 56 | this.ordersWriter = new OrdersWriter(orders); 57 | } 58 | 59 | [Test] 60 | public void GetContents_produces_no_orders() 61 | { 62 | var expectedOrder = 63 | "" + 64 | ""; 65 | 66 | Assert.AreEqual(expectedOrder, this.ordersWriter.GetContents()); 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /RefactoringToPatterns.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /RefactoringToPatterns.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RefactoringToPatterns.Tests", "RefactoringToPatterns.Tests\RefactoringToPatterns.Tests.csproj", "{6E49F4DC-8D6A-4DED-970C-D9C4DDD43A40}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReplaceConstructorsWithCreationMethods", "ReplaceConstructorsWithCreationMethods\ReplaceConstructorsWithCreationMethods.csproj", "{62ECDEAE-B8A4-4CD1-ACF5-E11965928B4B}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChainConstructors", "ChainConstructors\ChainConstructors.csproj", "{1CB60E44-2BCF-426A-9A1C-64598F2BF93E}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncapsulateClassesWithFactory", "EncapsulateClassesWithFactory\EncapsulateClassesWithFactory.csproj", "{F2D41130-D1A6-4F83-8408-F02D6AAF279C}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolymorphicCreationWithFactoryMethod", "PolymorphicCreationWithFactoryMethod\PolymorphicCreationWithFactoryMethod.csproj", "{632ABCBD-B56E-427B-B00B-ECFCEFFEF0D5}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReplaceConditionalLogicWithStrategy", "ReplaceConditionalLogicWithStrategy\ReplaceConditionalLogicWithStrategy.csproj", "{ABA760CB-DC75-4C05-9CD7-DE2D19B5E64F}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FormTemplateMethod", "FormTemplateMethod\FormTemplateMethod.csproj", "{F1231A49-7229-47D8-B19F-197683E3A829}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComposeMethod", "ComposeMethod\ComposeMethod.csproj", "{DB582B2C-1FED-426E-8DBC-9618ECA07843}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReplaceImplicitTreeWithComposite", "ReplaceImplicitTreeWithComposite\ReplaceImplicitTreeWithComposite.csproj", "{DA8504D9-4160-43FB-AEE5-E6DDC9368A91}" 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncapsulateCompositeWithBuilder", "EncapsulateCompositeWithBuilder\EncapsulateCompositeWithBuilder.csproj", "{9CA5D6B8-43D4-4325-9E7D-BF7E1E2D4C51}" 23 | EndProject 24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoveAccumulationToCollectingParameter", "MoveAccumulationToCollectingParameter\MoveAccumulationToCollectingParameter.csproj", "{E55105E2-9A9C-4C43-9E98-EF308663F77D}" 25 | EndProject 26 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtractComposite", "ExtractComposite\ExtractComposite.csproj", "{EA0BAF76-F1E5-45F5-B4C7-8B2C8E005249}" 27 | EndProject 28 | Global 29 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 30 | Debug|Any CPU = Debug|Any CPU 31 | Release|Any CPU = Release|Any CPU 32 | EndGlobalSection 33 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 34 | {6E49F4DC-8D6A-4DED-970C-D9C4DDD43A40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {6E49F4DC-8D6A-4DED-970C-D9C4DDD43A40}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {6E49F4DC-8D6A-4DED-970C-D9C4DDD43A40}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {6E49F4DC-8D6A-4DED-970C-D9C4DDD43A40}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {62ECDEAE-B8A4-4CD1-ACF5-E11965928B4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {62ECDEAE-B8A4-4CD1-ACF5-E11965928B4B}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {62ECDEAE-B8A4-4CD1-ACF5-E11965928B4B}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {62ECDEAE-B8A4-4CD1-ACF5-E11965928B4B}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {1CB60E44-2BCF-426A-9A1C-64598F2BF93E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {1CB60E44-2BCF-426A-9A1C-64598F2BF93E}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {1CB60E44-2BCF-426A-9A1C-64598F2BF93E}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {1CB60E44-2BCF-426A-9A1C-64598F2BF93E}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {F2D41130-D1A6-4F83-8408-F02D6AAF279C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {F2D41130-D1A6-4F83-8408-F02D6AAF279C}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {F2D41130-D1A6-4F83-8408-F02D6AAF279C}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {F2D41130-D1A6-4F83-8408-F02D6AAF279C}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {632ABCBD-B56E-427B-B00B-ECFCEFFEF0D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {632ABCBD-B56E-427B-B00B-ECFCEFFEF0D5}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {632ABCBD-B56E-427B-B00B-ECFCEFFEF0D5}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {632ABCBD-B56E-427B-B00B-ECFCEFFEF0D5}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {ABA760CB-DC75-4C05-9CD7-DE2D19B5E64F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {ABA760CB-DC75-4C05-9CD7-DE2D19B5E64F}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {ABA760CB-DC75-4C05-9CD7-DE2D19B5E64F}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {ABA760CB-DC75-4C05-9CD7-DE2D19B5E64F}.Release|Any CPU.Build.0 = Release|Any CPU 58 | {F1231A49-7229-47D8-B19F-197683E3A829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {F1231A49-7229-47D8-B19F-197683E3A829}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {F1231A49-7229-47D8-B19F-197683E3A829}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {F1231A49-7229-47D8-B19F-197683E3A829}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {DB582B2C-1FED-426E-8DBC-9618ECA07843}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 63 | {DB582B2C-1FED-426E-8DBC-9618ECA07843}.Debug|Any CPU.Build.0 = Debug|Any CPU 64 | {DB582B2C-1FED-426E-8DBC-9618ECA07843}.Release|Any CPU.ActiveCfg = Release|Any CPU 65 | {DB582B2C-1FED-426E-8DBC-9618ECA07843}.Release|Any CPU.Build.0 = Release|Any CPU 66 | {DA8504D9-4160-43FB-AEE5-E6DDC9368A91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 67 | {DA8504D9-4160-43FB-AEE5-E6DDC9368A91}.Debug|Any CPU.Build.0 = Debug|Any CPU 68 | {DA8504D9-4160-43FB-AEE5-E6DDC9368A91}.Release|Any CPU.ActiveCfg = Release|Any CPU 69 | {DA8504D9-4160-43FB-AEE5-E6DDC9368A91}.Release|Any CPU.Build.0 = Release|Any CPU 70 | {9CA5D6B8-43D4-4325-9E7D-BF7E1E2D4C51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 71 | {9CA5D6B8-43D4-4325-9E7D-BF7E1E2D4C51}.Debug|Any CPU.Build.0 = Debug|Any CPU 72 | {9CA5D6B8-43D4-4325-9E7D-BF7E1E2D4C51}.Release|Any CPU.ActiveCfg = Release|Any CPU 73 | {9CA5D6B8-43D4-4325-9E7D-BF7E1E2D4C51}.Release|Any CPU.Build.0 = Release|Any CPU 74 | {E55105E2-9A9C-4C43-9E98-EF308663F77D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 75 | {E55105E2-9A9C-4C43-9E98-EF308663F77D}.Debug|Any CPU.Build.0 = Debug|Any CPU 76 | {E55105E2-9A9C-4C43-9E98-EF308663F77D}.Release|Any CPU.ActiveCfg = Release|Any CPU 77 | {E55105E2-9A9C-4C43-9E98-EF308663F77D}.Release|Any CPU.Build.0 = Release|Any CPU 78 | {EA0BAF76-F1E5-45F5-B4C7-8B2C8E005249}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 79 | {EA0BAF76-F1E5-45F5-B4C7-8B2C8E005249}.Debug|Any CPU.Build.0 = Debug|Any CPU 80 | {EA0BAF76-F1E5-45F5-B4C7-8B2C8E005249}.Release|Any CPU.ActiveCfg = Release|Any CPU 81 | {EA0BAF76-F1E5-45F5-B4C7-8B2C8E005249}.Release|Any CPU.Build.0 = Release|Any CPU 82 | EndGlobalSection 83 | EndGlobal 84 | -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/InitialCode/Loan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace ReplaceConditionalLogicWithStrategy.InitialCode 5 | { 6 | public class Loan 7 | { 8 | double _commitment = 1.0; 9 | private DateTime? _expiry; 10 | private DateTime? _maturity; 11 | private double _outstanding; 12 | IList _payments = new List(); 13 | private DateTime? _today = DateTime.Now; 14 | private DateTime _start; 15 | private long MILLIS_PER_DAY = 86400000; 16 | private long DAYS_PER_YEAR = 365; 17 | private double _riskRating; 18 | private double _unusedPercentage; 19 | 20 | public Loan(double commitment, double notSureWhatThisIs, DateTime start, DateTime? expiry, DateTime? maturity, int riskRating) 21 | { 22 | this._expiry = expiry; 23 | this._commitment = commitment; 24 | this._today = null; 25 | this._start = start; 26 | this._maturity = maturity; 27 | this._riskRating = riskRating; 28 | this._unusedPercentage = 1.0; 29 | } 30 | 31 | public static Loan NewTermLoan(double commitment, DateTime start, DateTime maturity, int riskRating) 32 | { 33 | return new Loan(commitment, commitment, start, null, 34 | maturity, riskRating); 35 | } 36 | 37 | public static Loan NewRevolver(double commitment, DateTime start, DateTime expiry, int riskRating) 38 | { 39 | return new Loan(commitment, 0, start, expiry, 40 | null, riskRating); 41 | } 42 | 43 | public static Loan NewAdvisedLine(double commitment, DateTime start, DateTime expiry, int riskRating) 44 | { 45 | if (riskRating > 3) return null; 46 | Loan advisedLine = new Loan(commitment, 0, start, expiry, 47 | null, riskRating); 48 | advisedLine.SetUnusedPercentage(0.1); 49 | return advisedLine; 50 | } 51 | 52 | public void Payment(double amount, DateTime paymentDate) 53 | { 54 | _payments.Add(new Payment(amount, paymentDate)); 55 | } 56 | 57 | public double Capital() { 58 | if(_expiry == null && _maturity != null) 59 | return _commitment * Duration() * RiskFactor(); 60 | if(_expiry != null && _maturity == null) { 61 | if(GetUnusedPercentage() != 1.0) { 62 | return _commitment * GetUnusedPercentage() * Duration() * RiskFactor(); 63 | } 64 | else { 65 | return (OutstandingRiskAmount() * Duration() * RiskFactor()) 66 | + (UnusedRiskAmount() * Duration() * UnusedRiskFactor()); 67 | } 68 | } 69 | return 0.0; 70 | } 71 | 72 | public double Duration() 73 | { 74 | if (_expiry == null && _maturity != null) 75 | { 76 | return WeightedAverageDuration(); 77 | } 78 | else if (_expiry != null && _maturity == null) 79 | { 80 | return YearsTo(_expiry); 81 | } 82 | return 0.0; 83 | } 84 | 85 | private double WeightedAverageDuration() 86 | { 87 | double duration = 0.0; 88 | double weightedAverage = 0.0; 89 | double sumOfPayments = 0.0; 90 | 91 | foreach (var payment in _payments) 92 | { 93 | sumOfPayments += payment.Amount; 94 | weightedAverage += YearsTo(payment.Date) * payment.Amount; 95 | } 96 | 97 | if (_commitment != 0.0) 98 | { 99 | duration = weightedAverage / sumOfPayments; 100 | } 101 | 102 | return duration; 103 | } 104 | 105 | private double YearsTo(DateTime? endDate) 106 | { 107 | DateTime? beginDate = (_today == null ? _start : _today); 108 | return (double)((endDate?.Ticks - beginDate?.Ticks) / MILLIS_PER_DAY / DAYS_PER_YEAR); 109 | } 110 | 111 | private double RiskFactor() 112 | { 113 | return InitialCode.RiskFactor.GetFactors().ForRating(_riskRating); 114 | } 115 | 116 | private double GetUnusedPercentage() 117 | { 118 | return _unusedPercentage; 119 | } 120 | 121 | public void SetUnusedPercentage(double unusedPercentage) 122 | { 123 | _unusedPercentage = unusedPercentage; 124 | } 125 | 126 | private double UnusedRiskAmount() 127 | { 128 | return (_commitment - _outstanding); 129 | } 130 | 131 | private double UnusedRiskFactor() 132 | { 133 | return UnusedRiskFactors.GetFactors().ForRating(_riskRating); 134 | } 135 | 136 | private double OutstandingRiskAmount() 137 | { 138 | return _outstanding; 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/InitialCode/Payment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ReplaceConditionalLogicWithStrategy.InitialCode 4 | { 5 | public class Payment 6 | { 7 | private double _amount; 8 | private DateTime _date; 9 | 10 | public Payment() 11 | { 12 | _amount = 0.0; 13 | _date = new DateTime(); 14 | } 15 | 16 | public Payment(double amount, DateTime date) 17 | { 18 | Amount = amount; 19 | Date = date; 20 | } 21 | 22 | public double Amount 23 | { 24 | get { return _amount; } 25 | 26 | private set { _amount = value; } 27 | } 28 | 29 | public DateTime Date 30 | { 31 | get { return _date; } 32 | 33 | private set { _date = value; } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/InitialCode/RiskFactor.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConditionalLogicWithStrategy.InitialCode 2 | { 3 | public class RiskFactor 4 | { 5 | private RiskFactor() { 6 | 7 | } 8 | 9 | public static RiskFactor GetFactors() 10 | { 11 | return new RiskFactor(); 12 | } 13 | 14 | public double ForRating(double riskRating) 15 | { 16 | return 0.03; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/InitialCode/UnusedRiskFactors.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConditionalLogicWithStrategy.InitialCode 2 | { 3 | public class UnusedRiskFactors 4 | { 5 | private UnusedRiskFactors() { 6 | 7 | } 8 | 9 | public static UnusedRiskFactors GetFactors() 10 | { 11 | return new UnusedRiskFactors(); 12 | } 13 | 14 | public double ForRating(double riskRating) 15 | { 16 | return 0.01; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/MyWork/Loan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace ReplaceConditionalLogicWithStrategy.MyWork 5 | { 6 | public class Loan 7 | { 8 | double _commitment = 1.0; 9 | private DateTime? _expiry; 10 | private DateTime? _maturity; 11 | private double _outstanding; 12 | IList _payments = new List(); 13 | private DateTime? _today = DateTime.Now; 14 | private DateTime _start; 15 | private long MILLIS_PER_DAY = 86400000; 16 | private long DAYS_PER_YEAR = 365; 17 | private double _riskRating; 18 | private double _unusedPercentage; 19 | 20 | public Loan(double commitment, double notSureWhatThisIs, DateTime start, DateTime? expiry, DateTime? maturity, int riskRating) 21 | { 22 | this._expiry = expiry; 23 | this._commitment = commitment; 24 | this._today = null; 25 | this._start = start; 26 | this._maturity = maturity; 27 | this._riskRating = riskRating; 28 | this._unusedPercentage = 1.0; 29 | } 30 | 31 | public static Loan NewTermLoan(double commitment, DateTime start, DateTime maturity, int riskRating) 32 | { 33 | return new Loan(commitment, commitment, start, null, 34 | maturity, riskRating); 35 | } 36 | 37 | public static Loan NewRevolver(double commitment, DateTime start, DateTime expiry, int riskRating) 38 | { 39 | return new Loan(commitment, 0, start, expiry, 40 | null, riskRating); 41 | } 42 | 43 | public static Loan NewAdvisedLine(double commitment, DateTime start, DateTime expiry, int riskRating) 44 | { 45 | if (riskRating > 3) return null; 46 | Loan advisedLine = new Loan(commitment, 0, start, expiry, 47 | null, riskRating); 48 | advisedLine.SetUnusedPercentage(0.1); 49 | return advisedLine; 50 | } 51 | 52 | public void Payment(double amount, DateTime paymentDate) 53 | { 54 | _payments.Add(new Payment(amount, paymentDate)); 55 | } 56 | 57 | public double Capital() { 58 | if(_expiry == null && _maturity != null) 59 | return _commitment * Duration() * RiskFactor(); 60 | if(_expiry != null && _maturity == null) { 61 | if(GetUnusedPercentage() != 1.0) { 62 | return _commitment * GetUnusedPercentage() * Duration() * RiskFactor(); 63 | } 64 | else { 65 | return (OutstandingRiskAmount() * Duration() * RiskFactor()) 66 | + (UnusedRiskAmount() * Duration() * UnusedRiskFactor()); 67 | } 68 | } 69 | return 0.0; 70 | } 71 | 72 | public double Duration() 73 | { 74 | if (_expiry == null && _maturity != null) 75 | { 76 | return WeightedAverageDuration(); 77 | } 78 | else if (_expiry != null && _maturity == null) 79 | { 80 | return YearsTo(_expiry); 81 | } 82 | return 0.0; 83 | } 84 | 85 | private double WeightedAverageDuration() 86 | { 87 | double duration = 0.0; 88 | double weightedAverage = 0.0; 89 | double sumOfPayments = 0.0; 90 | 91 | foreach (var payment in _payments) 92 | { 93 | sumOfPayments += payment.Amount; 94 | weightedAverage += YearsTo(payment.Date) * payment.Amount; 95 | } 96 | 97 | if (_commitment != 0.0) 98 | { 99 | duration = weightedAverage / sumOfPayments; 100 | } 101 | 102 | return duration; 103 | } 104 | 105 | private double YearsTo(DateTime? endDate) 106 | { 107 | DateTime? beginDate = (_today == null ? _start : _today); 108 | return (double)((endDate?.Ticks - beginDate?.Ticks) / MILLIS_PER_DAY / DAYS_PER_YEAR); 109 | } 110 | 111 | private double RiskFactor() 112 | { 113 | return InitialCode.RiskFactor.GetFactors().ForRating(_riskRating); 114 | } 115 | 116 | private double GetUnusedPercentage() 117 | { 118 | return _unusedPercentage; 119 | } 120 | 121 | public void SetUnusedPercentage(double unusedPercentage) 122 | { 123 | _unusedPercentage = unusedPercentage; 124 | } 125 | 126 | private double UnusedRiskAmount() 127 | { 128 | return (_commitment - _outstanding); 129 | } 130 | 131 | private double UnusedRiskFactor() 132 | { 133 | return UnusedRiskFactors.GetFactors().ForRating(_riskRating); 134 | } 135 | 136 | private double OutstandingRiskAmount() 137 | { 138 | return _outstanding; 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/MyWork/Payment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ReplaceConditionalLogicWithStrategy.MyWork 4 | { 5 | public class Payment 6 | { 7 | private double _amount; 8 | private DateTime _date; 9 | 10 | public Payment() 11 | { 12 | _amount = 0.0; 13 | _date = new DateTime(); 14 | } 15 | 16 | public Payment(double amount, DateTime date) 17 | { 18 | Amount = amount; 19 | Date = date; 20 | } 21 | 22 | public double Amount 23 | { 24 | get { return _amount; } 25 | 26 | private set { _amount = value; } 27 | } 28 | 29 | public DateTime Date 30 | { 31 | get { return _date; } 32 | 33 | private set { _date = value; } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/MyWork/RiskFactor.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConditionalLogicWithStrategy.MyWork 2 | { 3 | public class RiskFactor 4 | { 5 | private RiskFactor() { 6 | 7 | } 8 | 9 | public static RiskFactor GetFactors() 10 | { 11 | return new RiskFactor(); 12 | } 13 | 14 | public double ForRating(double riskRating) 15 | { 16 | return 0.03; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/MyWork/UnusedRiskFactors.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConditionalLogicWithStrategy.MyWork 2 | { 3 | public class UnusedRiskFactors 4 | { 5 | private UnusedRiskFactors() { 6 | 7 | } 8 | 9 | public static UnusedRiskFactors GetFactors() 10 | { 11 | return new UnusedRiskFactors(); 12 | } 13 | 14 | public double ForRating(double riskRating) 15 | { 16 | return 0.01; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("ReplaceConditionalLogicWithStrategy")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /ReplaceConditionalLogicWithStrategy/ReplaceConditionalLogicWithStrategy.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {ABA760CB-DC75-4C05-9CD7-DE2D19B5E64F} 7 | Library 8 | ReplaceConditionalLogicWithStrategy 9 | ReplaceConditionalLogicWithStrategy 10 | v4.8 11 | 9 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/InitialCode/CapitalStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.InitialCode 2 | { 3 | public class CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/InitialCode/CapitalStrategyRCTL.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.InitialCode 2 | { 3 | public class CapitalStrategyRCTL : CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/InitialCode/CapitalStrategyRevolver.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.InitialCode 2 | { 3 | public class CapitalStrategyRevolver : CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/InitialCode/CapitalStrategyTermLoan.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.InitialCode 2 | { 3 | public class CapitalStrategyTermLoan : CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/InitialCode/Loan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ReplaceConstructorsWithCreationMethods.InitialCode 4 | { 5 | public class Loan 6 | { 7 | private double _commitment; 8 | private readonly double _outstanding; 9 | private readonly int _riskRating; 10 | private readonly DateTime? _maturity; 11 | private readonly DateTime? _expiry; 12 | private readonly CapitalStrategy _capitalStrategy; 13 | 14 | public Loan(double commitment, int riskRating, DateTime? maturity) 15 | : this(commitment, 0.00, riskRating, maturity, null) 16 | { 17 | 18 | } 19 | 20 | public Loan(double commitment, int riskRating, DateTime? maturity, DateTime? expiry) 21 | : this(commitment, 0.00, riskRating, maturity, expiry) 22 | { 23 | 24 | } 25 | 26 | public Loan(double commitment, double outstanding, 27 | int riskRating, DateTime? maturity, DateTime? expiry) 28 | : this(null, commitment, outstanding, riskRating, maturity, expiry) 29 | { 30 | 31 | } 32 | 33 | public Loan(CapitalStrategy capitalStrategy, double commitment, 34 | int riskRating, DateTime? maturity, DateTime? expiry) 35 | : this(capitalStrategy, commitment, 0.00, riskRating, maturity, expiry) 36 | { 37 | 38 | } 39 | 40 | public Loan(CapitalStrategy capitalStrategy, double commitment, 41 | double outstanding, int riskRating, 42 | DateTime? maturity, DateTime? expiry) 43 | { 44 | this._commitment = commitment; 45 | this._outstanding = outstanding; 46 | this._riskRating = riskRating; 47 | this._maturity = maturity; 48 | this._expiry = expiry; 49 | this._capitalStrategy = capitalStrategy; 50 | 51 | if (capitalStrategy == null) 52 | { 53 | if (expiry == null) 54 | this._capitalStrategy = new CapitalStrategyTermLoan(); 55 | else if (maturity == null) 56 | this._capitalStrategy = new CapitalStrategyRevolver(); 57 | else 58 | this._capitalStrategy = new CapitalStrategyRCTL(); 59 | } 60 | } 61 | 62 | public CapitalStrategy CapitalStrategy 63 | { 64 | get 65 | { 66 | return _capitalStrategy; 67 | } 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/InitialCode/RiskAdjustedCapitalStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.InitialCode 2 | { 3 | public class RiskAdjustedCapitalStrategy: CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/MyWork/CapitalStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.MyWork 2 | { 3 | public class CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/MyWork/CapitalStrategyRCTL.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.MyWork 2 | { 3 | public class CapitalStrategyRCTL : CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/MyWork/CapitalStrategyRevolver.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.MyWork 2 | { 3 | public class CapitalStrategyRevolver : CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/MyWork/CapitalStrategyTermLoan.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.MyWork 2 | { 3 | public class CapitalStrategyTermLoan : CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/MyWork/Loan.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ReplaceConstructorsWithCreationMethods.MyWork 4 | { 5 | public class Loan 6 | { 7 | private double _commitment; 8 | private readonly double _outstanding; 9 | private readonly int _riskRating; 10 | private readonly DateTime? _maturity; 11 | private readonly DateTime? _expiry; 12 | private readonly CapitalStrategy _capitalStrategy; 13 | 14 | public Loan(double commitment, int riskRating, DateTime? maturity) 15 | : this(commitment, 0.00, riskRating, maturity, null) 16 | { 17 | 18 | } 19 | 20 | public Loan(double commitment, int riskRating, DateTime? maturity, DateTime? expiry) 21 | : this(commitment, 0.00, riskRating, maturity, expiry) 22 | { 23 | 24 | } 25 | 26 | public Loan(double commitment, double outstanding, 27 | int riskRating, DateTime? maturity, DateTime? expiry) 28 | : this(null, commitment, outstanding, riskRating, maturity, expiry) 29 | { 30 | 31 | } 32 | 33 | public Loan(CapitalStrategy capitalStrategy, double commitment, 34 | int riskRating, DateTime? maturity, DateTime? expiry) 35 | : this(capitalStrategy, commitment, 0.00, riskRating, maturity, expiry) 36 | { 37 | 38 | } 39 | 40 | public Loan(CapitalStrategy capitalStrategy, double commitment, 41 | double outstanding, int riskRating, 42 | DateTime? maturity, DateTime? expiry) 43 | { 44 | this._commitment = commitment; 45 | this._outstanding = outstanding; 46 | this._riskRating = riskRating; 47 | this._maturity = maturity; 48 | this._expiry = expiry; 49 | this._capitalStrategy = capitalStrategy; 50 | 51 | if (capitalStrategy == null) 52 | { 53 | if (expiry == null) 54 | this._capitalStrategy = new CapitalStrategyTermLoan(); 55 | else if (maturity == null) 56 | this._capitalStrategy = new CapitalStrategyRevolver(); 57 | else 58 | this._capitalStrategy = new CapitalStrategyRCTL(); 59 | } 60 | } 61 | 62 | public CapitalStrategy CapitalStrategy 63 | { 64 | get 65 | { 66 | return _capitalStrategy; 67 | } 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/MyWork/RiskAdjustedCapitalStrategy.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceConstructorsWithCreationMethods.MyWork 2 | { 3 | public class RiskAdjustedCapitalStrategy: CapitalStrategy 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("ReplaceConstructorsWithCreationMethods")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /ReplaceConstructorsWithCreationMethods/ReplaceConstructorsWithCreationMethods.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {62ECDEAE-B8A4-4CD1-ACF5-E11965928B4B} 7 | Library 8 | ReplaceConstructorsWithCreationMethods 9 | ReplaceConstructorsWithCreationMethods 10 | v4.8 11 | 9 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/InitialCode/Order.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ReplaceImplicitTreeWithComposite.InitialCode 4 | { 5 | public class Order 6 | { 7 | private readonly int id; 8 | private List products; 9 | 10 | public Order(int id) 11 | { 12 | this.products = new List(); 13 | this.id = id; 14 | } 15 | 16 | public int OrderId() 17 | { 18 | return this.id; 19 | } 20 | 21 | public void Add(Product product) 22 | { 23 | this.products.Add(product); 24 | } 25 | 26 | public int ProductCount() 27 | { 28 | return this.products.Count; 29 | } 30 | 31 | public Product Product(int insertionIndex) 32 | { 33 | return this.products[insertionIndex]; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/InitialCode/Orders.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ReplaceImplicitTreeWithComposite.InitialCode 4 | { 5 | 6 | public class Orders 7 | { 8 | private List orders; 9 | 10 | public Orders() 11 | { 12 | this.orders = new List(); 13 | } 14 | 15 | public void Add(Order order) 16 | { 17 | this.orders.Add(order); 18 | } 19 | 20 | public int OrderCount() 21 | { 22 | return this.orders.Count; 23 | } 24 | 25 | public Order Order(int insertionIndex) 26 | { 27 | return this.orders[insertionIndex]; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/InitialCode/OrdersWriter.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace ReplaceImplicitTreeWithComposite.InitialCode 4 | { 5 | 6 | public class OrdersWriter 7 | { 8 | private Orders orders; 9 | 10 | public OrdersWriter(Orders orders) 11 | { 12 | this.orders = orders; 13 | } 14 | 15 | public string GetContents() 16 | { 17 | StringBuilder xml = new StringBuilder(); 18 | xml.Append(""); 19 | for (int i = 0; i < this.orders.OrderCount(); i++) 20 | { 21 | Order order = this.orders.Order(i); 22 | xml.Append(""); 26 | for (int j = 0; j < order.ProductCount(); j++) 27 | { 28 | Product product = order.Product(j); 29 | xml.Append(""); 44 | xml.Append(""); 48 | xml.Append(product.Price); 49 | xml.Append(""); 50 | xml.Append(product.Name); 51 | xml.Append(""); 52 | } 53 | 54 | xml.Append(""); 55 | } 56 | 57 | xml.Append(""); 58 | return xml.ToString(); 59 | } 60 | 61 | private string CurrencyFor(Product product) 62 | { 63 | // I made the assumption that all products will be in USD for 64 | // this example 65 | return "USD"; 66 | } 67 | 68 | private string SizeFor(Product product) 69 | { 70 | // I've made the assumption that all sizes will be a medium 71 | // for this example 72 | switch (product.Size) 73 | { 74 | case ProductSize.Medium: 75 | return "medium"; 76 | default: 77 | return "NOT APPLICABLE"; 78 | } 79 | } 80 | 81 | private string ColorFor(Product product) 82 | { 83 | // I made the assumption that all products are red for this example 84 | return "red"; 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/InitialCode/Product.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceImplicitTreeWithComposite.InitialCode 2 | { 3 | public class Product 4 | { 5 | public Product(int id, string name, ProductSize size, string price) 6 | { 7 | this.ID = id; 8 | this.Name = name; 9 | this.Size = size; 10 | this.Price = price; 11 | } 12 | 13 | public int ID { get; } 14 | 15 | public string Name { get; } 16 | 17 | public ProductSize Size { get; } 18 | 19 | public string Price { get; } 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/InitialCode/ProductSize.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceImplicitTreeWithComposite.InitialCode 2 | { 3 | public enum ProductSize 4 | { 5 | NotApplicable, 6 | Small, 7 | Medium, 8 | Large, 9 | ExtraLarge 10 | } 11 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/MyWork/Order.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ReplaceImplicitTreeWithComposite.MyWork 4 | { 5 | public class Order 6 | { 7 | private readonly int id; 8 | private List products; 9 | 10 | public Order(int id) 11 | { 12 | this.products = new List(); 13 | this.id = id; 14 | } 15 | 16 | public int OrderId() 17 | { 18 | return this.id; 19 | } 20 | 21 | public void Add(Product product) 22 | { 23 | this.products.Add(product); 24 | } 25 | 26 | public int ProductCount() 27 | { 28 | return this.products.Count; 29 | } 30 | 31 | public Product Product(int insertionIndex) 32 | { 33 | return this.products[insertionIndex]; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/MyWork/Orders.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace ReplaceImplicitTreeWithComposite.MyWork 4 | { 5 | 6 | public class Orders 7 | { 8 | private List orders; 9 | 10 | public Orders() 11 | { 12 | this.orders = new List(); 13 | } 14 | 15 | public void Add(Order order) 16 | { 17 | this.orders.Add(order); 18 | } 19 | 20 | public int OrderCount() 21 | { 22 | return this.orders.Count; 23 | } 24 | 25 | public Order Order(int insertionIndex) 26 | { 27 | return this.orders[insertionIndex]; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/MyWork/OrdersWriter.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace ReplaceImplicitTreeWithComposite.MyWork 4 | { 5 | 6 | public class OrdersWriter 7 | { 8 | private Orders orders; 9 | 10 | public OrdersWriter(Orders orders) 11 | { 12 | this.orders = orders; 13 | } 14 | 15 | public string GetContents() 16 | { 17 | StringBuilder xml = new StringBuilder(); 18 | xml.Append(""); 19 | for (int i = 0; i < this.orders.OrderCount(); i++) 20 | { 21 | Order order = this.orders.Order(i); 22 | xml.Append(""); 26 | for (int j = 0; j < order.ProductCount(); j++) 27 | { 28 | Product product = order.Product(j); 29 | xml.Append(""); 44 | xml.Append(""); 48 | xml.Append(product.Price); 49 | xml.Append(""); 50 | xml.Append(product.Name); 51 | xml.Append(""); 52 | } 53 | 54 | xml.Append(""); 55 | } 56 | 57 | xml.Append(""); 58 | return xml.ToString(); 59 | } 60 | 61 | private string CurrencyFor(Product product) 62 | { 63 | // I made the assumption that all products will be in USD for 64 | // this example 65 | return "USD"; 66 | } 67 | 68 | private string SizeFor(Product product) 69 | { 70 | // I've made the assumption that all sizes will be a medium 71 | // for this example 72 | switch (product.Size) 73 | { 74 | case ProductSize.Medium: 75 | return "medium"; 76 | default: 77 | return "NOT APPLICABLE"; 78 | } 79 | } 80 | 81 | private string ColorFor(Product product) 82 | { 83 | // I made the assumption that all products are red for this example 84 | return "red"; 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/MyWork/Product.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceImplicitTreeWithComposite.MyWork 2 | { 3 | public class Product 4 | { 5 | public Product(int id, string name, ProductSize size, string price) 6 | { 7 | this.ID = id; 8 | this.Name = name; 9 | this.Size = size; 10 | this.Price = price; 11 | } 12 | 13 | public int ID { get; } 14 | 15 | public string Name { get; } 16 | 17 | public ProductSize Size { get; } 18 | 19 | public string Price { get; } 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/MyWork/ProductSize.cs: -------------------------------------------------------------------------------- 1 | namespace ReplaceImplicitTreeWithComposite.MyWork 2 | { 3 | public enum ProductSize 4 | { 5 | NotApplicable, 6 | Small, 7 | Medium, 8 | Large, 9 | ExtraLarge 10 | } 11 | } -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("ReplaceImplicitTreeWithComposite")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("${AuthorCopyright}")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | -------------------------------------------------------------------------------- /ReplaceImplicitTreeWithComposite/ReplaceImplicitTreeWithComposite.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | {DA8504D9-4160-43FB-AEE5-E6DDC9368A91} 7 | Library 8 | ReplaceImplicitTreeWithComposite 9 | ReplaceImplicitTreeWithComposite 10 | v4.8 11 | 9 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | true 37 | 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | true 48 | 49 | 50 | false 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | --------------------------------------------------------------------------------