Last active
May 7, 2022 02:45
-
-
Save jwChung/3996292ead0cacdfe508fe31e278ea37 to your computer and use it in GitHub Desktop.
Payment Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
namespace ClassLibrary3 | |
{ | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
var service = new PaymentService( | |
new CompositeDiscountableFactory( | |
// new EventDiscountFactory(), | |
new NaverDiscountableFactory(), | |
new DanawaDiscountableFactory(), | |
new FancafeDiscountableFactory())); | |
service.Pay(100, "Naver"); | |
service.Pay(100, "Danawa"); | |
service.Pay(100, "Fancafe"); | |
} | |
} | |
public class PaymentService | |
{ | |
public PaymentService(IDiscountableFactory factory) | |
{ | |
Factory = factory; | |
} | |
public IDiscountableFactory Factory { get; } | |
public void Pay(decimal amount, string discountName) | |
{ | |
decimal payment = amount - Factory.Create(discountName).GetDiscountAmount(amount); | |
Console.WriteLine($"Paied {payment}."); | |
} | |
} | |
public interface IDiscountable | |
{ | |
decimal GetDiscountAmount(decimal originalAmout); | |
} | |
public class NullDiscountPolicy : IDiscountable | |
{ | |
private static NullDiscountPolicy instance = new NullDiscountPolicy(); | |
private NullDiscountPolicy() | |
{ | |
} | |
public static NullDiscountPolicy Instance | |
{ | |
get { return NullDiscountPolicy.instance; } | |
} | |
public decimal GetDiscountAmount(decimal originalAmout) | |
{ | |
throw new InvalidOperationException( | |
"This respresents the null-discount policy."); | |
} | |
} | |
public class RateDiscountPolicy : IDiscountable | |
{ | |
public RateDiscountPolicy(decimal rate) | |
{ | |
Rate = rate; | |
} | |
public decimal Rate { get; } | |
public decimal GetDiscountAmount(decimal originalAmout) | |
{ | |
return originalAmout * Rate; | |
} | |
} | |
public class MaxDiscountPolicy : IDiscountable | |
{ | |
public MaxDiscountPolicy(decimal maxAmount) | |
{ | |
MaxAmount = maxAmount; | |
} | |
public decimal MaxAmount { get; } | |
public decimal GetDiscountAmount(decimal originalAmout) | |
{ | |
return originalAmout < MaxAmount | |
? originalAmout | |
: MaxAmount; | |
} | |
} | |
public interface IDiscountableFactory | |
{ | |
IDiscountable Create(string discountName); | |
} | |
public class CompositeDiscountableFactory : IDiscountableFactory | |
{ | |
public CompositeDiscountableFactory(params IDiscountableFactory[] factories) | |
{ | |
Factories = factories; | |
} | |
IEnumerable<IDiscountableFactory> Factories { get; } | |
public IDiscountable Create(string discountName) | |
{ | |
foreach (IDiscountableFactory factory in Factories) | |
{ | |
IDiscountable policy = factory.Create(discountName); | |
if (policy != NullDiscountPolicy.Instance) | |
return policy; | |
} | |
return NullDiscountPolicy.Instance; | |
} | |
} | |
public class NaverDiscountableFactory : IDiscountableFactory | |
{ | |
public IDiscountable Create(string discountName) | |
{ | |
return discountName == "Naver" | |
? (IDiscountable)new RateDiscountPolicy(0.1m) | |
: NullDiscountPolicy.Instance; | |
} | |
} | |
public class DanawaDiscountableFactory : IDiscountableFactory | |
{ | |
public IDiscountable Create(string discountName) | |
{ | |
return discountName == "Danawa" | |
? (IDiscountable)new RateDiscountPolicy(0.15m) | |
: NullDiscountPolicy.Instance; | |
} | |
} | |
public class FancafeDiscountableFactory : IDiscountableFactory | |
{ | |
public IDiscountable Create(string discountName) | |
{ | |
return discountName == "Fancafe" | |
? (IDiscountable)new MaxDiscountPolicy(50m) | |
: NullDiscountPolicy.Instance; | |
} | |
} | |
public class EventDiscountFactory : IDiscountableFactory | |
{ | |
public IDiscountable Create(string discountName) | |
{ | |
//DB에서 dicountName에 해당하는 할인율 적용 | |
decimal rate; | |
if (TryGetDicountRate(discountName, out rate)) | |
{ | |
return new RateDiscountPolicy(rate); | |
} | |
return NullDiscountPolicy.Instance; | |
} | |
private bool TryGetDicountRate(string discountName, out decimal rate) | |
{ | |
rate = 0.2m; // DB에서 할인율 가져오기 | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
코드 잘 보았습니다. 그런데 질문이 있습니다
코드에서 새로운 DiscountPolicy를 추가하려면 결국에는 Main 메서드가 있는 Program 클래스를 수정해야하는데, 그러면 결국 OCP가 또 위반이 되는게 아닌가 생각합니다