• 架构实例解析面向对象的封装,多态,继承,接口,泛型


    1. 架构实例基础准备

    假设我们做一个简单的小系统,需要的操作为:

    1.管理用户,对用户进行增、删、改(User表)

    2.管理角色,对角色进行增、删、改(Role表)

    3.管理功能,对系统功能进行增、删、改(Fun表)

    由此可以分析,我们这个小系统需要的表为,User用户表,Role角色表,Fun权限表,还要派生出一张表 角色-权限(RoleFun) 关联表。其中用户表里面有字段存放角色Role的ID。

    2. 搭建项目基础框架

    一般情况下,我们都采用的是3层架构模式,即使是复杂模式也是在此基础上延伸的。

    上面这幅图是最最基础的一个框架。总共分为5个层次,Model层,DAL层,BLL层,Tools层,UI层

    3. 代码实现基础架构

    对于一般的编程者来说,实现起来并不复杂,可能不会将那么多的思想应用到实例中来,那么这里我们模拟下,先抛开这些思想。

    (1)首先每个数据库表对应一个Model类这个是必须的吧,那么我们在Model层新建4个类,User,Role,RoleFun,Fun

    (2)这个四个对象都需要数据库增、删、改操作,那么我们在DAL里面对应的创建4个类,UserDAL,RoleDAL,RoleFunDAL,FunDAL,然后每个类里面写入相同的方法,增、删、改。

           Insert(对象),Delete(对象),Update(对象)

           这里你可能已经意识到问题了,hold,继续看。

    (3)同样在BLL层要实现对DAL的调用,需要建立同样的四个业务操作类,UserMgr,RoleMgr,RoleFunMgr,FunMgr,每个类里面实现同样的调用方法。

    (4)Tools暂不考虑,主要存放经常用的类

    (5)UI层,表现层,可以是Web或者Winform等形式

    搭建好的代码框架如下:

    4. 开始OOP的分析应用--封装

    面向对象的第一个特性是:封装,其实我们已经实现了,分层就是封装的最好体现,各层相互调用,“低耦合,高内聚”

    这里不在解释封装了。

    5. OOP--继承

    通过上面的代码编写你肯定遇见了灾难了,当随着我们业务功能的不断增加,我们的DAL和BLL类越来越多,越来越难管理了。

    更悲催的是,如果每个实体类我想实现一个查询(Search)操作,那么需要在众多的类里面实现这个Search代码,试想那是多么的可怕,你的价值全部浪费在了基础代码的编写上。

    如何解决这个问题呢?

    那就是采用继承的思想实现,父子类来实现,一个公共的父类(BASE),所有子类继承这个子类,那么子类也就具有了父类的public方法,如果需要增加公共的方法,只需要在父类中添加方法即可实现,所有子类自动会继承。

    模式如上图所示,这样实现一个Search()方法,我们只需要变动BaseDAL类即可,而其他实体类都不需要动了。试想对若干实体类的系统,这意思想是多么的重要,可以节省大量的时间。

    还没有结束,细心的你可能发现,我们的Insert,Update,Delete都需要自己的Model呀,那BaseDAL应该如何实现呢?怎么知道具体的方法去调用具体的Model呢?

    哈哈,这里C#提出了引以为豪的“泛型”思想。通过泛型,可以轻松的解决这个问题。

    6. 泛型

    对于BaseDAL我们可以设计成为泛型的类,在使用该类的时候需要将该类具体的实例化,看代码:

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace DAL
    {
        public class BaseDAL<T> where T:new ()
        {
            public bool Insert(T t)
            {
                //TODO 解析T,通过反向工程构造SQL
                return true;
            }
    
            public bool Update(T t)
            {
                //TODO 解析T,通过反向工程构造SQL
                return true;
            }
    
            public bool Delete(T t)
            {
                //TODO 解析T,通过反向工程构造SQL
                return true;
            }
        }
    }
    复制代码

     这样,我们其他的类可以直接继承父类了。但为了整体架构的可塑行,我们DAL层将不做对BaseDAL的继承操作,原因很简单,因为我们可能会切换DAL的技术,例如由ADO.Net切换成HNibernate等,同时DAL作为数据操作层尽量要保持简约。

    我们这里在业务逻辑层BLL来实现继承,同样也需要一个BaseBLL的基类。

    复制代码
    using DAL;
    using System.Collections;
    using System.Collections.Generic;
    
    namespace BLL
    {
        public class BaseMgr<T> where T : new()
        {
            //可以重写
            public virtual bool Insert(T t)
            {
                return new BaseDAL<T>().Insert(t);
            }
    
            public bool Update(T t)
            {
                return new BaseDAL<T>().Update(t);
            }
    
            public bool Delete(T t)
            {
                return new BaseDAL<T>().Delete(t);
            }
            //重载
            public bool Delete(List<T> list)
            {
                return true;
            }
        }
    }
    复制代码

    然后具体的实体类继承这个BaseMgr

    复制代码
    using Model;
    
    namespace BLL
    {
        public class UserMgr : BaseMgr<User> //继承
        {
            //继承基类最大的好处是,可以写本类自己的特有方法
            //例如User,我想获取所有的用户,而其他的业务逻辑不需要实现这个方法,
            //那么我们可以单独写在这个类里面
            //当然你也可以写在BaseMgr里面,哪样所有的子类都具有这个方法了
    
            //可以对基类进行重写(多态)
            public override bool Insert(User t)
            {
                return true;
            }
    
            //继承基类前的代码
            //public bool Insert(User t)
            //{
            //    return new UserDAL().Insert(t);
            //}
    
            //public bool Delete(User t)
            //{
            //    return new UserDAL().Delete(t);
            //}
    
            //public bool Update(User t)
            //{
            //    return new UserDAL().Update(t);
            //}
    
    
        }
    }
    复制代码

    通过泛型实现继承我们获得的最大好处:

    1,数据库每增加一个实体,代码的Model层只需要增加一个对应的实体类,那么该类的基础操作随即产生了(即,BaseDAL类的所有方法)

    2,通过在业务层对基类的继承,可以实现特有方法,当然并不是所有的实体类都需要继承,具体看自己的需求

    7. OOP-多态

    多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

    实现多态,有二种方式,覆盖,重载。

    覆盖:override,上面代码UserMgr类中的Insert方法就是用的覆盖方法,可以重写父类的某些方法来达到自己的业务要求。一定要注意将允许重写的方法事先声明为virtual

    重载:通俗点就是一个方法名,不同的参数类型,例如我想实现一个批量删除功能,方法的名字同样想起名为Delete,那么只需要改变参数即可

             public bool Delete(List<T> listT);

     

    8. 接口

    顾名思义,接口,即插即用,例如插座,只要有对应插头,插入即可使用了。

    接口:在编程里面起到的是一种规范,既然是规范,必定是约束若干人的,也就是团队开发项目,大家共同遵循一个规范,协调开发代码,而且互不干扰。

    接口更多的是被软件架构师使用,设计好整体的软件架构,直接交给程序员开发即可,程序员只需要按照这种规范做就可以了,对每个接口进行具体的实现。

    注意哦:接口不实现,是可以通过编译的哦

     

    9. 引申架构

    通过采用上面的思想,基本上我们可以实现一套牢固的架构了,而且可以复用到任何的系统中。

    但技术是在不断革新的,而且需求也是不断变化的,更可怕的是能够运行系统的设备越来越多了,从PC到普通手机,再到智能手机(Android,IOS,WP7),再到平板电脑等等。

    还有语言的差异,Java,php等等

    这就要求一套架构不但要牢固,更能够适用于各种平台的开发。

    为此我们的架构可以引申成一个服务,将上面的架构在加上一个服务层(可以用WCF,可以用MVC4的WebAPI,Restful规范),那么整体的架构就是下面这个样子了。

    10. 总结

    软件开发其实就是一种思想,将人的一种思想通过代码形式反映出来。好好用心思考,你就明白为什么会这么做,仔细体会其中的妙处。



    博客声明本站部分内容转自网络,如果侵害到您的权利,请及时联系我
    转载请注明出处:http://www.cnblogs.com/qidian10
    Mail:ovenjackchain@gmail.com;QQ:710782046;Web:云极科技
  • 相关阅读:
    Linux下制作和使用静态库和动态库
    C语言的内存管理
    C语言柔性数组
    大小端模式
    C位域操作
    C/C++字节对齐
    C/C++指针
    Linux之Socket编程
    VSCode配置FTP
    GCC的编译过程和链接
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2508107.html
Copyright © 2020-2023  润新知