实体类的变形【1】—— 餐盘原理

 

    在亚历山大同学的post里面我说可以让实体类和表不必一一对应,但是并没有详细说明如何来做,也有人想问我是怎么做的,那么我就说一下。先说一个简单一点的,那就是在网页里面显示列表数据的情况,其他的下次再说。我们先来看一个生活中的情况,然后再说程序里面如何来做。

 

餐盘原理——模糊对应

 

     餐盘,大家去食堂吃饭的时候,是不是会用一个长方形的餐盘来盛饭和菜呢?长方形的餐盘里有一个大一点的长方形的阁子,可以用来盛饭,当然也可以放馒头、花卷、面条等;有两、到四个个小一点的阁子,可以盛菜;由一个圆形的阁子可以放小碗;还有一个细长的可以放筷子。

     无论食堂做什么饭菜,我们都是用这个餐盘来盛的。这个餐盘既可以放鸡蛋炒黄瓜、烧茄子、黄花鱼还可以放宫保鸡丁等。一个餐盘应对了好多种菜。

     

     餐盘规定了有几个阁子,阁子里面可以放食物,但是并没有规定阁子里面必须放什么食物,阁子里面到底放什么食物就是一种模糊的对应关系。

     好了让我们回到程序中来,假设我们要仿照博客园的社区来做一个小程序。社区里面有新闻、小组、博文、闪存、博友等内容,假设数据库里面有这几个表:cmt_News_NewsInfo(存放新闻内容)、cmt_Group_topic(小组里面的话题)、cmt_FAQ_Questions(存放博友提问)、cmt_Flash_FlashInfo(存放闪存内容)

 

     如果现在我们想要做一个社区首页,要如何设置实体类呢?按照我对OO的一知半解,我可能会设计下面这几个类,这几个类都是和表(或者是视图)一一对应的。不管和谁对应,并不是重点。

 

public class Group_topic
 {
  public string Topic;  //话题名称
  public string TopicURL;  //话题的连接地址
  public string Group;  //话题所属小组
  public string GroupURL;  //小组的连接地址
  public string View;   //回应/浏览
  public string SendDate;  //话题发表日期
  public string Author;  //作者姓名
  public string AuthorURL; //作者的连接地址
   
 }

 public class FlashInfo
 {
  public string Author;  //作者姓名
  public string AuthorURL; //作者的连接地址
  public string Message;  //闪存的内容
  public string SendDate;  //话题发表日期
  public string ToAuthor;  //to 作者姓名
  public string ToAuthorURL; //to 作者的连接地址
  
 }

public class Group_Lesson
 {
  public string GroupName; //小组名称
  public string GroupURL; //小组名称
  public string GroupImage; //小组名称
  public string MembersCount; //成员数量
   

 }

 

其他的就省略了。

     不知道这么设计对不对,先假设这么设计是对的吧,那么由于属性不同,就需要设计多个不同的实体类,给实体类赋值的部分也要写多个,业务逻辑的部分也要针对各个实体类的属性名称来编写,UI也要根据实体类的属性名称来取值。

我们来看看程序的步骤:

 

1、定义实体类。有几个“列表”就要定义几个实体类。
2、给实体类赋值。由于是多种实体类,那么给实体类赋值就有点麻烦,不能用一个函数搞定,当然我们可以请来ORM帮忙。但是ORM的使用也并不是很轻松。
3、业务逻辑的处理。依据业务需求对实体类的属性名称来做处理。
4、显示数据。依据页面布局和实体类的属性名称来提取数据。

     这样各个部分都和实体类的属性名称发生了关联(这个就是内容耦合吧?),如果这时候字段名称发生了变化,那么每个部分都要做些修改。而修改的原因仅仅是实体类的属性名称变化了。

 

     这样设计实体类对吗?面向对象,一切皆为对象,见到猫猫了就 class cat, 见到狗狗了就 class dog,见到新闻就 class News。真的有这么简单吗?面向对象的精华是“抽象”吧?猫和狗可以抽出来一个class Animals,那么这么做抽象的依据是什么呢?往往被忽略了。

 

     请注意:我们讨论的前提和目的:在网页里面显示列表性质的数据,这个例子的要求:实现社区的首页。

首页里面是最新的新闻、最新的小组话题、最新的问题等。那么我们是不是要根据这个要求来进行一下抽象呢?

要显示最新(最多的、最高的等)的n条数据,有“名称”、连接、点击量、介绍等。那么是不是可以根据这个来抽象呢?

您可能会眼前一亮,对呀,设计一个基类,然后派生出四个子类对应新闻、博文、小组话题等。

比如这样 class WebDataList {}

 

     这样是抽象了,但是其实还是多种不同的实体类,对上面的步骤不会有什么的改进和帮助。

