本篇文章来自于设计模式一书中的“生成器模式”

本篇中我们学习如何使用生成器模式从部件构建对象,假设我们不但需要一个用于计算的算法,还需要一个根据数据的不同而完全不同的用户界面,典型的例子就是E-mail地址薄,在地址薄中,即有个人信息也有组的信息,而用户希望能根据信息的不同,改变地址薄的显示, 这样在用户屏幕中能显示姓名、公司、E-mail地址和电话号码。另一方面,如果显示一个组的地址页,希望能看到组名、组的职能、成员表及他们的E-mail地址。单击一个人的时候得到一种显示方式,单击一个组的时候得到另一种显示方式。假设所有的E-mail地址都保存在Address类的一个对象里,个人和组都派生于这个基类,如下图。

设计模式-生成器模式

 

我们考虑一个简单一点的例子,编写一个程序来跟踪投资的效益。我们有股票、债券和基金等投资项目,对每一种投资项目都要显示特有量的列表。无论是对大数量的投资项目(如股票)还是小数量的投资项目(如基金)都有一种易于使用的显示方式。每种情况下我们都要一种多选显示,这样就能够选择一个或多个项目来标注。如果投资项目的数量大,可以使用一个多选的列表框显示;如果只有三个或更少的项目,则使用几个复选框来表示。让Builder类根据需要显示的项目个数生成界面,同时还要有相同的方法来返回结果。完整的类图如下。

设计模式-生成器模式

namespace BuilderPattern
{
    public interface IMultiChoice
    {
        ArrayList GetSelected();
        void Clear();
        Panel GetPanel();
    }
}

GetPanel方法返回一个包含多选显示的面板,这里使用两个显示面板实现该界面,一个是复选框,一个是列表框。

    public class ListChoice : IMultiChoice
    {
        private ArrayList Stocks;
        private Panel Panel;
        private ListBox List;

        public ListChoice(Equities stocks)
        {
            Stocks = stocks.GetNames();
            Panel = new Panel();

            List = new ListBox
            {
                Location = new Point(16, 0),
                Size = new Size(120, 160),
                SelectionMode = SelectionMode.MultiExtended
            };
            Panel.Controls.Add(List);

            foreach (var stks in Stocks)
                List.Items.Add(stks);
        }

        public ArrayList GetSelected()
        {
            var sel = new ArrayList();
            foreach (string str in List.SelectedItems)
                sel.Add(str);
            return sel;
        }

        public void Clear()
        {
            List.Items.Clear();
        }

        public Panel GetPanel()
        {
            return Panel;
        }
    }
列表选择界面

相关文章: