我有以下简单的功能:
private void EnableDisable941ScheduleBButton()
{
if (this._uosDepositorFrequency.Value != null)
this._btnScheduleB.Enabled = ((int)this._uosDepositorFrequency.Value == 0);
}
它是Winform类的成员,我试图将其拆分为被动视图和演示者。很明显,业务逻辑与UI布线纠缠在一起。我只是不确定将它们分开的最佳方法。
为了给出一点上下文,该函数从表单中的三个位置调用。 _uosDepositorFrequency是一个只有两个按钮的单选按钮组。
有什么想法吗?
更新
好吧,也许它没有我想象的那么明显。业务规则规定,如果雇主进行半周存款(_uosDepositorFrequency.Value = 0),则需要填写附表B表格。
答案 0 :(得分:2)
主讲人:
if(this._uosDepositorFrequency.Value > 0) //int objects cannot be null
ViewData["ScheduleBRequired"] = true;
查看:
private void Draw()
{
if ((bool)ViewData["ScheduleBRequired"]){
this._btnScheduleB.Enabled = true;
this._validatorScheduleB.Active = true; //required data should be checked clientside with js
}
}
如果是商业要求,应该填写,应该由演示者触发。 ui负责遵循演示者的决定。例如是否要求附表B ....
答案 1 :(得分:0)
我认为这不是商业逻辑。它看起来像我的UI逻辑。我不会改变它。
虽然如果我使用wpf,我会将启用状态绑定到数据。
答案 2 :(得分:0)
也许我错过了什么,但我不确定我是否在那里看到了业务逻辑。您只是根据表单上的其他控件是否具有值来启用/禁用按钮。我没有看到需要重构这个方法,这对我来说都是逻辑。
答案 3 :(得分:0)
听起来你正在将UI逻辑和业务规则混为一谈。你拥有的代码是UI逻辑,不应该重构。您说的业务规则是,如果_btnScheduleB
的值为0
,那么您需要让用户填写表单。您的业务逻辑应该是确保在用户可以继续之前启用_btnScheduleB
时填写完整的表单。
答案 4 :(得分:0)
一个替代方案(我并不是说它是一个更好的方法)是让无线电控件的选择更改事件更新模型(雇主实体?),这反过来触发了某种类型的DepositorChanged事件,即UI相应地订阅并启用/禁用计划按钮。观察者模式,或多或少。
也就是说,上面的替代方案产生了更多的复杂性,我建议将其留给UI代码(添加关于它的注释或使用中间布尔变量来向读者陈述意图)。特别是如果这是规则被使用的唯一地方。
关于代码的附注:在使用下划线为类字段添加前缀或使用this.
之间进行宗教辩论。我想每个人都同意使用两者都是多余的......
答案 5 :(得分:0)
正如其他人所指出的那样,这样可以保持UI的一致性,因此实际上不是业务逻辑。你可以删除这样的空检查。
this._btnScheduleB.Enabled = (int)(this._uosDepositorFrequency.Value ?? 0) == 0;
答案 6 :(得分:0)
我不会太担心重构2行代码,除非真的在当前格式中没有意义。
答案 7 :(得分:0)
首先,我要感谢所有回答我问题的人。
我花了一些时间研究这个问题,我相信我已经找到了解决方案。
首先我将_uosDepositorFrequency.Value和_btnScheduleB.Enabled公开为公共属性并更新视图界面我还花了一些时间来定义存款频率的枚举。
public bool EnableScheduleB
{
get
{
return _btnScheduleB.Enabled;
}
set
{
_btnScheduleB.Enabled = value;
}
}
public DepositFrequency DepositorFrequency
{
get
{
return (DepositFrequency)_uosDepositorFrequency.Value;
}
set
{
_uosDepositorFrequency.Value = (int)value;
}
}
然后我将原始函数的主体复制到我的演示者并修改它以使用我刚刚创建的属性。原始函数中的空值检查结果是不必要的,因为_uosDepositorFrequency控件在其他地方初始化。
public void UpdateScheduleBStatus()
{
ReturnView.EnableScheduleB = ReturnView.DepositorFrequency == DepositFrequency.Semiweekly;
}
最后更新_uosDepositorFrequency_ValueChanged事件处理程序以调用UpdateScheduleBStatus。
private void _uosDepositorFrequency_ValueChanged(object sender, System.EventArgs e)
{
Presenter.UpdateScheduleBStatus();
}
欢迎评论。