网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档

小总结:

所用技术:

01.C/S架构,数据存储在XML文件中

02.简单工厂模式

03.继承和多态

04.解析XML文档技术

05.深入剖析内存中数据的走向

06.TreeView控件的使用

核心:通过该项目,我们对业务流程有一个整体把控。对继承和多态有深入的了解

下面是类图:

主界面图:

核心思路:

 1   1.首先在频道管理类ChannelManager中写一个加载所有频道方法LoadAllChannel;
 2  
 3        该方法作用读取FullChannels.xml文件,并且将读取到的内容赋值给ChannelBase          对象。关键的问题就转化成了如何创建一个ChannelBase对象。我们都知道ChannelBase本身是一个抽象类,无法创建实例。由此,我们想到可以通过其子类来创建对象。由于不同子类实例化需要多次new,我们单独写了一个工厂类(ChannelFafactory),来创建子类实例,但是该子类实例存储在父类变量中。赋值完成后,我们需要将频道对象添加到字典中。那么
 4  
 5 LoadAllChannel方法结束后,字典中就有了XML文档中的数据。也就是我们实现了将
 6  
 7 本地硬盘上的xml文件中的数据读取到了内存中的一个字典集合中。

 9  
10 2.将集合中的数据绑定到TreeView中
11 将字典集合中的数据通过Foreach拆解,每循环一项,都创建一个TreeNode对象。
12 并且将集合中的属性赋值给节点对应的属性。然后将拼接处的节点添加到TreeView上
13 。这里需要注意的是,如何找到TreeView控件中的【所有电视台】这个节点,因为
14 我们需要在该节点上添加频道名称。代码如下:

1 在对应的频道子类中书写Fetch方法,解析对应的频道xml文件,然后将xml文件中的数据读取到 public List<TvProgram>  TvList { get; set; }中。
2     2.将TvList中的数据绑定到DataGridView上
3  
4 实现TreeView的右键菜单功能(能添加电台和删除电台)
5   核心思路:
6      1.添加电台

1 其实我们在做的事情就是先获取所有电台的某一个电台(北京电视台),然后通过
2 Tag属性拿到该电台对应的属性,将拆解出来的属性赋值给我的电台下的某一个
3 节点,由于节点不存在,所以我们要构造出一个节点。然后赋值,赋值完成后,我们就将构造出来的 节点添加到我的电台下就OK。
4  
5 当然,上面的操作仅仅是界面上新增电台的一个假象。程序再次运行时,我们添加的电台并没有保存。所以我们要将选中的电台添加到我的电台(由于我喜欢的电台可能有多个,所以我们定义了一个集合。)集合中。因为我们大家都知道集合中的数据时存储在内存中的,所以我们要向程序下次运行时,显示出我们添加的电台,那么就必须将集合中的数据永久保存。当然我们知道,永久保存数据的方法有很多,在这里我们采取的是使用txt文件的方式,所以我们书写了一个方法来帮我们完成这项工作,sw.WriteLine(“End”)主要为了方便后面对文本文件的读取

通过Visible属性控制右键菜单的显示和隐藏:

1 网络电视精灵后续思路
2 1.点击TreeView上某个电视台节点后,显示该频道下所有的节目单,
3 将节目单内容填充到DataGridView控件中。
4 思路分析:既然TypeAChannel:ChannelBase对应的北京电视台,那么我们需要找到保存
5 北京电视台中所有节目的xml文件,然后接续该xml文件,每一个<TvProgram>
6 节点都是一个节目单对象。我只需要将解析出的内容加载到集合中。集合中就存储了
7 一系列TvProgram对象,我只需要将该集合绑定到DataGridView上就OK了。
8
9 DgvList.DataSource=list;

