纠结的重构:事件方式?配置方式?还是其他?
应用背景:
曾经开发过一个子系统,它最初的功能是站内的会员间相互送礼(某些礼物每个月是固定的),后来随着运营业务的扩展,逐渐地给它赋予了新的含义:比如参与评选最受欢迎的会员活动后,会员每收到一个礼物,其欢迎值按照某个比例增加,不参与活动的则忽略;某次与某个礼品店合作,会员参与活动后在特定的时间段内收到若干朵特定的花后即可兑换成某个实物;某些时候某些礼物又作为一个投票计数功能……等等,在某个清醒的早晨,我想到了重构该功能。
伪代码如下:
代码
public delegate void SendGift(UserBase sender, GiftBase gift, UserBase receiver);
public class UserGift
{
public event SendGift OnSendComplete;
public UserGift() { }
public int Send(UserBase sender, GiftBase gift, UserBase receiver) {
bool flag = false;
//检查花的数量是否足够
//检查收件人的设置
//其他规则
//检查通过才开始送礼
int result = -1;
if (flag) result = SendAction(sender.UserId, gift.GiftId, receiver.UserId);
if (result > 0)
{
//方法1: 直接在这里硬写所有的调用方法
//VoteAction(sender, gift, receiver);
//方法2: 采用事件的方式实现 ,将扩展点移到调用层实现
if (OnSendComplete != null)
OnSendComplete(sender, gift, receiver);
//方法3: 通过配置文件 + 接口的方式实现
}
return 0;
}
private int SendAction(int senderid, int giftid, int receverid) {
//测试用
Console.WriteLine("送礼成功了.");
return 1;
}
}
public class UserGift
{
public event SendGift OnSendComplete;
public UserGift() { }
public int Send(UserBase sender, GiftBase gift, UserBase receiver) {
bool flag = false;
//检查花的数量是否足够
//检查收件人的设置
//其他规则
//检查通过才开始送礼
int result = -1;
if (flag) result = SendAction(sender.UserId, gift.GiftId, receiver.UserId);
if (result > 0)
{
//方法1: 直接在这里硬写所有的调用方法
//VoteAction(sender, gift, receiver);
//方法2: 采用事件的方式实现 ,将扩展点移到调用层实现
if (OnSendComplete != null)
OnSendComplete(sender, gift, receiver);
//方法3: 通过配置文件 + 接口的方式实现
}
return 0;
}
private int SendAction(int senderid, int giftid, int receverid) {
//测试用
Console.WriteLine("送礼成功了.");
return 1;
}
}
客户端调用:
客户端调用
static void TestSend() {
//环境配置
UserBase sender = new UserBase() { UserId = 12345, UserName = "感恩的心" };
UserBase receiver = new UserBase() { UserId = 23456, UserName = "infozero" };
GiftBase gift = new GiftBase() { GiftId = 12, Name = "红玫瑰" };
UserGift ugift = new UserGift();
// 扩展功能点 1,2,3
ugift.OnSendComplete += new SendGift(ugift_OnSendComplete);
ugift.OnSendComplete += (s, g, re) => {
Console.WriteLine("扩展2。UserId:{0}",s.UserId);
};
ugift.Send(sender, gift, receiver);
}
static void ugift_OnSendComplete(UserBase sender, GiftBase gift, UserBase receiver)
{
Console.WriteLine("做额外的事情1。Receiver:{0}" , receiver.UserId);
}
//环境配置
UserBase sender = new UserBase() { UserId = 12345, UserName = "感恩的心" };
UserBase receiver = new UserBase() { UserId = 23456, UserName = "infozero" };
GiftBase gift = new GiftBase() { GiftId = 12, Name = "红玫瑰" };
UserGift ugift = new UserGift();
// 扩展功能点 1,2,3
ugift.OnSendComplete += new SendGift(ugift_OnSendComplete);
ugift.OnSendComplete += (s, g, re) => {
Console.WriteLine("扩展2。UserId:{0}",s.UserId);
};
ugift.Send(sender, gift, receiver);
}
static void ugift_OnSendComplete(UserBase sender, GiftBase gift, UserBase receiver)
{
Console.WriteLine("做额外的事情1。Receiver:{0}" , receiver.UserId);
}
我暂时想到的解决方法:
- 直接在业务逻辑层 Send 方法里硬写所有的调用方法;
- 采用事件的方式实现 ,将扩展点移到调用层(送礼那个动作中)实现;
- 通过配置文件 + 接口的方式实现(大致采用的方法类似于 这里 );
第一、二个方法中每次更改都要对原有的系统源代码进行修改-重新编译-发布-甚至是要引用扩展的 dll , 所以我倾向于采用第三种方法来实现程序的扩展,但是考虑到性能(此功能是整个系统的核心功能之一,使用的频率相对还是比较高的),对此有点犹豫;
求大家支招,还有什么比较好的办法没?