轉自:http://www.csframework.com/archive/2/arc-2-20110805-1771.htm
看似一個簡單的功能需求,其實很多初學者處理不好的,很多朋友會這麼寫:
//父窗體是是frmParent,子窗體是frmChildA
//在父窗體中打開子窗體
frmChildA child = new frmChildA();
child.MdiParent = this;
child.Show();
//子窗體調父窗體方法:
//錯誤的調用!!!!!!!!
(this.MdiParent as frmParent).ParentFoo();
知道錯在那裏嗎?錯在強依賴!如果父窗體與子窗體在同一個模塊內看似沒有錯,因爲這種反向引用在同一個模塊內是可行的,但程序不能這麼寫,你把它寫死了!固化了!假設我們的項目不斷在擴展,需要將父窗體與子窗體分開在不同的模塊,這段代碼就完了!因爲父窗體模塊必須引用子窗體模塊,而子窗體需要用到frmParent的類,又要引用父窗體的模塊!這時構成了雙向引用,編譯不能通過,所以講程序寫死了!
有什麼辦法解除這種依賴關係呢?辦法是有的,就是使用接口解除依賴關係!
我們把程序改下:
///<summary>
/// 主窗體接口
///</summary>
public interface IMdiParent
{
void ParentFoo();
}
///<summary>
/// 子窗體接口
///</summary>
public interface IMyChildForm
{
void Foo();
}
主窗體的代碼:
///<summary>
/// 主窗體,實現IMdiParent接口
///</summary>
public partial class frmParent : Form, IMdiParent
{
public frmParent()
{
InitializeComponent();
}
private void form1ToolStripMenuItem_Click(object sender, EventArgs e)
{
//打開子窗體
frmChildA child = new frmChildA();
child.MdiParent = this;
child.Show();
}
private void menuCallFoo_Click(object sender, EventArgs e)
{
//調用子窗體的Foo()方法
Form activedChild = this.ActiveMdiChild;
if ((activedChild != null) && (activedChild is IMyChildForm))
(activedChild as IMyChildForm).Foo();
}
#region IMdiParent 成員
public void ParentFoo()
{
MessageBox.Show("調用" this.GetType().FullName ".ParentFoo()方法!");
}
#endregion
}
//來源:C/S框架網(www.csframework.com) QQ:1980854898
子窗體的代碼:
///<summary>
/// 子窗體,實現IMyChildForm接口
///</summary>
public partial class frmChildA : Form, IMyChildForm
{
public frmChildA()
{
InitializeComponent();
}
#region IMyChildForm 成員
public void Foo()
{
MessageBox.Show("調用" this.GetType().FullName ".Foo()方法!");
}
#endregion
private void btnParentFoo_Click(object sender, EventArgs e)
{
//調用父窗體的ParentFoo()方法
if ((this.MdiParent !=null) && (this.MdiParentis IMdiParent))
(this.MdiParent as IMdiParent).ParentFoo();
}
private void btnErrCall_Click(object sender, EventArgs e)
{
//錯誤的調用
(this.MdiParent as frmParent).ParentFoo();
}
//來源:C/S框架網(www.csframework.com) QQ:1980854898
實現思路:
frmParent窗體所在的模塊依賴frmChildA所在模塊,而frmChildA只依賴IMdiParent接口,這正是《敏捷軟件開發》中所講的依賴倒置原則。最後,我們把IMdiParent接口部署在一個Common模塊內,實際上frmParent與frmChildA只需要依賴Common模塊。
點擊下載附件 (如下載失敗,請郵件通知我們寄回給您,或QQ:23404761留言.)