下面是本人写的一些代码:

  1      ChannelManager manager = new ChannelManager();
  2         private void Form1_Load(object sender, EventArgs e)
  3         {
  4             lvTV.Visible = false;//让ListView控件隐藏
  5             dgvProgList.AutoGenerateColumns = false;//不自动产生英文列
  6             //1.加载我的电视台和所有电视台(TvChannel中的固定项)
  7             TreeNode myNode = new TreeNode();
  8             //点击该节点时,对应的图片改变
  9             myNode.SelectedImageIndex = 1;
 10             myNode.Text = "我的电视台";
 11
 12             TreeNode allNode = new TreeNode();
 13             allNode.SelectedImageIndex = 1;
 14             allNode.Text = "所有电视台";
 15
 16             //让节点和TreeView产生关系
 17             tvChannel.Nodes.Add(myNode);
 18             tvChannel.Nodes.Add(allNode);
 19
 20             //2.接下来我们需要读取 xml文件 获取所有电视台下的子节点
 21             //遍历集合中的每一项,然后拼接成一个TreeNode即可
 22
 23             manager.LoadAllChannel();
 24             Dictionary<string, ChannelBase> fullChannel = manager.FullChannel;
 25             foreach (ChannelBase channelBase in fullChannel.Values)
 26             {
 27                 //每遍历一次,都是一个频道,每一次都要创建一个TreeNode节点
 28                 TreeNode tn = new TreeNode();
 29                 tn.Text = channelBase.ChannelName;
 30                 //Tag
 31                 tn.Tag = channelBase;
 32
 33                 //找到所有电台节点,在所有电台的基础上增加子节点
 34                 tvChannel.Nodes[1].Nodes.Add(tn);
 35             }
 36
 37
 38
 39             //从txt文档将数据读取到集合中
 40             if (File.Exists("files/Save.txt"))
 41             {
 42                 manager.LoadFromTxt();
 43                 foreach (ChannelBase  item in manager.MyChannelList.ChannelList)
 44                 {
 45                     //每一项item都是一个TreeNode对象
 46                     TreeNode tn=new TreeNode();
 47                     tn.Text = item.ChannelName;
 48                     tn.Tag = item;
 49
 50                     myNode.Nodes.Add(tn);
 51                 }
 52             }
 53
 54             imageIcons.Images[0].Save("01.jpg");
 55             imageIcons.Images[1].Save("02.jpg");
 56
 57             //02.遍历集合拼接节点
 58
 59         }
 60
 61         //选中TreeView中国某个节点后执行的事件
 62         private void tvChannel_AfterSelect(object sender, TreeViewEventArgs e)
 63         {
 64             TreeNode tn = tvChannel.SelectedNode;//获取当前选中的节点对象
 65             //点击某个节点(必须是子节点:Level==1)
 66             if (tn!=null&&tn.Level==1)
 67             {
 68                 //发现是子节点,才获取到频道对象
 69                 ChannelBase channel = (ChannelBase) tn.Tag;
 70                 if (channel.TvList!=null)
 71                 {
 72                     channel.TvList.Clear();
 73                 }
 74                 channel.Fetch();
 75
 76                 //然后将tvList集合绑定到DGV上
 77                 dgvProgList.DataSource = channel.TvList;
 78             }
 79
 80         }
 81         //
 82         private void tvChannel_MouseClick(object sender, MouseEventArgs e)
 83         {
 84             TreeNode node = tvChannel.SelectedNode;
 85             if (node!=null&&node.Level==1)//选中了电视台节点
 86             {
 87                 if (node.Parent.Text=="我的电视台")
 88                 {
 89                     cmenuRight.Items[0].Visible = false;
 90                     cmenuRight.Items[1].Visible = true;
 91                 }
 92                 else
 93                 {
 94                     cmenuRight.Items[0].Visible = true;
 95                     cmenuRight.Items[1].Visible = false;
 96                 }
 97             }
 98             else
 99             {
100                 //如果选中节点为父节点,那么添加、删除菜单项都不显示
101                 cmenuRight.Items[0].Visible = false;
102                 cmenuRight.Items[1].Visible = false;
103             }
104
105         }
106         //加入我的电台
107         private void tsmAddToFavor_Click(object sender, EventArgs e)
108         {
109             //如何将电台从所有电台加载到我的电台
110             //01.获取选中项
111             TreeNode tn = tvChannel.SelectedNode;
112             if (tn==null)
113             {
114                 return;
115             }
116             //02.判断我的电台下是否已经存在你要加入的电台
117             foreach (TreeNode child in tvChannel.Nodes[0].Nodes)
118             {
119                 if (child.Text==tn.Text)
120                 {
121                     return;
122                 }
123             }
124             //03.真正加入节点到我的电台下
125             //把当前选中的节点的Tag属性取出来,转换成ChannelBase
126             ChannelBase channel=(ChannelBase) tn.Tag;
127             //04.将channel对象添加到我的电台下成为我的电台的一个节点
128             TreeNode node=new TreeNode();
129             node.Text = channel.ChannelName;
130             node.Tag = channel;
131             tvChannel.Nodes[0].Nodes.Add(node);
132             //04.将channel加入到集合中
133             manager.MyChannelList.ChannelList.Add(channel);
134             //05.如果集合在main 中,那么将集合中数据写入文本文件的时候比较麻烦
135             //所以我们将集合和SaveToTxt方法都写入了ChannelManager类
136             manager.SaveToTxt();
137         }
138
139         //从我的电台中删除
140         private void TMenuItemDel_Click(object sender, EventArgs e)
141         {
142             //01.先获取我的电台下要删除的电台
143             //02.从Tv上移除
144             //03.从集合中移除
145             //04.SaveToTxt()
146
147         }
148         //播放视频
149         private void tsmPlay_Click(object sender, EventArgs e)
150         {
151            string path= dgvProgList.SelectedRows[0].Cells[3].Value.ToString();
152             FrmPlay frm=new FrmPlay();
153             frm.mypath = path;
154             frm.Show();
155             frm.Play();
156         }

