设计开篇

1 设计模式

   类是我们面向对象编程的承载工具,可以说是面向对象的起点。
   设计模式,这种算面向对象的进化。按照gof设计模式的分类
   设计模式分为:创建型,结构型,行为型。
   其中创建型主要和类的创建有关
   结构性组织扩展类和类之间的关系
   行为型主要扩展的类的访问
   这三个对应到类上
   创建型模式对应的是构造函数
   结构型对应的是类的属性
   行为型对应类的方法
   就想我们以前学数学中很多证明题,都源自最基本的定理,面向对象编程也有类似的地方
   设计模式就是类最基本功能的一个进化


2.依赖注入

  相信大家对Ioc(依赖注入)肯定不陌生,Ioc主要遵循设计原则中的依赖倒置原则,

  但是假设我们不要把这个东西提升到设计的高度,只看它的功能就会发现,   Ioc创建类正好就是控制类的构造函数,和设计模式中创建型模式有关,

  例如创建型模式中单例模式用ioc生命周期管理可以达到同样的效果,

  这里以Unity为例,Untiy支持child容器。利用child容器,我们可以在运行时提供更多动态创建的内容。

  我们以asp.net mvc为例,我们可以在session初始化的时候根据不同用户注入不同接口的实现。

  例如我们可以在repository中注入一个默认的规约,当不同用户登录   我们可以将用户对数据的访问权限形成一个规约,

  注册到child容器中,然后在controller激活的时候使用当前session的子容器来激活controller。

  在这里使用例子中,Ioc又实现了类似factory,甚至是building模式的功能(这个例子会在后面的文章中给大家展现具体的实现).


3.抽象的维度

  多态是代码的下行

  抽象是代码的下行

  如果B继承自A,C继承自A,那么A称之为B,C这个维度的抽象,B,C称之为A这个维度的变化 A,B,C称之为一个维度的继承关系

  传统的继承解决的是一个维度的变化,如果我们在这个维度上面引入泛型,并且用where限制泛型的行为 或者属性,

  那么就可以用诸如interface<T1,T2,T3>这样,通过组合几个泛型提供多个维度的变化。 此处用泛型扩展的继承有点类似于多继承。


4.元数据编程(Attribute)

  Attribute在我所使用的元数据编程占有重要位置。

  在asp.net mvc中,ValueProvider,ModuleBinding,Validator,Filter,都使用了元数据编程。

  不谈这个大的我们看一个更小的例子。

  最早在winform中使用DateGrid的时候,我们都是在grid设计器中去设置列的属性,名称,绑定的字段,等等。

  如果我们引入元数据编程,就可以通过在类的属性上加上特性来扩展。

  这样做更便于维护,当你的界面需要修改时,只需要在绑定的类上做修改,修改的地方相对集中,而不用去操作设计器。


5. 策略工厂

  上面说了很多理论的东西,下面为大家带来点干货。
  首先我们分析一个简单工厂的代码:

  public interface ITest
      {
          void DoSomething();
      }

      public class Test1: ITest
      {
          public void DoSomething()
          {

          }
      }
      public class Test2: ITest
      {
          public void DoSomething()
          {

          }
      }

      public class Factory
      {
          public static ITest Create(string type)
          {
              if (type == "1")
                  return new Test1();
              if (type == "2")
                  return new Test2();
              throw new NotImplementedException();
          }
      }

分析简单工厂的弊端

  1,扩展不方便需要改动create的逻辑

  2,客户需要知道create的具体逻辑

  3,创建类型过于单一导致简单工厂类的泛滥

  4,无法为对象创建提供灵活性,例如构造函数参数

  5,无法实现运行时扩展

