├── .gitignore ├── BridgePattern.sln ├── BridgePattern ├── BridgePattern.csproj ├── Movie.cs └── Program.cs ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | .svn 3 | obj 4 | bin 5 | .idea 6 | _ReSharper* 7 | *.sln.GhostDoc.xml 8 | *.dotCover 9 | *.suo 10 | *.user 11 | *.Cache 12 | *.cache 13 | *.ncrunchsolution 14 | *.ncrunchproject 15 | */packages/*/* 16 | /Tools/*/* 17 | project.lock.json 18 | project.fragment.lock.json 19 | .vs -------------------------------------------------------------------------------- /BridgePattern.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30114.128 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BridgePattern", "BridgePattern\BridgePattern.csproj", "{556A9F42-400D-486D-B785-85E86D5685EE}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8AD3D1CA-D306-416B-8AB2-C328922C6FF2}" 9 | ProjectSection(SolutionItems) = preProject 10 | .gitignore = .gitignore 11 | LICENSE = LICENSE 12 | README.md = README.md 13 | EndProjectSection 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|Any CPU = Debug|Any CPU 18 | Release|Any CPU = Release|Any CPU 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {556A9F42-400D-486D-B785-85E86D5685EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {556A9F42-400D-486D-B785-85E86D5685EE}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {556A9F42-400D-486D-B785-85E86D5685EE}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {556A9F42-400D-486D-B785-85E86D5685EE}.Release|Any CPU.Build.0 = Release|Any CPU 25 | EndGlobalSection 26 | GlobalSection(SolutionProperties) = preSolution 27 | HideSolutionNode = FALSE 28 | EndGlobalSection 29 | GlobalSection(ExtensibilityGlobals) = postSolution 30 | SolutionGuid = {13D85759-9910-4CD7-BF2F-7AF9563B4722} 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /BridgePattern/BridgePattern.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /BridgePattern/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BridgePattern 4 | { 5 | public class MovieLicense 6 | { 7 | private readonly Discount _discount; 8 | private readonly LicenceType _licenceType; 9 | private readonly SpecialOffer _specialOffer; 10 | 11 | public string Movie { get; } 12 | public DateTime PurchaseTime { get; } 13 | 14 | public MovieLicense( 15 | string movie, 16 | DateTime purchaseTime, 17 | Discount discount, 18 | LicenceType licenceType, 19 | SpecialOffer specialOffer = SpecialOffer.None) 20 | { 21 | Movie = movie; 22 | PurchaseTime = purchaseTime; 23 | _discount = discount; 24 | _licenceType = licenceType; 25 | _specialOffer = specialOffer; 26 | } 27 | 28 | public decimal GetPrice() 29 | { 30 | int discount = GetDiscount(); 31 | decimal multiplier = 1 - discount / 100m; 32 | return GetBasePrice() * multiplier; 33 | } 34 | 35 | private int GetDiscount() 36 | { 37 | return _discount switch 38 | { 39 | Discount.None => 0, 40 | Discount.Military => 10, 41 | Discount.Senior => 20, 42 | 43 | _ => throw new ArgumentOutOfRangeException() 44 | }; 45 | } 46 | 47 | private decimal GetBasePrice() 48 | { 49 | return _licenceType switch 50 | { 51 | LicenceType.TwoDays => 4, 52 | LicenceType.LifeLong => 8, 53 | 54 | _ => throw new ArgumentOutOfRangeException() 55 | }; 56 | } 57 | 58 | public DateTime? GetExpirationDate() 59 | { 60 | DateTime? expirationDate = GetBaseExpirationDate(); 61 | TimeSpan extension = GetSpecialOfferExtension(); 62 | 63 | return expirationDate?.Add(extension); 64 | } 65 | 66 | private TimeSpan GetSpecialOfferExtension() 67 | { 68 | return _specialOffer switch 69 | { 70 | SpecialOffer.None => TimeSpan.Zero, 71 | SpecialOffer.TwoDaysExtension => TimeSpan.FromDays(2), 72 | 73 | _ => throw new ArgumentOutOfRangeException() 74 | }; 75 | } 76 | 77 | private DateTime? GetBaseExpirationDate() 78 | { 79 | return _licenceType switch 80 | { 81 | LicenceType.TwoDays => PurchaseTime.AddDays(2) as DateTime?, 82 | LicenceType.LifeLong => null, 83 | 84 | _ => throw new ArgumentOutOfRangeException() 85 | }; 86 | } 87 | } 88 | 89 | public enum LicenceType 90 | { 91 | TwoDays, 92 | LifeLong 93 | } 94 | 95 | public enum Discount 96 | { 97 | None, 98 | Military, 99 | Senior 100 | } 101 | 102 | public enum SpecialOffer 103 | { 104 | None, 105 | TwoDaysExtension 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /BridgePattern/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BridgePattern 4 | { 5 | public class Program 6 | { 7 | public static void Main() 8 | { 9 | DateTime now = DateTime.Now; 10 | 11 | var license1 = new MovieLicense("Secret Life of Pets", now, Discount.None, LicenceType.TwoDays); 12 | var license2 = new MovieLicense("Matrix", now, Discount.None, LicenceType.LifeLong); 13 | 14 | PrintLicenseDetails(license1); 15 | PrintLicenseDetails(license2); 16 | 17 | var license3 = new MovieLicense("Secret Life of Pets", now, Discount.Military, LicenceType.LifeLong); 18 | var license4 = new MovieLicense("Matrix", now, Discount.Senior, LicenceType.TwoDays); 19 | 20 | PrintLicenseDetails(license3); 21 | PrintLicenseDetails(license4); 22 | 23 | var license5 = new MovieLicense("Matrix", now, Discount.Senior, LicenceType.TwoDays, SpecialOffer.TwoDaysExtension); 24 | 25 | PrintLicenseDetails(license5); 26 | 27 | Console.ReadKey(); 28 | } 29 | 30 | private static void PrintLicenseDetails(MovieLicense license) 31 | { 32 | Console.WriteLine($"Movie: {license.Movie}"); 33 | Console.WriteLine($"Price: {GetPrice(license)}"); 34 | Console.WriteLine($"Valid for: {GetValidFor(license)}"); 35 | 36 | Console.WriteLine(); 37 | } 38 | 39 | private static string GetPrice(MovieLicense license) 40 | { 41 | return $"${license.GetPrice():0.00}"; 42 | } 43 | 44 | private static string GetValidFor(MovieLicense license) 45 | { 46 | DateTime? expirationDate = license.GetExpirationDate(); 47 | 48 | if (expirationDate == null) 49 | return "Forever"; 50 | 51 | TimeSpan timeSpan = expirationDate.Value - DateTime.Now; 52 | 53 | return $"{timeSpan.Days}d {timeSpan.Hours}h {timeSpan.Minutes}m"; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Vladimir Khorikov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Welcome to C# Design Patterns: Bridge 2 | ===================== 3 | 4 | This is the source code for my Pluralsight course [C# Design Patterns: Bridge][L1] 5 | 6 | "Before" and "After" versions 7 | --------------------------- 8 | 9 | If you want to follow along with the course, clone the repository and roll its state back to the [commit marked as "Initial"][L2]. This is the starting point of the course. 10 | 11 | [L1]: https://enterprisecraftsmanship.com/ps-bridge 12 | [L2]: https://github.com/vkhorikov/BridgePattern/commits/master 13 | --------------------------------------------------------------------------------