父类:

 1  /// <summary>
 2     /// 频道基类
 3     /// </summary>
 4    public abstract class ChannelBase
 5     {
 6        //频道名称
 7         public string ChannelName { get; set; }
 8         //频道路径
 9         public string  Path { get; set; }
10        //频道类型
11        public string Type { get; set; }
12        //节目列表,该频道上的所有节目列表
13         public List<TvProgram>  TvList { get; set; }
14         //获取频道列表:通过Fetch方法获取该频道拥有的所有节目列表
15         public abstract void Fetch();
16
17     }

A频道
 1 //解析北京电视台中所有的节目单集合
 2         public override void Fetch()
 3         {
 4             //既然我们已经拿到了所有的频道,只需要加载对应频道下节目就OK
 5             //将硬盘中xml文件的数据读取到了泛型集合中(内存中)
 6             XmlDocument doc=new XmlDocument();
 7             doc.Load(Path);
 8             if (TvList==null)
 9             {
10                 TvList=new List<TvProgram>();
11             }
12             XmlElement root = doc.DocumentElement;
13             foreach (XmlNode item in root.ChildNodes)
14             {
15                 if (item.Name == "tvProgramTable")
16                 {
17                     //
18                     foreach (XmlNode tn in item.ChildNodes)
19                     {
20                         TvProgram program=new TvProgram();
21                         program.PlayTime=Convert.ToDateTime(tn["playTime"].InnerText);
22                         program.Name = tn["programName"].InnerText;
23                         program.ShiDuan = tn["meridien"].InnerText;
24                         program.Path = tn["path"].InnerText;
25
26                         TvList.Add(program);
27                     }
28                 }
29             }
30         }

