题目
用户有一张信用卡,信用卡有一个总额度;每个月会有信用卡账单显示月消费总额,月消费总额是小于信用卡总额度的;用户有若干储蓄卡,可选择某张储蓄卡进行还款;还款是指从储蓄卡中划走信用卡的月消费总额到信用卡;如果储蓄卡余额不足则还款动作不成功。
要求如下:①必须使用委托②事件的触发方式是每个月的到期还款日;
题目分析
题目还是比较清晰的,要设计的点的有:
- 信用卡是到特定的日期才会广播需要结算的总消费额。
- 信用卡的成员是消费额度,还有一个最大额度来限制。
- 用户有若干个储蓄卡,每个储蓄卡都有各自的余额,信用卡的结算应该要广播到所有的储蓄卡都来接受。
- 储蓄卡余额不足会显示还款不成功。
逻辑并不复杂,我的想法是各个储蓄卡会订阅信用卡的广播,当到达特定的日期的时候,信用卡会向所有订阅了它的储蓄卡广播,然后进行扣款。需要注意的是这样设计的话每张储蓄卡都会收到扣款的广播,那么需要有一种办法能避免重复扣款。
代码实现
信用卡
可以先看看我对信用卡类的定义:
class CreditCard
{
private int consume;
private int maxconsume;
public delegate void SendAllConsumption(int count);
public event SendAllConsumption BeginMonth;
public int Consume
{
get { return consume; }
}
public void Buy(int a)
{
if (consume + a <= maxconsume)
{
consume += a;
}
else
{
System.Console.WriteLine("剩余额度不足!");
}
}
public void Settle(int day)
{
// 当到达还款日的时候,也就是每月四号,开始结算账目,把款项广播给各张储蓄卡
if (day == 4)
{
System.Console.WriteLine("到达还款日,将扣款{0}", consume);
BeginMonth(consume);
}
}
public CreditCard(int max)
{
this.consume = 0;
this.maxconsume = max;
}
信用卡的设计没啥特别的,就是定义了一个委托,然后定义了一个名为BeginMonth的事件,表示到了一个月的开头,要准备还款了;成员函数Settle就是结算,参数是每个月的号数,当号数为4的时候,判定成功,向订阅的函数发起广播,传递的参数为这个月信用卡的消费额。
储蓄卡
然后再看看对于储蓄卡的定义:
class DebitCard
{
private string name;
private int balence;
private static bool Settled;
public int Balence
{
get { return balence; }
}
public void Save(int a)
{
balence += a;
}
public void draw(int a)
{
balence -= a;
}
public string Name { get { return name; } set { name = value; } }
public DebitCard(string name)
{
this.name = name;
balence = 0;
Settled = false;
}
public void SettleHandler(int count)
{
// 如果没有结算,那么尝试扣款。
if (!Settled)
{
if (balence - count <= 0)
System.Console.WriteLine("{0}余额不足", name);
else
{
balence -= count;
Settled = true;
System.Console.WriteLine("{0}已成功扣款{1}", name, count);
}
}
}
这里我对于防止重复扣款的解决办法是定义一个静态成员settled,来标识当前这一次广播有没有背其他的储蓄卡成功处理,如果有被成功出的话settled应该会是true。
主函数
public static void Main(string[] args)
{
//定义一张最高消费额十万的信用卡
CreditCard cdcard = new CreditCard(100000);
//定义三张储蓄卡
DebitCard dbcard1 = new DebitCard("card1");
DebitCard dbcard2 = new DebitCard("card2");
DebitCard dbcard3 = new DebitCard("card3");
//往储蓄卡中存钱
dbcard1.Save(10000);
dbcard2.Save(9000);
dbcard3.Save(3000);
//订阅事件
cdcard.BeginMonth += dbcard1.SettleHandler;
cdcard.BeginMonth += dbcard2.SettleHandler;
cdcard.BeginMonth += dbcard3.SettleHandler;
//消费4000元
cdcard.Buy(4000);
//结算,传递参数为当前日期
cdcard.Settle(4);
}
最后就是主函数了,该说的都在注释里面写了。
运行
仓库
仓库clone地址为:https://gitee.com/DobyAsa/windows_-credit-card.git