那么到底要如何来做呢呢?想想上面的餐盘,我们是不是可以设置一个这样的“通用”实体类?(请注意通用的范围:网页里的列表数据的显示)
 

/// 一般的列表
 public struct TitleBase
 {
  /// 0 记录的主键ID
  public string ID;   //
  /// 1 链接地址,用于静态页或者URL重写
  public string URL;   //
  /// 2 全部标题
  public string AllTitle;  //
  /// 2 限制字数的标题
  public string Title;  //
  /// 3 发表时间
  public string AddedDate; //
  /// 4 简介内容
  public string Introduction; //
  /// 5 备用1。人气
  public string Other1;     //
  /// 6 备用2。图片路径
  public string Other2;     //
  /// 7 备用3。
  public string Other3;     //
 }

     这是一个固定的“实体类”,他的属性名称是固定的,这样做有什么优点呢?

 

1、只需要定义一个实体类就可以了,实体类的数量不会根据网站(列表页面)的扩展而扩展。
2、给实体类赋值的函数只写一个就可以了,不同的列表只需要修改SQL语句即可。
3、由于实体类的属性名称是固定的,这样如果只是字段名称修改了,那么只需要改一下SQL语句即可,其他的代码都不需要修改。

 

缺点:有优点就会带来点缺点。

1、有浪费的嫌疑,由于属性的数量是固定的,有的时候并不需要这么多,那么多出来属性的就浪费了。
2、需要写一个属性名和字段名的对应关系的说明(约定),各个部分按照这个约定行事。这个应该属于文档的一部分吧。
3、SQL语句的编写有一定的要求:SQL语句里的字段数必须是8个,而且字段的顺序必须要对好。
4、只适合网站的列表型数据的显示,因为一般这样的数据字段比较类似,字段数量也比较少,8个属性可以应对。

 

代码实现

 

定义实体类,

实现填充数据的help
定义数据层
定义业务逻辑层
定义UI层

 

 

Code
public TitleBase[] LoadTitleBase(int Count,string sql)
        {
            //int Count = 10 ;    //显示最新的10条小组话题
            //string sql = "";

            TitleBase[] tmp = new TitleBase[Count];

            SqlConnection cn = new SqlConnection();
            SqlCommand cm = new SqlCommand (sql,cn);
            cn.Open();

            SqlDataReader dr = cm.ExecuteReader();
            int i = 0;
            while (dr.Read())
            {
                tmp[i].ID = dr[0].ToString();
                tmp[i].URL = dr[1].ToString();
                tmp[i].Title  = dr[2].ToString();
                tmp[i].AddedDate  = dr[3].ToString();
                tmp[i].Introduction  = dr[4].ToString();
                tmp[i].Other1  = dr[5].ToString();
                tmp[i].Other2  = dr[6].ToString();
                tmp[i].Other3  = dr[7].ToString();
 
                i++;
            }

            return tmp;

        }

        /// <summary>
        /// 数据层
        /// </summary>
        /// <returns></returns>
        public TitleBase[] Get_top10_Group_topic()
        {
            //                            ID            URL      Title   AddedDate Introduction  Other1  Other2  Other3
            string sql = "select top 10 TopicURL,GroupURL,Topic,  SendDate,  Group,       View,   Author, AuthorURL from cmt_Group_topic order by SendDate desc "; //SQL语句略
            return  LoadTitleBase(10, sql);
        }

        /// <summary>
        /// 逻辑层
        /// </summary>
        /// <returns></returns>
        public TitleBase[]  Top10_Group_topic()
        {
            TitleBase[] tmp;
            tmp = Get_top10_Group_topic();
            //逻辑处理
            return tmp;
            
        }

        /// <summary>
        /// UI
        /// </summary>
        private void LoadData()
        {
            TitleBase[] Group_topic ;
            Group_topic = Top10_Group_topic();

            //数据绑定
        }

}

 

 

简化的写法

 

 

private void MyLoadData()
        {
            TitleBase[] Group_topic ;

            //                            ID            URL      Title   AddedDate Introduction  Other1  Other2  Other3
            string sql = "select top 10 TopicURL,GroupURL,Topic,  SendDate,  Group,       View,   Author, AuthorURL from cmt_Group_topic order by SendDate desc "; //SQL语句略
            
            Group_topic =  LoadTitleBase(10, sql);

            //逻辑处理

            //数据绑定

        }

 

 

直接在.aspx.cs文件里面写上面的代码。

 

 SQL语句的处理。
SQL语句可以放在一个单独的类里面统一管理,也可以放在xml文件里面动态加载。这样是不是变成了传说中的依赖注入呢?

 

 

 