B频道

 1  public class TypeBChannel:ChannelBase
 2     {
 3         public override void Fetch()
 4         {
 5             XmlDocument doc = new XmlDocument();
 6             doc.Load(Path);
 7             if (TvList == null)
 8             {
 9                 TvList = new List<TvProgram>();
10             }
11             XmlElement root = doc.DocumentElement;
12             foreach (XmlNode item in root.ChildNodes)
13             {
14                 foreach (XmlNode tn in item.ChildNodes)
15                 {
16                     TvProgram program = new TvProgram();
17                     program.PlayTime = Convert.ToDateTime(tn["playTime"].InnerText);
18                     program.Name = tn["name"].InnerText;
19
20                     program.Path = tn["path"].InnerText;
21
22                     TvList.Add(program);
23                 }
24             }
25         

传递类

 1 public class ChannelManager
 2     {
 3         private const string channelPath = "files/Fullchannels.xml";
 4         public ChannelManager()
 5         {
 6             this.fullChannel = new Dictionary<string, ChannelBase>();
 7             this.myChannelList=new SavingInfo();
 8         }
 9         //所有频道列表(string:名称   ChannelBase:频道父类)
10         private  Dictionary<string, ChannelBase> fullChannel;
11         public Dictionary<string, ChannelBase> FullChannel
12         {
13             get { return fullChannel; }
14             set { fullChannel = value; }
15         }
16
17         public SavingInfo MyChannelList
18         {
19             get { return myChannelList; }
20             set { myChannelList = value; }
21         }
22
23         //保存我的电台
24         private SavingInfo myChannelList;
25         //加载所有频道
26         public void LoadAllChannel()
27        {
28            XmlDocument doc=new XmlDocument();
29            doc.Load(channelPath);
30            //获取根节点
31             XmlElement root=doc.DocumentElement;
32
33             foreach (XmlNode item in root.ChildNodes)
34             {
35                 //加上注释!@@@@
36               ChannelBase channel= ChannelFactory.CreateChannel(item["channelType"].InnerText);
37                 foreach (XmlNode xmlNode in item.ChildNodes)
38                 {
39
40                     switch (xmlNode.Name)
41                     {
42                         case "tvChannel":
43                            channel.ChannelName= xmlNode.InnerText;
44                             break;
45                         case "path":
46                             channel.Path = xmlNode.InnerText;
47                             break;
48                         case "channelType":
49                             channel.Type = xmlNode.InnerText;
50                             break;
51                     }
52                 }
53                 fullChannel.Add(channel.ChannelName,channel);
54             }
55
56        }


 1  //简单工厂
 2     public static class ChannelFactory
 3     {
 4         public static ChannelBase CreateChannel(string type)
 5         {
 6             ChannelBase channel=null;
 7             switch (type)
 8             {
 9                 case "TypeA":
10                     channel = new TypeAChannel();
11                     break;
12                 case "TypeB":
13                     channel = new TypeBChannel();
14                     break;
15             }
16             return channel;
17         }
18     }


1  //节目类
 2    public class TvProgram
 3     {
 4        //播出时间
 5         public DateTime  PlayTime{ get; set; }
 6        // 早间档,午间档,晚间档
 7         public string ShiDuan { get; set; }
 8         public string Name { get; set; }
 9         //视频路径
10         public string Path { get; set; }
11     }
 1 public class SavingInfo
 2     {
 3        //构造函数
 4        public SavingInfo()
 5        {
 6            this.ChannelList=new List<ChannelBase>();
 7        }
 8
 9        //我的收藏:定义了一个泛型集合,保存我的电台下所有的频道
10        private List<ChannelBase> channelList;
11
12        public List<ChannelBase> ChannelList
13        {
14            get
15            {
16                return channelList;
17            }
18            set { channelList = value; }
19        }
20     }

完结待续。。。。。。。。。。。。。。。。

时间: 2024-12-14 05:34:18

网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档的相关文章

结合实例分析简单工厂模式&amp;工厂方法模式&amp;抽象工厂模式的区别

之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略.这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处.工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类.也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口

Android解析XML文档的两种方式的简单对比

Android之所以会用到解析XML文档,不仅与JAVA对XML的解析比较简单,而且还因为XML是Android在网络间传递信息的主要存储方式.下面我简单谈谈Android对XML文档解析的两种方式:dom和sax.dom解析方式是,解析方法将一个XML文件看成是一棵树.由数据结构的知识我们知道对树的处理比较简单,就是对树的节点进行增,删,改,查,这也是dom的一个最大优点.但是,dom方式在解析的时候是一次性就将整个XML文档读进内存,这坏处不用我说了吧,我宝贵的内存是禁不起这么折腾的. sa

简单工厂模式&amp;工厂方法模式&amp;抽象工厂模式的区别

之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略.这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处.工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类.也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口

iOS设计模式(代码分析系列2:简单工厂模式)

简单工厂模式示例代码下载地址, 1.简述 首先需要说明一下,简单工厂模式不属于23种GOF设计模式之一.它也称作静态工作方法模式,是工厂方法模式的特殊实现(也就是说工厂模式包含简单工厂模式).这里对简单工厂模式进行介绍,是为后面的工厂方法和抽象工厂模式做一个引子. 2.定义 "专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类." 世界上就是由一个工厂类,根据传入的参数,动态地决定创建出哪一个产品类的实例. 3.结构图 简要分析结构图: ConcreteProduct

完整案例分析再加知识整合——艾特简单工厂模式,超详细的

简单工厂模式 一.模式动机与定义 模式动机 只需要知道水果的名字即可得到相应的水果 模式定义 简单工厂模式(Simple Factory Pattern):又称为静态工厂方法模式,它属于类创建型模式. 在简单工厂模式中,可以根据参数的不同返回不同类的实例. 简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 二.模式结构与分析 模式结构 简单工厂模式包含如下角色: Factory:工厂角色 Product:抽象产品角色 ConcreteProduct:具体产品角

简单工厂模式的介绍、优缺点分析和解决方案

所有的模式都是利用java中的封装.继承.多态这三个特性张开的,就像由这三个秘籍组成的各种变幻万千的招式,而所有的目的都是为了打败坏模式带来的代码垃圾这个敌人,所有的招式都是要求“可维护”.“可扩展”.“可复用”,当然如果达到这三个标准后,基本上“灵活性好”同时也就拥有了. 所以下面介绍最常用的工厂模式,分为三类:简单工厂模式.工厂模式和抽象工厂模式. 一.简单工厂模式 1.介绍 工厂模式,顾名思义,最少有一个生产产品的机器存在的工厂Factory,与此同时,也要有一个构建好的产品模块Produ

简单工厂模式( Simple Factory Pattern )

1. 简单工厂模式( Simple Factory Pattern ) 1.1. 模式动机 考虑一个简单的软件应用场景,一个软件系统可以提供多个外观不同的按钮(如圆形按钮.矩形按钮.菱形按钮等), 这些按钮都源自同一个基类,不过在继承基类后不同的子类修改了部分属性从而使得它们可以呈现不同的外观,如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的名字,只需要知道表示该按钮类的一个参数,并提供一个调用方便的方法,把该参数传入方法即可返回一个相应的按钮对象,此时,就可以使用简单工厂模式. 1.2

JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)

在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象. 在这些情况,新对象的建立就是一个 "过程",不仅是一个操作,像一部大机器中的一个齿轮传动. 模式的问题:你如何能轻松方便地构造对象实例,而不必关心构造对象实

(转)设计模式(五)简单工厂模式+工厂方法模式

在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象. 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动. 模式的问题:你如何能轻松方便地构造对象实例,而不必关心构造对象实例的细节和