`

封装一个树形菜单一——类设计

 
阅读更多

[我有废话要说]
     PA的U。M界面的树也是我封装的,做这个功能的时候,我希望它可以像smart-gwt的treeGrid一样好用。

     不过我不会C#,也第一次写ASP控件,还想让他像treeGrid……在这个难度上,我想再加点,把我的树写的通用又好维护,于是我决定好好设计,加入设计模式的思想:)
[正文——封个控件来画树]

  需求:

    领导说写个读取XML配置,让后封装成树,在界面上展示出来。

    我是个画蛇添足的程序员,我想分两步完成,希望这个题目能两天就写完。

第一步:

    从XML解析一棵树,放到tree中。并且考虑:如果XML格式变了、如果不从XML取数据库……要让我的代码尽量满足开闭原则。

第二步:

    做一个渲染树的控件,将这个树丢到控件中,树就画出来了,可以多列。

 

开始干活:

我的树的设计

 

读数的类图第一版

 

用户通过工厂类得到一个XML工厂。

XMLTreeReader工厂解析XML文件,把XML配置的指定解析自己的ITreeReader返回。(比如扁平或层级的表示树形的XML文件)

ITreeReader一拿到就可以开始干活了,ITreeReader解析xml的节点,把数据封装到树结构ITreeNode中。

这里需要注意的是:ITreeNode表示一个树的树根节点,有节点的属性,还有子节点。因此ITreeReader解析时候,需要创建子节点,也就是ITreeNode对象。而ITreeNode是接口,不能new出来,所以ITreeReader需要知道ITreeNode的实现类,于是我传入ITreeReader一个ITreeNode的实现类,反射来创建对象。

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace com.Origin.Base.test.mywork.Tree
{
    public interface ITreeReaderFactory
    {
        ITreeReader createTreeReader();
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace com.Origin.Base.test.mywork.Tree
{
    public class XMLTreeRreaderFactory:ITreeReaderFactory
    {
        private string xmlPath {set;get; }
        public XMLTreeRreaderFactory(string path) 
        {
            xmlPath = path;

        }
        public ITreeReader createTreeReader()
        {

            //解析xmlPath路径下的xml文件,根据XML配置取得解析该XML对应的类,反射回去.

            //这里把解析XML的一段省略了先,直接写死读到了xml配置的类:
            string className = "com.Origin.Base.test.mywork.Tree.SimpleTreeReader";
            Type type = Type.GetType(className);
            Console.WriteLine("    解析XML的类:" + type);
            ITreeReader reader = (ITreeReader)type.Assembly.CreateInstance(className);
            return reader;
        }
    }
}
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace com.Origin.Base.test.mywork.Tree
{
    public interface ITreeReader
    {
        ITreeNode createTree();

    }
}
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace com.Origin.Base.test.mywork.Tree
{
    public class SimpleTreeReader:ITreeReader

    {
        private static string DEFAULT_NODE_CLASS = "com.Origin.Base.test.mywork.Tree.MyTreeNode";
        private string treeNodeClassName { set; get; }
        public ITreeNode createTree() 
        {
            ITreeNode treeNode = createNode();
            //根据XML的结构,解析XML文件,封装到ITreeNode的对象中,返回

            //这里不读取XML了,直接用假数据封装下。
            treeNode.putAttribute("name"," 用户管理");
            treeNode.putAttribute("url"," /userManage.html");

            //创建子树
            ITreeNode subNode = createNode();
            subNode.putAttribute("name", "创建用户");
            subNode.putAttribute("url", " /createUser.html");
            treeNode.addSubNode(subNode);

            return treeNode;
        }

        private ITreeNode createNode()
        {
            if (treeNodeClassName == null) 
            {
                treeNodeClassName = DEFAULT_NODE_CLASS;
            }
            //再次用到反射
            Type type = Type.GetType(treeNodeClassName);
            ITreeNode treeNode = (ITreeNode)type.Assembly.CreateInstance(treeNodeClassName);
            return treeNode;
        }
    }
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace com.Origin.Base.test.mywork.Tree
{
    public abstract class ITreeNode
    {
        protected IList<ITreeNode> subNodes { get; set; }
        //设置当前节点的key-value对
        public abstract void putAttribute(object key, object value);
       
        //根据key得到对应的值
        public abstract object getAttribute(object key);
       
        //为当前节增加一个子节点,在它的节点的下一级节点的末尾增加
        public abstract void addSubNode(ITreeNode node);
        public abstract IList<ITreeNode> getSubNodes();
    }
}
 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections;
namespace com.Origin.Base.test.mywork.Tree
{
    public class MyTreeNode : ITreeNode
    {
        private Hashtable attributes = new Hashtable();
        //设置当前节点的key-value对
        public override void putAttribute(object key, object value)
        {
            attributes.Add(key,value);
        }

        //根据key得到对应的值
        public override object getAttribute(object key)
        {
            if (attributes.Contains(key))
            {
                return attributes[key];
            }
            else 
            {
                return null;
            }
        }

        //为当前节增加一个子节点,在它的节点的下一级节点的末尾增加
        public override void addSubNode(ITreeNode node) 
        {
            if (subNodes == null) 
            {
                subNodes = new List<ITreeNode>();
            }
            subNodes.Add(node);
        }
        public override IList<ITreeNode> getSubNodes()
        {
            return subNodes;
        }
    }
}

 

 看看client调用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.Origin.Base.test.mywork.Tree;
namespace ConsoleApplication1
{
    class Program
    {
        private ITreeReaderFactory factory = new XMLTreeRreaderFactory(@"D:\\menu.xml");

        public ITreeNode fetchTreeNode()
        {
            ITreeNode root = null;
            ITreeReader reader =  factory.createTreeReader();
            root  = reader.createTree();
            return root;
        }
        static void Main(string[] args)
        {
            Console.WriteLine("start...");
            Program p = new Program();
            ITreeNode root = p.fetchTreeNode();
            string tab ="";
            printTree(root, tab);
          
            Console.ReadLine();
        }

        public static void printTree(ITreeNode node,string s)
        {
            s = "  " + s;
            Console.WriteLine(s + "NAME = " + node.getAttribute("name") + "  url = " + node.getAttribute("url"));

            IList<ITreeNode> subNodes = node.getSubNodes();
            if (subNodes == null) 
            {
                return;
            }
            for (int i = 0; i < subNodes.Count; i++)
            {
                 printTree(subNodes[i],s);

            }
        
        }
    }
}
 

  输出:

分享到:
评论
2 楼 zws466460939 2013-12-19  
  [color=orange][/color]:!:
1 楼 zws466460939 2013-12-19  
:c4564ry:456 

相关推荐

Global site tag (gtag.js) - Google Analytics