diff --git a/prototype_pattern/prototype/BasicCustomer.cs b/prototype_pattern/prototype/BasicCustomer.cs new file mode 100644 index 0000000..a950f84 --- /dev/null +++ b/prototype_pattern/prototype/BasicCustomer.cs @@ -0,0 +1,15 @@ +using System; + +namespace Billing +{ + public abstract class BasicCustomer : ICloneable + { + public string FirstName {get;set;} + public string LastName{get;set;} + public Address HomeAddress{get;set;} + public Address BillingAddress{get;set;} + + public abstract object Clone(); + public abstract Customer DeepClone(); + } +} \ No newline at end of file diff --git a/prototype_pattern/prototype/Customer.cs b/prototype_pattern/prototype/Customer.cs index b76b956..b0901cb 100644 --- a/prototype_pattern/prototype/Customer.cs +++ b/prototype_pattern/prototype/Customer.cs @@ -1,13 +1,36 @@ +using System; + namespace Billing { - public abstract class Customer : ICloneable + public class Customer : BasicCustomer { - public string FirstName {get;set;} - public string LastName{get;set;} - public Address HomeAddress{get;set;} - public Address BillingAddress{get;set;} + public override object Clone() + { + return this.MemberwiseClone() as BasicCustomer; + } + public override Customer DeepClone() + { + var customer = this.MemberwiseClone() as Customer; + + customer.BillingAddress = new Address + { + StreetAddress = this.BillingAddress.StreetAddress, + City = this.BillingAddress.City, + State = this.BillingAddress.State, + Country = this.BillingAddress.Country, + PostCode = this.BillingAddress.PostCode + }; + + customer.HomeAddress = new Address + { + StreetAddress = this.HomeAddress.StreetAddress, + City = this.HomeAddress.City, + State = this.HomeAddress.State, + Country = this.HomeAddress.Country, + PostCode = this.HomeAddress.PostCode + }; - public abstract object Clone(); - public abstract Customer DeepClone(); + return customer; + } } } \ No newline at end of file diff --git a/prototype_pattern/prototype_pattern.sln b/prototype_pattern/prototype_pattern.sln index bba50e0..0abed97 100644 --- a/prototype_pattern/prototype_pattern.sln +++ b/prototype_pattern/prototype_pattern.sln @@ -3,6 +3,10 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26124.0 MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "prototype", "prototype\prototype.csproj", "{9691B873-D070-4816-B6CD-05E6F3A02011}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "prototype_test", "prototype_test\prototype_test.csproj", "{5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,4 +19,30 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9691B873-D070-4816-B6CD-05E6F3A02011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Debug|x64.ActiveCfg = Debug|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Debug|x64.Build.0 = Debug|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Debug|x86.ActiveCfg = Debug|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Debug|x86.Build.0 = Debug|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Release|Any CPU.Build.0 = Release|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Release|x64.ActiveCfg = Release|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Release|x64.Build.0 = Release|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Release|x86.ActiveCfg = Release|Any CPU + {9691B873-D070-4816-B6CD-05E6F3A02011}.Release|x86.Build.0 = Release|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Debug|x64.ActiveCfg = Debug|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Debug|x64.Build.0 = Debug|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Debug|x86.ActiveCfg = Debug|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Debug|x86.Build.0 = Debug|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Release|Any CPU.Build.0 = Release|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Release|x64.ActiveCfg = Release|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Release|x64.Build.0 = Release|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Release|x86.ActiveCfg = Release|Any CPU + {5EEB1626-0C27-4FC9-9EFB-6F55E6E08FCE}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection EndGlobal diff --git a/prototype_pattern/prototype_test/UnitTest1.cs b/prototype_pattern/prototype_test/UnitTest1.cs deleted file mode 100644 index 722f225..0000000 --- a/prototype_pattern/prototype_test/UnitTest1.cs +++ /dev/null @@ -1,18 +0,0 @@ -using NUnit.Framework; - -namespace prototype_test -{ - public class Tests - { - [SetUp] - public void Setup() - { - } - - [Test] - public void Test1() - { - Assert.Pass(); - } - } -} \ No newline at end of file diff --git a/prototype_pattern/prototype_test/prototype_test.cs b/prototype_pattern/prototype_test/prototype_test.cs new file mode 100644 index 0000000..596ea99 --- /dev/null +++ b/prototype_pattern/prototype_test/prototype_test.cs @@ -0,0 +1,71 @@ +using NUnit.Framework; +using FluentAssertions; +using Moq; + +namespace Billing.Tests +{ + public class Tests + { + private BasicCustomer _basicCustomer; + [SetUp] + public void Setup() + { + _basicCustomer = new Customer(); + _basicCustomer.FirstName = "John"; + _basicCustomer.LastName = "Smith"; + _basicCustomer.HomeAddress = new Address + { + StreetAddress = "1 Kent Street", + City = "Sydney", + State = "New South Wales", + Country = "Australia", + PostCode = "2000" + }; + _basicCustomer.BillingAddress = new Address + { + StreetAddress = _basicCustomer.HomeAddress.StreetAddress, + City = _basicCustomer.HomeAddress.City, + State = _basicCustomer.HomeAddress.State, + Country = _basicCustomer.HomeAddress.Country, + PostCode = _basicCustomer.HomeAddress.PostCode + }; + } + + [Test] + public void NewCustomer_ShallowCloneFromCustomerWithSameAddress_AddressObjectsAreShared() + { + // Arrange + var customer = (Customer)_basicCustomer.Clone(); + + // Act + var newStreetAddress = "26 York Street"; + var relatedCustomer = (Customer)customer.Clone(); + relatedCustomer.FirstName = "Jane"; + relatedCustomer.HomeAddress.StreetAddress = newStreetAddress; + + // Assert + customer.HomeAddress.Should().Be(relatedCustomer.HomeAddress); + + } + [Test] + public void NewCustomer_DeepCloneFromCustomerWithDifferentAddressSameFirstName_AddressObjectsAreDifferent() + { + // Arrange + var customer = (Customer)_basicCustomer.Clone(); + + // Act + var diffCustomer = customer.DeepClone(); + diffCustomer.FirstName = "Peter"; + diffCustomer.LastName = "Wick"; + diffCustomer.HomeAddress.StreetAddress = "57 Hassall Ridge"; + diffCustomer.HomeAddress.City = "Lexington"; + diffCustomer.HomeAddress.State = "Kentucky"; + diffCustomer.HomeAddress.Country = "United States Of America"; + diffCustomer.HomeAddress.PostCode = "40511"; + + // Assert + customer.HomeAddress.Should().NotBeEquivalentTo(diffCustomer.HomeAddress); + customer.FirstName.Should().BeEquivalentTo("John"); + } + } +} \ No newline at end of file diff --git a/prototype_pattern/prototype_test/prototype_test.csproj b/prototype_pattern/prototype_test/prototype_test.csproj index 04a656c..fb9bf1d 100644 --- a/prototype_pattern/prototype_test/prototype_test.csproj +++ b/prototype_pattern/prototype_test/prototype_test.csproj @@ -7,6 +7,8 @@ + +