Here are my class library code which create credit card.
public abstract class CreditCard
{
public CardType CardType { get; protected set; }
public decimal CreditLimit { get; protected set; }
public decimal AnnualCharge { get; protected set; }
}
public class GoldCreditCard : CreditCard
{
private GoldCreditCard(decimal creditLimit, decimal annualCharge)
{
CardType = CardType.Gold;
CreditLimit = creditLimit;
AnnualCharge = annualCharge;
}
/// <summary>
/// Factory pattern
/// </summary>
/// <returns></returns>
public static CreditCard Create()
{
return new GoldCreditCard(creditLimit: 15000, annualCharge: 100);
}
}
public class TitaniumCreditCard : CreditCard
{
private TitaniumCreditCard(decimal creditLimit, decimal annualCharge)
{
CardType = CardType.Titanium;
CreditLimit = creditLimit;
AnnualCharge = annualCharge;
}
/// <summary>
/// Factory pattern
/// </summary>
/// <returns></returns>
public static CreditCard Create()
{
return new TitaniumCreditCard(creditLimit: 30000, annualCharge: 250);
}
}
and the ui will be:
static void Main(string[] args)
{
CreditCard card;
System.Console.WriteLine("Select your card type");
System.Console.WriteLine("1. Gold Credit Card");
System.Console.WriteLine("2. Titanium Credit Card");
var option = System.Console.ReadLine();
switch (option)
{
case "1":
card = GoldCreditCard.Create();
PrintCard(card);
break;
case "2":
card = TitaniumCreditCard.Create();
PrintCard(card);
break;
default:
break;
}
}
static void PrintCard(CreditCard card)
{
System.Console.WriteLine($"Your credit card has been successfully created.");
System.Console.WriteLine($"The credit card type is {card.CardType}.");
System.Console.WriteLine($"The credit card limit is {card.CreditLimit:C}.");
System.Console.WriteLine($"The credit card annual fee is {card.AnnualCharge:C}.");
}
Is this implementation of factory design pattern in C#?
-
1\$\begingroup\$ Subclasses are not ment to be used like this. In your example both implemnetations are identical with only the data being different. \$\endgroup\$Anders– Anders2020年06月19日 09:22:23 +00:00Commented Jun 19, 2020 at 9:22
-
2\$\begingroup\$ In a normal usecase these are stored in a credit card type table or nosql data type. Than you set which credit card type a instance has. Thats the naive way, you probably need to make that data periodic since mulrtiple versions of the card can exists at the same time with different bonuses, fees etc \$\endgroup\$Anders– Anders2020年06月19日 09:24:33 +00:00Commented Jun 19, 2020 at 9:24
-
1\$\begingroup\$ "State what your code does in your title, not your main concerns about it." codereview.stackexchange.com/help/how-to-ask \$\endgroup\$BCdotWEB– BCdotWEB2020年06月19日 22:34:05 +00:00Commented Jun 19, 2020 at 22:34
1 Answer 1
In your implementation you have smashed together two separate roles: Product and Creator.
Your implementation is equivalent with the following:
public class GoldCreditCard : CreditCard
{
private GoldCreditCard(decimal creditLimit, decimal annualCharge)
{
CardType = CardType.Gold;
CreditLimit = creditLimit;
AnnualCharge = annualCharge;
}
public GoldCreditCard()
{
CardType = CardType.Gold;
CreditLimit = 15000;
AnnualCharge = 100;
}
}
Or almost with this one (this provides more flexibility):
public class GoldCreditCard : CreditCard
{
public GoldCreditCard(decimal creditLimit = 15000, decimal annualCharge = 100)
{
CardType = CardType.Gold;
CreditLimit = creditLimit;
AnnualCharge = annualCharge;
}
}
The whole point of the pattern is that only the Creator (Factory) knows how to setup a concrete product. In your case your class knows how to initialize itself.