官术网_书友最值得收藏!

1.4 理解服務(wù)抽象

服務(wù)抽象指的是,對(duì)外部操作來(lái)說(shuō),一個(gè)類(lèi)向外部操作隱藏內(nèi)部工作的程度。應(yīng)該盡可能多地設(shè)置服務(wù)的屬性和方法為私有的,以阻止外部調(diào)用者對(duì)于服務(wù)中任何部分的無(wú)意操作。通過(guò)隱藏這些信息,我們促使應(yīng)用程序更加松耦合。

回顧代碼清單1.6中的例子,思考ShowDatabaseInfo類(lèi)和DisplayForm類(lèi)的交互方式。ShowDatabaseInfo直接給窗體中的標(biāo)簽賦值。

代碼清單1.8 直接給標(biāo)簽賦值


/// <summary>
/// Show the information to the user in the given form.
/// </summary>
public void ShowDataInForm(DisplayForm frm, ADODB.Recordset data)
{
  frm.UserFirstNameLbl.Text = data.Fields[0].ToString();
  frm.UserLastNameLbl.Text = data.Fields[0].ToString();
  frm.Show();
}

假設(shè)想讓窗體使用另一種不同類(lèi)型的控件(比如列表框)來(lái)顯示信息。窗體的這個(gè)改變并不影響ShowDatabaseInfo類(lèi)的邏輯,但是由于缺乏窗體的抽象,所以我們還是需要在該類(lèi)中更新代碼。

在不引入緊耦合的情況下同時(shí)允許這兩個(gè)類(lèi)進(jìn)行交互,這意味我們必須為這個(gè)窗體創(chuàng)建一個(gè)抽象,這樣的話,窗體就可以根據(jù)需求來(lái)改變,而依賴于該窗體的其他類(lèi)則無(wú)須做相應(yīng)改動(dòng)。服務(wù)抽象的理念使得類(lèi)能夠按需完善。請(qǐng)閱讀以下實(shí)現(xiàn)相同目的的抽象代碼。

代碼清單1.9 緊耦合類(lèi)的抽象版本


/// <summary>
/// This class will retrieve a string from the database and
/// display it on the screen.
/// </summary>
public class ShowDatabaseInfoAbstracted
{
  /// <summary>
  /// Main driver method
  /// </summary>
  public void GetAndShowData(int recordId)
  {
    ADODB.Recordset data = GetData();
    DisplayFormAbstracted frm = GetForm();
    ShowDataInForm(frm, data);
  }
  /// <summary>
  /// Open an ADO connection to Microsoft SQL Server,
  /// get the data, and return it.
  /// </summary>
  public ADODB.Recordset GetData()
  {
    var connection = new ADODB.Connection();
    connection.ConnectionString = "my connection string";
    connection.Open();
    var rs = new ADODB.Recordset();
    //The following query is specific to Microsoft SQL Server.
    //It will not execute properly on Oracle.
    rs.Open("Microsoft SQL Specific Query", connection);
    rs.ActiveConnection = null;
    return rs;
  }
  /// <summary>
  /// Get the proper form to use for our display.
  /// </summary>
  private DisplayFormAbstracted GetForm()
  {
    return new DisplayFormAbstracted();
  }
  /// <summary>
  /// Show the information to the user in the given form.
  /// </summary>
  public void ShowDataInForm(DisplayFormAbstracted frm, ADODB.Recordset data)
  {
    frm.UserFirstName = data.Fields[0].ToString();
    frm.UserLastName = data.Fields[0].ToString();
    frm.Show();
  }
}
/// <summary>
/// Form that displays the information to the user.
/// </summary>
public class DisplayFormAbstracted : Form
{
  /// <summary>
  /// This is private so it cannot be used by an outside
  /// consumer, thus improving the abstraction.
  /// </summary>
  private Label _userFirstNameLbl;
  private Label _userLastNameLbl;
  /// <summary>
  /// These getters and setters can change as the
  /// display requirements change, but the calling
  /// code will be unaffected.
  /// </summary>
  public string UserFirstName
  {
    get { return _userFirstNameLbl.Text; }
    set { _userFirstNameLbl.Text = value; }
  }
  /// <summary>
  /// These getters and setters can change as the
  /// display requirements change, but the calling
  /// code will be unaffected.
  /// </summary>
  public string UserLastName
  {
    get { return _userLastNameLbl.Text; }
    set { _userLastNameLbl.Text = value; }
  }
  /// <summary>
  /// Constructor that creates the data display form.
  /// </summary>
  public DisplayFormAbstracted()
  {
    _userFirstNameLbl = new Label();
    Controls.Add(_userFirstNameLbl);
    _userLastNameLbl = new Label();
    Controls.Add(_userLastNameLbl);
  }
}

這段代碼清單1.9和代碼清單1.6的不同之處在于DisplayFormAbstracted的定義。現(xiàn)在,它暴露的僅僅是用戶的名和姓的字符串屬性,而不是暴露整個(gè)標(biāo)簽。這有助于抽象化,因?yàn)榇绑w使用者不需要了解數(shù)據(jù)是如何顯示的。DisplayFormAbstracted可以變?yōu)槲谋究蚧蛘咂渌问剑襍howDatabaseInfoAbstracted類(lèi)無(wú)須改變。

主站蜘蛛池模板: 磐石市| 新闻| 潼关县| 正定县| 阿拉善盟| 宜黄县| 博兴县| 鄢陵县| 土默特右旗| 藁城市| 班戈县| 清远市| 宁武县| 井研县| 柳林县| 翁源县| 财经| 班戈县| 开阳县| 北宁市| 洞口县| 凤翔县| 新沂市| 濮阳市| 青神县| 前郭尔| 崇明县| 屏南县| 安岳县| 蒙山县| 慈利县| 聊城市| 义马市| 濮阳市| 德江县| 乐业县| 崇阳县| 竹山县| 新余市| 德惠市| 丘北县|