下面我对简单工厂做了一些改造

    public  interface IStrategy
    {
    }

    public interface IGenericsFactory<TStrategy>
        where TStrategy : IStrategy
    {

        /// <summary>
        /// 注册处理策略
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        void Regist(Type type);

        /// <summary>
        /// 获取处理策略
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        TStrategy GetStrategy(string name);

        /// <summary>
        /// 获取所有的处理策略
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        List<string> GetStrategys();
    }

    public class GenericsFactory<TStrategy> : IGenericsFactory<TStrategy>
        where TStrategy : IStrategy
    {
        public GenericsFactory()
        {
            if (_strategys == null)
            {
                _strategys = GetType().Assembly
                        .GetTypes()
                        .Where(item => item.GetInterfaces().Contains(typeof(TStrategy)) || item.IsSubclassOf(typeof(TStrategy)))
                        .Where(item => !item.IsAbstract)
                        .ToDictionary(item =>
                        {
                            var desc = item.GetCustomAttribute<DescriptionAttribute>();
                            return desc != null ? desc.Description : string.Empty;
                        }, item => item);
            }
        }

        protected Dictionary<string, Type> _strategys;

        public void Regist(Type type)
        {
            if (type.GetInterfaces().Contains(typeof(TStrategy)) && type.IsSubclassOf(typeof(TStrategy)))
                throw  new TypeLoadException(string.Format("类型不是从{0},继承",typeof(TStrategy).Name));
            if (_strategys.ContainsKey(MetaDataManager.Attribute.GetDescription(type)))
                return;
            _strategys.Add(MetaDataManager.Attribute.GetDescription(type), type);
        }

        public TStrategy GetStrategy(string name)
        {
            if (!_strategys.ContainsKey(name))
                _strategys.Add(name, typeof(TStrategy));
            return (TStrategy)UnityService.Resolve(_strategys[name]);
        }

        public List<string> GetStrategys()
        {
            return _strategys.Keys.ToList();
        }
    }

改造思路
  1,使用将create的类型标记在对应的接口实现上,反射获取子类的特性,如果新增加一个类型只
       需要增加子类,并且在子类添加特性
  2,将所有可用子类的元素据缓存起来,在工厂构造函数中反射所有子类和子类的特性用字典缓存起来
       并且所有可创建的类型暴露给外部
  3,将构造出来的类型做成泛型,并且提供泛型限制,将可构造类型独立出一个维度来变化
  4,通过ioc来动态创建类型
  5,通过提供regist来提供运行时扩展

使用的案例:
  1,SSO登陆,前台用户和后台用户,存放在不同的数据表,数据结构也可能不一样
  2,动态数据权限配置,例如,某个角色只能访问某部分数据 =,>,<等等这些筛选条件的扩展
  3,状态者模式,状态可扩展,可以由界面去选择某种状态对应那种处理方式,
     将处理方式类型放在数据库
  4,责任链模式中节点的扩展和配置
       通过缓存可以直接所有节点,灵活配置节点来实现流程的功能
  5,装饰器的扩展
  可以搭配装饰器模式配置出先用某个装饰后用某个装饰、


总结:

  上面的这些关于程序设计的一些思考,会在后面的文章中分享一些自己在实际项目中的
  具体案例,请关注后续文章。要想一个架构设计能顺利推广,最简单粗暴的方法就是这个架构能够帮助程序员少些代码。
  下一篇文章将分享一个,全栈式编程的设计,主要应用于后台系统的增删改查,方便程序员更
  快速的处理掉数据的增删改查这部分通用逻辑

时间: 2024-10-19 22:05:30

设计开篇的相关文章

学习领域驱动设计(二)之上下文映射图及架构

前一篇文章 :"学习领域驱动设计开篇"给大家主要了解了下领域驱动设计是什么!这篇文章主要介绍下上下文映射图及架构相关方面的知识. 1.上下文映射图 1.1上下文映射图为何如此重要 当项目中开始采用DDD时,首先你应该为当前的项目绘制一个上下文映射图,该图主要描述当前项目中的限界上下文之间的集成关系!而上下文映射图的作用就是帮助我们从解决方案空间的角度来看待问题.(限界上下文已在上篇文章中介绍了) U表示上游(Upstream).D表示下游(Downstream) 1.2绘制上下文映射图

ASP.NET MVC +EasyUI 权限设计(一)开篇

在前一段时间中,老魏的确非常的忙碌,Blog基本上没有更新了,非常的抱歉,那么在后面的时间中,老魏会尽量的抽时间来写的,可能时间上就不太富裕了.今天开始呢,老魏会和大家分享一下关于权限设计的有关文章,由于在园子中已经有很多人写过这方面的知识了,所以老魏在这里呢可不能班门弄斧了,只是把自己的理解和做法和大家分享一下,如果有什么不对的地方或者可以优化的地方,老魏非常希望能够得到各位的建议. 话说权限是在任何的项目或者产品中都必须要用的模块,而这部分呢基本上是作为基础数据来提供的,为了能够控制各个用户

