面向对象最重要的是“抽象”,三层最重要的也是“抽象”,没有抽象就不是真正的面向对象、三层。

  只用class的,那叫做“基于对象”,比如当初的vb6.0;只是分了三个项目,把以前写在一起的代码分成了三份,所谓的业务逻辑层就是一个传声筒,这一类自称三层的,在我看来都是“模仿三层”,甚至是“伪三层”。

  面向对象,就是要先考虑“对象”,考虑对象的时候完全不用去考虑数据库结构是什么样子的,这个对吧?ORM讲究的是现有O后有R,然后再去映射。

代码   写到这里,突然想到一个观点:其实O和R是同时有的,他们都是根据项目需求来分别设计的,互不影响!都设计好了之后再去考虑如何映射。   您可能会说,都分别设计,那么设计之后还能对应上吗?关于这个问题,本来对象和关系型数据库的思路就是完全相反的。   面向对象,考虑的是对象,抽象,个体。要把众多的对象抽象出来,要把众多的属性、方法整合起来,要把各个类找到适合的关系。   关系型数据库,考虑的是划分,做到数据尽量没有冗余,那么多的范式要达到的效果是什么?就是要尽量的分表,分成多个表,每个表只表达一种意思,然后在“关系”(关联)在一起,以达到避免数据冗余的目的。   面向对象是根本就不去考虑数据冗余的问题的,他考虑的是“一”。一个对象的结构,和其他对象的关系(继承、接口、委托、组合、聚合等)。他不会考虑一万个实例会如何,至少不会把这个当成重点来考虑。   关系型数据库考虑的是“多”,多条数据,一万、十万、百万条记录,要如何处理。多条数据如何处理的问题。

  好像有点跑题了,赶紧回来。

  上一篇,写的那种“分开”方式,为了三层而三层的做法,我觉得就是伪三层,所以请注意,我说的是伪三层不好,为了三层而三层是不对的。我觉得我上一篇写代码的方式根本就不是真正的三层,所以请大家不要误会,我并没有说真正的三层不好,我也不是反对面向对象。

  这一篇我就是想说一下,我使用面向对象的方式。也许我的思路和您的理解不大一致,不过没关系嘛,拿出来大家一起讨论嘛。

  网站,从业务方面(就是客户的需求)可能的分类形式,比如博客园

  一开始博客园并没有这么多的模块,后来慢慢加上去了。那么我们是不是要按照这些分类来设计类呢?一个模块一个类或者若干个类?如果简单的这么做的话,那么就是类爆炸!而且没有进行抽象。(我不知道博客园是怎么做的,这里只是猜测,从技术角度上的猜测。我只是那大家熟悉的来举个例子,请不要联想,谢谢。)

  我作网站的话,会从另一个角度来思考 —— 从页面的角度来分类

  可能您看着有点晕,这都什么呀,乱七八糟的,先不要着急,带我慢慢道来。

请注意,这里说的是网页,不包括后台管理。后台管理是另一个单独的项目,和页面是完全分离开来的。他们的连系只是读取同一个数据库。

  第一个图里面分了那么多的栏目,但是首页的随笔列表、左右两侧的各种列表,新闻里的新闻列表,小组里的小组列表、小组话题列表等等。这些都是列表,形式、数据格式(就是类的属性)也都大同小异,那么我们是不是可以抽象一下呢?针对这些各式各样的列表抽象出来一个实体类?

  先看小列表

  首页里的栏目导航,左侧的连接、专题、博客排行榜,右侧的24小时阅读排行等,这一类的就是我说的“小列表”。

  栏目导航需要哪些属性?栏目名称、连接地址。   连接需要哪些属性?连接名称、链接地址。   博客排行榜需要哪些属性?博客名称、连接地址。   24小时阅读排行需要哪些属性?随笔名称、连接地址。

  好了其他的就不多说了,以免有凑字数的嫌疑。

  现在我们来抽象一下。

  这么多的属性,其实就两个属性——名称、连接地址。

【小列表的类的定义】

代码
/// <summary>
    /// 简单的列表
    /// </summary>
    public struct ListInfo1
    {
        /// <summary>
        /// 记录的主键ID。
        /// 对应字段名(别名):ID
        /// </summary>
        public string ID;            
        /// <summary>
        /// 链接地址,用于静态页或者URL重写,也可以是动态页面
        /// 对应字段名(别名):URL
        /// </summary>
        public string URL;            
        /// <summary>
        /// 标题、名称等
        /// 对应字段名(别名):Title
        /// </summary>
        public string Title;        
    }

  这么做的话,一个类可以用在许多的地方,出现新的需求不必再去定义新的类,避免了类爆炸。然后下一步就是考虑如何映射了。映射的思路也是很简单的,一个类在不同的地方,和不同的表(字段)进行映射。