时间: 2024-07-29 09:40:42

实体类的变形【1】—— 餐盘原理的相关文章

实体类的变形【2】—— 行列转换

     上次说了一下在网页里面显示列表数据的情况,这个应用范围太小了,添加.修改怎么办呢?网站的后台管理.OA.CRM等怎么办?还是这样处理显然是不行的.   我们还是看一个小例子,这回是数据库设计的.   假设我们要做一个小学的成绩单,设计一个成绩表 小学生成绩表 字段:学生名称.语文成绩.数学成绩.美术成绩等. 小学里的课程是有限的,就那么几个,都作为字段放在表里面就ok了. 如果我们现在要做一个中学的成绩单呢?物理.化学.生物.地理.历史课程增加了不少,还是往用往表里面增加字段的方式吗?

【实体类变形】—— 元数据(另类ORM) 描述字段的数据

       放假了,不知道有没有加班的,先祝大家国庆节快乐!      上次说得有点乱,"行列转换"这个词可能误导了大家,那么把这个词扔掉吧.我们重新开始.假设我们有一个News表,我们要往里面添加数据,我们先只考虑保存数据的部分. 一.我们定义一个类.变形的"实体类"  public class ColumnsInfoBase            {         #region 字段的基本信息的描述         /// <summary>

掌握 ASP.NET 之路:自定义实体类简介

asp.net 摘要:有些情况下,非类型化的 DataSet 可能并非数据操作的最佳解决方案.本指南的目的就是探讨 DataSet 的一种替代解决方案,即:自定义实体与集合.(本文包含一些指向英文站点的链接.) 本页内容引言 DataSet 存在的问题 自定义实体类 对象关系映射 自定义集合 管理关系 高级内容 小结 引言ADODB.RecordSet 和常常被遗忘的 MoveNext 的时代已经过去,取而代之的是 Microsoft ADO.NET 强大而又灵活的功能.我们的新武器就是 Sys

hql语句查询实体类News的属性category为“生活类新闻”的LIST,HQL语句怎么写?

问题描述 hql语句查询实体类News的属性category为"生活类新闻"的LIST,HQL语句怎么写? 用SSH框架,写一个实现类,查询实体类News的属性category为"生活类新闻"的LIST 返回一个LIST,该怎么写???????????????????? 实体类为News 属性为category 数据库中表名为t_news category为属性 import java.util.List; import org.springframework.st

hashmap-ListView 里面嵌套了一层ListView 如何写实体类呢

问题描述 ListView 里面嵌套了一层ListView 如何写实体类呢 左边的是别人用HashMap写的 右边是我想换成封装成实体类的时候 提示不能获取id 请问如何获取呢

ssh框架web,自动生成hbm.xml和实体类

问题描述 ssh框架web,自动生成hbm.xml和实体类 ssh框架web,数据库由MySQL变oracle,myeclipse自动生成hbm.xml和实体类,Injection of resource dependencies failed.org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'BHZControl': Injection of resource depe

.net中如何给数据表实体类赋值的方法

数据 今天遇到一个问题,就是数据实体类中如何给属性赋值.因为从数据库中取出来的是一个DataSet如果一个一个给数据实体类中的属性赋值显的非常的笨拙,而且我们的数据表多达24个.在网上搜索了下写出了个简单的方法,代码如下: 首先我们做个实体类  1     public class Class1 2     { 3         private int inttemp; 4  5         public int IntTemp 6         { 7             get

三层结构ASP.NET程序中,把实体类自动显示在页面上的例子(c#)

asp.net|程序|显示|页面 在这里我们假设这样一个场景:在一个三层bs系统(asp.net)中有一个实体类Student,包括Name,Age两个字段.现在需要把这个实体类的数据显示在一个StudentInfo.aspx页面上,StudentInfo.aspx中有两个文本框:StudentName(用来显示Student.Name)StudentAge(用来显示Student.Age).下面的步骤将通过反射和Attribute来实现自动把Student实体显示在StudentInfo中:1

软件工程之系统建模篇:设计实体类模型

本文主要介绍实体类模型的设计过程,首先识别类及类之间的关系,然后画出 类图和包图,最后识别类的属性和操作.类是面向对象方法的一个全新概念,类 模型是面向对象分析的核心,实体类位于系统结构的商业规则服务层.实体类是 系统需要持久保存的对象最终要映射到数据库.实体类模型用类图和包图描述. 1.类的识别 1.1 类的识别 识别类币识别用例要困难的多,实体世界中,一切都是对象,识别起来并非易 事.我们在程序设计过程中,一般是用名词识别方法,然而你也可以用其他的方 法.用名词识别法时,从系统中找出名词.名