从底层谈WebGIS 原理设计与实现(一):开篇

从底层谈WebGIS 原理设计与实现(一):开篇 作者:naaoveGI-    文章来源:http://www.cnblogs.com/naaoveGIS/    点击数:4773    更新时间:2014-9-12 摘要:我相信大家对百度地图,谷歌地图等相关应用已经是非常熟悉了.通过这些应用,我们可以浏览地图.定位我们自己的位置.查找我们想知道的兴趣点.搜索交通路线等等.而其实,这些功能便是WebGIS的一些最基本的功能.那么什么是WebGIS呢,说到这里,我还是首先给大家讲讲什么是GIS.

【Java&amp;Android开源库代码剖析】のandroid-async-http(如何设计一个优雅的Android网络请求框架,同时支持同步和异步请求)开篇

在<[Java&Android开源库代码剖析]のandroid-smart-image-view>一文中我们提到了android-async-http这个开源库,本文正式开篇来详细介绍这个库的实现,同时结合源码探讨如何设计一个优雅的Android网络请求框架.做过一段时间Android开发的同学应该对这个库不陌生,因为它对Apache的HttpClient API的封装使得开发者可以简洁优雅的实现网络请求和响应,并且同时支持同步和异步请求. 网络请求框架一般至少需要具备如下几个组件:1

【JQuery NoviceToNinja系列】01 开篇 Html页面设计和布局

01 开篇 Html页面设计和布局 index.html <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>StarTrackr !</title&

设计原则开篇

bob大叔在他的著作<敏捷软件开发-原则模式与实践>一书中提到拙劣设计的七种症状: 1.僵化性:指的是设计难以改变: 2.脆弱性:设计易于遭到破坏: 3.顽固性:设计难以重用: 4.粘滞性:难以做正确的事情: 5.不必要的重复性:过分设计: 6.不必要的重复:滥用鼠标进行复制黏贴 7.晦涩性:混乱的表达 设计的"臭味"主要是因为他们违背了一个或多个设计原则,这些原则包括: 1.单一职责原则(the single responsibility principle, SRP);

【重构:改善既有代码的设计】读书笔记——开篇

[重构:改善既有代码的设计]读书笔记总目录 1.重构原则 2.代码的坏味道[1] 3.代码的坏味道[2] 4.代码的坏味道[3] 5.代码的坏味道[4] 6.重构手法之Extrct Method(提炼函数).Inline Method(内联函数).Inline Temp(内联临时变量) 7.重构手法之Replace Temp With Query(以查询取代临时变量) 边写边更新吧...... 背景介绍 重构,一言以蔽之,就是在不改变外部行为的前提下,有条不紊地改善代码. 重构不只可以改善既有的

设计模式开篇——7大设计原则

七大设计原则 开闭原则:是设计模式的总原则.开闭原则就是说对拓展开放,对修改关闭,模块应该在尽量不修改代码的前提下进行拓展.开闭原则要求我们尽量通过拓展来实现变化,尽可能少地改变已有模块. 提高代码复用性 提高代码可维护性 单一职责原则:简单来说就是保证设计类.接口.方法做到功能单一,权责明确.指的是一个类或者模块有且只有一个改变的原因. 单一职责可以降低类的复杂性.提高代码可读性.可维护性 里式替换原则:所有引用基类的地方必须能够透明地使用其子类的对象 里式替换可以提高代码复用性.子类继承父类

2015黑帽大会开篇:“互联网自由和开放正走向消亡”

2015年黑帽大会于上周三在拉斯维加斯正式拉开帷幕,本次大会新增关注互联网文化中的法律角色极其暗淡前景的话题. 当天开讲人Jennifer Granick,系斯坦福大学社交网络中心公民自由系主任,因其在合法防御黑客方面的建树而知名,以理想主义的口吻开篇. "我一直坚信自由和开放的互联网终将到来.且我一直相信我们需要一个信息可免费获取的世界,"Granick这样说道,"我认为人们可以自由获取tinker--这样的手动命令人们应该能够研究.操控乃至对定义着世界的设备和软件进行反向