不知道有没有这样的规定,不允许一个类的属性和不同的表的字段作对应。

  您可能会问了,一个属性一会和随笔名称对应,一会和栏目名称对应,这不乱吗?这还怎么维护,怎么扩展,又乱来了!这个就要看映射规则如何来定义了。

  首先要有文档,这个是必须的,文档里规定,在某个地方,类的属性和哪个表的字段对应。这是第一步。

  第二步就是这个映射如何实现了。其实相当简单,相当的不容易乱。

  我估计好些人都是面向对象习惯了,ORM给惯坏了,把SQL语句都给忘记了。

Select col0 as ID, col1 as Title ,col2 as URL from table1

  不知道大家看到这个SQL语句,有没有想到我要如何映射。对就是用字段别名来映射。这么映射,您还觉得会映射乱吗?会不好维护吗?

  因为实体类的结构固定了,那么给实体类赋值的代码(函数)也就固定了,只有SQL语句是变化的。当然了,在页面里如何显示也是变化的。

  这样的话,代码量就会几何级减少,而且不需要用代码生成器,用的话也就是生成个SQL语句了。

  字段名有变化,只需要修改SQL语句即可,实体类本来就是固定的,不用改。给实体类赋值的代码也是固定的,还是不用改。大大的降低了数据库结构的变动给代码带来的影响。

  今天是五一劳动节,祝大家劳动节快乐!

  今天天气不错,先写到这里,我去出去晒晒太阳。回来再接着写。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Ceph对象存储方案

对象存储基础概念

对象存储诞生之初 谈到为什么要有对象存储,必须聊聊对象存储诞生之前的两大存储模型:块存储和文件存储。 块存储主要是将存储介质的空间整个映射给主机使用的,主机如果...

6404
来自专栏linxu shell指南

软件构件、中间件、面向对象

    1、构件定义:组(构)件是软件系统可替换的、物理的组成部分,它封装了实现体(实现某个职能)并提供了一组接口的实现方法。可以认为组件是一个封装的代码模块或...

2694
来自专栏吉浦迅科技

DAY51:阅读Warp Shuffle Functions

__shfl_sync, __shfl_up_sync, __shfl_down_sync, and __shfl_xor_sync exchange a va...

2112
来自专栏知识分享

(五)Lua脚本语言入门

---恢复内容开始--- 写完这篇Lua脚本语言入门,自己就要尝试去用Lua脚本语言写esp8266了,,自己现在挺心急的,因为朋友使用esp8266本来说自己...

3874
来自专栏木子昭的博客

Python3好用的原生api

对列表进行反序是一个很常见的操作, 但python反向切片的玩法实在是非常简洁, 让人无法拒绝, 其实对某一数据结构进行"反向"是一个很有意...

911
来自专栏程序员的碎碎念

redis不难,benny带你入门

关于redis的学习,相信在各大博客、公众号上和教学视频教程里有很多,benny学习了一段时间总算是入门了,在会不定期的更新redis学习日记。

1284
来自专栏大数据和云计算技术

flink二三事(2):起家的技术

上一篇聊到flink的历史,请看上篇 flink两三事 ----(1)历史。 可以说基本上是起了个大早,赶了个晚集,但是flink能做今天这种热度,没有被spa...

4785
来自专栏编程

Go语言·听说你想让程序运行的更快?

作者:孙飞撩技术 链接:https://www.jianshu.com/p/0db174aebfec 來源:简书 共11254字,阅读需28分钟 迁移自 CSD...

2196
来自专栏GreenLeaves

EF基础知识小记一

1、EF等ORM解决方案出现的原因 因为软件开发中分析和解决问题的方法已经接近成熟,然后关系型数据库却没有,很多年来,数据依然是保存在表行列这样的模式里,所以,...

1829
来自专栏java思维导图

架构师必须掌握的 10 条设计原则

函数是程序员的工具中最重要的抽象形式。它们能更多地被重复使用,你需要编写的代码就越少,代码也因此变得更可靠。较小的函数遵循单一职责原则更有可能被重复使用。

793

扫码关注云+社区

领取腾讯云代金券