Bug开发工程师
作者相关精选

把3000行代码重构成15行的牛逼操作!!!

前往小程序,Get更优阅读体验!
立即前往
Bug开发工程师
关注我,不错过每一次更新。
社区首页 >专栏 >把3000行代码重构成15行的牛逼操作!!!

把3000行代码重构成15行的牛逼操作!!!

作者头像
Bug开发工程师
发布于 2019-12-25 00:13:03
4860
发布于 2019-12-25 00:13:03
举报
文章被收录于专栏:码农沉思录码农沉思录

如果你认为这是一个标题党,那么我真诚的恳请你耐心的把文章的第一部分读完,然后再下结论。如果你认为能够戳中您的G点,那么请随手点个赞。

把3000行代码重构为15行

那年我刚毕业,进了现在这个公司。公司是搞数据中心环境监控的,里面充斥着嵌入式、精密空调、总线、RFID的概念,我一个都不懂。还好,公司之前用Delphi写的老客户端因为太慢,然后就搞了个Webform的替代,恰好我对Asp.Net还算了解,我对业务的不了解并不妨碍我称成为这个公司的一个程序员。小公司也有小公司的好,人少,进去很快负责代码开发。我当然也就搞这个数据中心智能管理系统啦。

这个系统非常的庞大,尤其牛逼的是支持客户端组态,然后动态生成网页,数据还能通过Socket实时监控(那时我还真就不懂网络编程)。这个对于当时的我来说,真真是高、大、上呐!!当时跟着了解整个系统大半个月才算能够调试,写一些简单的页面。

在维护系统的过程中,时不时要扩展一些功能,也就接触了下面这个类:

看到没有,就是当年最最流行的三层架构的产物,对于刚出茅庐的毛头小子来说,这是多么专业的文件头注释,还有反射也就算了,这构造函数还能静态的,还能私有的?那时刚接触这么高大上的代码的我,瞬间给跪了!

但是,类写多了,我就感觉越来越别扭,就是下面这段代码:

每增加一个表,除了要改接口、要改DAL、要改BLL之外,还得在这个工厂类添加一个方法,真真是累到手抽筋,即使有当时公司了的G工给我推荐的神器——动软代码生成器,这粘贴复制的几遍,也是让我感觉到异常繁琐,有时候打键盘稍微累了点,还把复制出来代码改错了,你妹的,难道这就是程序员该干的事情,不,绝对不是!我想起了一句至理名言:当你觉得代码重复出现在程序中的时候,就应该重构了。是的,在这句话的指导下,我开始了折腾,决定挑战这个高大上的代码,事实证明,思想的力量是无穷的。

那么,怎么修改呢,仔细观察之后,发现其中className的生成跟返回的类型非常类似,只是一个是类名,一个是字符串,这两者之间应该能够关联起来。于是google了一下(当时GFW还没猖獗起来哈),隐隐约约就找到了“反射”这两个字,深入了解之后,确定可以完成。

接下来,就是返回的类型了,返回的类型并不固定,但是似乎很有规律……这个似乎好像在哪里见过,对了,模板,C++课程上有讲过的,于是再次google,了解到了C#中使用了泛型代替了C++中的模板。在学习完泛型和反射之后,并参考了网上的一些文章,我捣鼓出了下面的代码:

没错,就是它了,三层架构年代最流行的工厂类……

看着原来滚十几屏幕的代码,变成了十多行的代码,真是爽到了骨子里去了,太干净了!唯一让我担忧的是,我进公司的时候,帮忙整理公司申请软件著作权都是需要代码量的,根据代码多少行来评估软件的大小,万一老板知道了我非但没有帮公司增加代码量,还减少了,会不会立即把我开掉?我没敢给我们老板展示我优秀的成果,所幸,这段代码非但没有出过任何问题,还避免了以前同事老是在新增一个类之后,把代码复制过来,但是没有正确修改的问题,大大提高了效率。虽然,我没敢大事宣布我的劳动成果,但是这次成功的修改,则彻底让我走上了代码重构的不归路。

看到这里,大家应该知道这个案例是否真实的了吧。我相信,从08年开始的码农们,看到这种类似的代码绝对不比我少。那么,我想告诉你们的是什么呢?

  • 要在编程过程中多思考
  • 编程的思想很重要,请多看点经典的书
  • 从小处着眼,慢慢重构,尤其在应对一个大型的系统
  • 当重复出现的时候,你应该考虑重构了
  • 粘贴复制的代码越少,你的系统越稳定

少用代码生成器

我们来分析一下,为什么我之前的前辈会写出上面的代码。我归结起来有以下几点:

  • 因为使用了动软代码生成器,生成代码方便,就没多想了。
  • 三层架构的概念倒是了解了,但是没有去深入思考就拿来应用
  • 遇到重复的代码,没有重构的概念,这是思想的问题——思想比你的能力重要

至今为止,还是很多人使用代码生成器,那么我们应该怎么对待这个问题呢。我认为,代码生成器确实可以减少你不少工作,但是少用,那些重复性的工作,除了部分确实是没有办法的,其他大部分都是可以通过框架解决的,举例来说,像三层架构,真正需要用到代码生成器的,也就是Model类而已,其他的完全可以在框架中完成。因此你要竭尽全力的思考怎么在框架中来减少你的重复性工作,而不是依赖于代码生成器。

另外,如果你还是在用相关的代码生成工具,请重新定义“动软代码生成器”的代码模板,自己写一个模板;或者使用CodeSmith来完全制定自己的代码生成,因为动软给的代码模板真心乱,比如下面这段代码:

代码语言:javascript
复制
for (int n = 0; n < rowsCount; n++)
{
    model = new DBAccess.Model.eventweek();
    if(dt.Rows[n]["GroupNo"].ToString()!="")
    {
        model.GroupNo=int.Parse(dt.Rows[n]["GroupNo"].ToString());
    }
    if(dt.Rows[n]["Week0"].ToString()!="")
    {
        model.Week0=int.Parse(dt.Rows[n]["Week0"].ToString());
    }
    if(dt.Rows[n]["Week1"].ToString()!="")
    {
        model.Week1=int.Parse(dt.Rows[n]["Week1"].ToString());
    }
}

首先,你就不能用 var row=dt.Rows[n] 替代吗?其次,直接用int.Parse如果抛出了异常性能得有多低?再次,这段代码要是有点修改,我不是要每个dt.Rows[n]得改一遍?

不要重复发明轮子

我们再来看看其他的一些代码:

代码语言:javascript
复制
public List<string> GetDevices(string dev){
    List<string> devs=new List<string>();

    int start=0;
    for(int i=0;i<dev.Length;i++){
        if(dev[i]=='^'){
            devs.Add(dev.SubString(start,i));
            start=i+1;
        }
    }

    return devs;
}

有没有很眼熟,没错,这就是对String.Split()函数的简单实现。我的前辈应该是从c++程序员转过来的,习惯了各种功能自己实现一遍,但是他忽略了C#的很多东西。我们不去评判这段代码的优劣,而实际上他在很长一段时间都运行得很好。我们来看看使用这一段代码有什么不好的地方:

  • 重复发明轮子。花费了额外的时间,函数的健壮性和很差
  • 可读性差。其实是一个很简单的功能,但是用上了这么一段函数,起初我还以为有什么特别的功能。

那么,我们应该怎样去避免重复发明轮子呢?我从个人的经历来提出以下几点,希望能够对各位有所帮助:

  • 了解你所学的编程语言的特性。你可以看一本基础的入门书籍,把所有的特性浏览一遍,或者上MSDN,把相关的内容过一遍。
  • 在你决定动手发明一个轮子之前,先搜索一下现成的解决方案。你还可以到CodeProject、GitHub之类的网站搜索一下。在知乎上有很多人都在批评这么一种现象,老是问一些重复性的问题,然后又职责知乎没落了,没有人回答他的问题,实际上相关问题已经有了很详细的解答,那提问之前,不能首先去搜一下是否有现成的答案,反而指责没有回答他的问题呢?
  • 你有一定的基础之后,还应该去读一下相关的经典书籍,深入了解其中的原理。比如,你觉得你有一定的基础了,我建议你去把《CLR Via C#》多读几遍,你了解原理越多,你越是能够利用这编程语言的特性,从而来实现原本那些你认为要靠自己写代码的功能。

这里我再举一个我自己的例子。在我现有的程序中,我发现我需要越来越多的线程来执行一些简单的任务,比如在每天检测一下硬盘是否达到90%了,每天9点要控制一下空调的开启而在网上6点的时候把空调关掉。线程使用越来越多,我越是觉得浪费,因为这些现场仅仅只需完成一次或者有限的几次,大部分时间都是没有意义的,那么怎么办呢?我决定自己写一个任务类,来完成相关的事情。说干就干,我很快把这个类写出来了。

代码语言:javascript
复制
public abstract class MissionBase : IMission
{
    private DateTime _nextExecuteTime;
    protected virtual DateTime[] ExecuteTimePoints { get; private set; }
    protected virtual int IntervalSeconds { get; private set; }
    protected IEngine Engine { get; private set; }

    public bool IsCanceled{get{……}}
    public bool IsExecuting{get{……}}
    public bool IsTimeToExecute{get{……}}

    public abstract bool Enable { get; }
    public abstract string Name { get; }

    protected MissionBase(IEngine engine)
    {
        ExecuteTimePoints = null;//默认采用间隔的方式
        IntervalSeconds = 60 * 60;//默认的间隔为1个小时

        Engine = engine;
    }

    /// 任务的执行方法
    public void Done()
    {
        if (Interlocked.CompareExchange(ref _isExecuting, 1, 0) == 1) return;

        try
        {
            ……
        }
        finally
        {
            Interlocked.CompareExchange(ref _isExecuting, 0, 1);
        }
    }
    
    ///实际方法的执行
    protected abstract void DoneReal();
}

但是,实际上这个任务方法,并不好用,要写的代码不少,而且可靠性还没有保障。当然,我可以继续完善这个类,但是我决定搜索一下是否还有其他的方法。直到有一天,我再次阅读《CLR Via C#》,看到线程这一章,讲到了System.Threading.Timer以及ThreadPool类时,我就知道了,使用Timer类完全可以解决我的这个用尽量少的线程完成定时任务的问题。

因为从原理上来说,Timer类无论你声明了多少个,其实就只有一个线程在执行。当你到了执行时间时,这个管理线程会用ThreadPool来执行Timer中的函数,因为使用的ThreadPool,执行完成之后,线程就马上回收了,这个其实就完全实现了我所需要的功能。

等你无法重构的时候再考虑重写

我带过很多优秀的程序员,也与很多优秀的程序员共事过。有一大部分的程序员在看到一套系统不是那么满意,或者存在某些明显的问题,就总是忍不住要把整套系统按自己觉得可以优化的方向来重写,结果,重写结构往往并不令人满意。系统中确实存在很多不合理的地方,但是有不少的这种代码,恰恰是为了解决一些特定场景下的问题的。也就是说,所有的规范以及编程的原则,其实也是有条件限制的,他可能在大部分的时候是正确的,能够指导你完成你的任务,但是,并不是在所有地方都是适用的。比如数据库范式,但实际中我们的设计往往会考虑冗余,这是违背范式的,但是为什么还有那么多人趋之若鹜呢?因为我们可能需要用空间换时间。

如果我们一开始就考虑重写,那么你可能会陷入以下的困境:

  • 需要花更大的精力来完成一些看似简单的BUG 你要知道,有一部分看似错误或者非常不优美的代码,其实恰恰是为了解决一些非常刁钻的问题的。
  • 再也无法兼容老的系统了 你急于把原有系统重写,却往往忽略了对原有系统的兼容,那么你新的系统的推进则会十分缓慢。而老系统的维护,又会陷入及其尴尬的情况。
  • 过度设计,导致重写计划迟迟无法完成 有重写冲动的程序员往往是在架构设计上有一些读到的见解,他们善于利用所学的各种设计模式和架构技巧来建立系统,但是越是想尽可能的利用设计模式,越是陷入过度设计的困局,导致重写的计划迟迟都无法完成。
  • 无法有效利用现有系统已经完成并测试的代码 如果你确实有必要进行重写,我还是建议你把代码尽可能的重构。因为重构之后的系统,能够让你更轻易的重写,又最大限度了保留以前可用的业务代码

我举个例子,说明如何通过重构更好的利用现有代码的。

我有一个非常庞大的系统,其中有一块功能是用于数据采集、存储、告警管理以及电话、短信等告警通知。大致的结构如下:

代码语言:javascript
复制
class MainEngine:IEngine{
    public MainEngine(ConfigSettings config){
        
    }

    public void Start();
    public void Stop();
}

需要增加新的业务功能时,程序员写的代码往往是这样的:首先时修改配置类

代码语言:javascript
复制
class ConfigSettings{
    public bool NewFuncEnable{get;private set;}
    public ConfigSettings(){
        NewFuncEnable=xx;//从配置文件读取
    }
}

接着修改主程序:

代码语言:javascript
复制
class MainEngine:IEngine{
    private NewFuncClass newCls=new NewFuncClass();
    public MainEngine(ConfigSettings config){
    }

    public void Start(){
        if(config.NewFuncEnable)
            newCls.Start();
    }
    public void Stop(){
        if(config.NewFuncEnable)
            newCls.Stop();
    }
}

在修改的过程中,往往是根据配置文件来判断新功能是否启用。上面代码会造成什么问题呢:

  • 主程序代码和扩展功能耦合性太强,每增加一个功能都要修改主程序代码,这里非常非常容易出错。尤其是新的人进度开发组,很容易就忘主程序中增加了一些致命性的代码。比如上述的扩展功能,可能是在特定的项目中才会有这个扩展功能,但是,写代码的人忘记增加是否启用的配置选项了,导致所有的项目都应用了这个功能,而这个功能需要特定的表,这样就悲剧了。即使是你增加了配置,也是非常的不美观,因为在通用的版本中使用了这个配置,往往会让定制项目以外的人员感到困惑
  • 增加扩展功能的人还需对整个MainEngine代码有一定的熟悉,否则,他根本就不知道在Start方法和Stop方法进行newClas的对应方法的调用
  • 如果你打算对这段代码进行重写,那么,你会感到非常的困难,因为你分不清楚newCls这个新实例的作用,要么你花大精力去把所有代码理清楚,要么直接就把这段新增的业务代码去掉了。

那么我们如何对这段代码进行重构呢。首先,我们把新功能注册的代码抽取出来,通过反射来实现新的功能的注册。

代码语言:javascript
复制
    private void RegisterTaskHandlerBundles()
    {
        var bundles = xxx.BLL.Caches.ServiceBundleCache.Instance.GetBundles("TaskHandlerBundle");
        if (bundles != null && bundles.Count > 0)
        {
            var asmCache = new Dictionary<string, Assembly>();
            foreach (var bundle in bundles)
            {
                try
                {
                    if (!asmCache.ContainsKey(bundle.Category)) asmCache.Add(bundle.Category, Assembly.Load(bundle.AssemblyName));
                    var handler = (ITaskHandler)asmCache[bundle.Category].CreateInstance(bundle.ClassName, false, BindingFlags.Default, null,
                        new object[] { this, bundle }, null, null);
                    _taskHandlerBundles.Add(bundle, handler);
                }
                catch (Exception e)
                {
                    NLogHelper.Instance.Error("加载bundle[Name:{0},Assembly:{1}:Class:{2}]异常:{3}", bundle.Name, bundle.AssemblyName, bundle.ClassName, e.Message);
                }
            }
        }
    }

修改MainEngine代码

代码语言:javascript
复制
class MainEngine:IEngine{
    private NewFuncClass newCls=new NewFuncClass();
    public MainEngine(ConfigSettings config){
        RegisterTaskHandlerBundles();
    }

    public void Start(){
        _taskHandlerBundles.Start();
    }
    public void Stop(){
        _taskHandlerBundles.Stop();
    }
}

OK,现在我们再来看看怎么实现原来的新增功能:你只需按规范新建一个类,继承ITaskHandler接口,并实现接口的方法。最后在XTGL_ServiceBundle表中新增一条记录即可。我们再来看看这么做有什么好处:

  • 新增的类只需按规范写即可,完全对MainEngine代码没有任何影响。你甚至可以把这个MainEngine代码写在一个新建的Dll中。
  • 新增功能的这个业务类跟原来的代码解耦,非常方便进行新功能的业务测试,而无需考虑原有框架的影响
  • 新增功能的业务类与架构完全分离,我们在重写代码中只要保证接口的稳定性,无论我们怎么把系统架构重写,我们可以马上就重用上原有的业务功能代码。

重构的目标之一,就是把框架和业务完全分离。

有志于深入了解的同学,可以了解下反射、Ioc和插件话编程等。

学会单元测试,培养你的重构意识

可能上面说了这么多,还是有很多人并不理解重构。没关系,在这里我教你们一个快速入门的办法,就是单元测试。什么是单元测试,请自行google。单元测试有什么要求?就是要求你要把每个方法都弄成尽量可以测试的。尽量让你的方法变成是可测试的,就是培养你重构意识的利器。在你要求把方法变成可测试的过程,你就会发现你必须得不断的修改你的方法,让它的职责尽量单一,让它尽量的与上下文无关,让它尽可能通过方法参数的输入输出就能完成相关的功能,让依赖的类都尽量改为接口而不是实例。最终,你就会发觉,这就是重构!而且是在不知不觉中,你重构的功力就会大大提升,你编程的水平也会大大提升!

看到这里,有经验的程序员就会问,你这是在鼓励我使用TDD吗?不,不是的。TDD(Test-Driven Development)鼓励的是测试驱动开发,未开发之前先编写单元测试用例代码,测试代码确定需要编写什么产品代码。这是一种比较先进的开发方法,但是在编程的实践过程中,我认为它过于繁琐,很多中小企业很难实施,更别提我们个人开发者。我这里提倡你用单元测试培养你的重构意识,可以说是一种后驱动,用于提高你的重构能力和重构愿望,你完全可以把我的这个方法称为“TDR(Test-Driven Refactoring)——测试驱动重构”。当然,在开发之前如果你有意识的让方法可测试,那么你写出来的函数将会是比较高质量的代码。当你的函数都是一个个可重用性高的函数之时,你将会发现,写代码其实就像堆积木一样,可以把一个大型的需求分解成无数细小的功能,很快的把需求实现。

以下是一个超大方法中的一段代码,如果你懂得怎样让这段代码编程一个可测试的方法,那么,恭喜你,你入门了。

所谓重构

如果你有耐心看到这里,你应该知道,我并非一个标题党,而这篇文章也许称为“如何在编程中应用重构的思想”更为贴切,但是我不想用这么严肃的标题。

很多编程初学者,或者有多年编程经验的人都觉得阅读别人的代码非常困难,重构更是无从谈起,他们要么对这些代码望洋兴叹,要么就是推翻从来。但是,如果我们有重构的意识,以及在编程的过程中熟悉一些代码调整和优化的小技巧,你自然而然就会培养出重构的能力。

重构,其实很简单:

  • 把基础打牢固
  • 多看点优秀的代码
  • 避免复制粘贴,如果看见重复代码时应该有意识要消灭它
  • 减少对代码生成器的依赖
  • 在处理现有代码时尽量用重构代替重写,在重写之前一定要先重构
  • 尽量让所有的方法都是可测试的

如果你坚持这么去做了,一段时间之后感觉自然就出来了。

重构的目的,是让你的代码更为精简、稳定、能够重用,是最大程度的让功能和业务分离。在重构的过程中,你的阅读代码的能力、写出优秀代码的能力以及系统架构能力都会稳步提升。你成为一个优秀的程序员将指日可待。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农沉思录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
从把三千行代码重构成15行代码谈起
那年我刚毕业,进了现在这个公司。公司是搞数据中心环境监控的,里面充斥着嵌入式、精密空调、总线、RFID的概念,我一个都不懂。还好,公司之前用Delphi写的老客户端因为太慢,然后就搞了个Webform的替代,恰好我对Asp.Net还算了解,我对业务的不了解并不妨碍我称成为这个公司的一个程序员。小公司也有小公司的好,人少,进去很快负责代码开发。我当然也就搞这个数据中心智能管理系统啦。
java架构师
2019-02-26
4780
简单代码生成器原理剖析(一)
上篇文章(深入浅出三层架构)分析了简单三层架构的实现。包括Model,DAL(数据访问层),BLL(业务逻辑层)的实现。 实际开发中,由于重复代码的操作,会花费大量时间,如果以代码生成器来自动生成三层
用户1161731
2018-01-11
1.3K0
简单代码生成器原理剖析(一)
简单代码生成器原理剖析(二)
上篇《简单代码生成器原理剖析(一)》分析了代码生成器的原理,查询数据库系统视图:INFORMATION_SCHEMA.TABLES、 INFORMATION_SCHEMA.COLUMNS  可以获得数据库中表、列的相关信息,再运用StringBuilder类的其AppendLine方法追加字符串,最后早运用File.WriteAllText方法将字符串写入文件。 第二版代码生成器在第一版的基础上扩展了以下功能: 使用了部分类(partial):当使用大项目或自动生成的代码(如由 Windows 窗体设计器提
用户1161731
2018-01-11
7020
代码生成器原理及示例
在三层架构中Model、DAL(Data Access Layer)、BLL层有必要分开,其中有些代码可以由代码生成器生成。虽然网络已经有成熟的代码生成器,但是第三方代码生成器在实际应用场景中,生成的代码经常还需要在其基础上修改。修改其代码就不如修改代码生成器本身。所以掌握代码生成器的编写方法、原理还是很有必要的。
全栈程序员站长
2022-07-25
8840
代码生成器原理及示例
手把手教你开发代码生成器,学不会的来怼我!
在实际的软件项目开发过程中,我可以很负责任的跟大家说,如果你真的实际写代码的时间过5年了,你对增删改查这类简单的功能需求开发,可以说已经完全写吐了,至少我就是这种类型的。
macrozheng
2021-09-22
5030
手把手教你开发代码生成器,学不会的来怼我!
ASP.NET MVC5+EF6+EasyUI 后台管理系统(59)-BLL层重构
前言:  这应该是本系统最后一次重构,将重构BLL层和Model层。来完全取代代码生成器生成的BLL层和DAL层。完全废掉了代码生成器的DAL,BLL,MODEL层。     全自动生成增,删,改,查的通用方法和模型转换与BLL层的模型事务脱离,后续文章,会以一些插件或功能为目的,继续完善,进行分享,最后60节的文章会对本系统做一个总结   (但是还没时间写,相信60节的文章能让你快速了解到本系统的优势和架构,就算你从未阅读之前的所有文章)    继上次的DAL层重构(上一节),本来只想重构DAL层算了,
用户1149182
2018-01-16
1.2K0
ASP.NET MVC5+EF6+EasyUI 后台管理系统(59)-BLL层重构
我用过很多代码生成器,还是选了他
大家好,我是鲏。如果你是一名后端开发者,那么大多数的工作一定是重复编写各种 CRUD(增删改查)代码。时间长了你会发现,这些工作不仅无趣,还会浪费你的很多时间,没有机会去做更有创造力和挑战的工作。
程序员鱼皮
2023-10-23
3700
我用过很多代码生成器,还是选了他
数据字典生成工具之旅(7):NVelocity实现代码生成器
用户1168362
2018-01-05
7680
数据字典生成工具之旅(7):NVelocity实现代码生成器
.NET对存储过程的调用抽象封装
最近一边参与公司的项目开发,一边还肩负着基础库的创建和维护。真真切切的体会到写框架的不容易,写出好的,方便使用的框架更不容易,需要考虑的东西太多,需要掌握的东西太多。不过不要紧我们正在前进的道路上。同志们一起加油!
王清培
2022-03-14
6620
.NET对存储过程的调用抽象封装
代码重构之道
如果我纯粹为今天工作,明天我将完全无法工作。 -- 某子 程序员要面向未来编程。代码重构永远是程序员们无法回避的话题,当你的软件在编写的那一刻起,重构就不可避免。做一个系统,我们为什么要费劲地不断抽象,竭尽全力让自己的代码能够被重用,说白了就是让我们今日所付出的时间,让未来的我们能够更轻松地工作而已。 有位读者让我就 Martin Fowler 的『重构 - 改善既有代码的设计』一书,谈谈重构。我诚惶诚恐。这本书我很久很久以前买过,至今还躺在北京家中的书柜里;当时对系统领悟还不够深,所以很多思想都并未参透,
tyrchen
2018-03-28
9200
代码重构之道
JeecgBoot低代码平台 v3.6.0大版本发布—1024 程序员节快乐~
JEECG
2023-10-23
3500
使用 Source Generator 在编译你的 .NET 项目时自动生成代码
本文以 dotnetCampus.Ipc 项目为例,来说明如何为一个现成的 .NET 类库添加自动生成代码的功能。这是一个在本机内进行进程间通信的库,在你拥有一个 IPC 接口和对应的实现之后,本库还会自动帮你生成通过 IPC 代理访问的代码。由于项目加了 Roslyn 的 SourceGenerator 功能,所以当你安装了 dotnetCampus.Ipc NuGet 包 后,这些代码将自动生成,省去了手工编写的费神。
walterlv
2023-10-23
3940
使用 Source Generator 在编译你的 .NET 项目时自动生成代码
从数据到代码——通过代码生成机制实现强类型编程[下篇]
在《上篇》中,我们实现了将保存有消息条目的XML向CodeDOM的转换,即是将XML文件生成一个CodeCompileUnit对象,而该CodeCompileUnit对象反映出来的DOM层次和我们将会生成的代码文件向匹配。在下篇中,我们将实现整个代码生成系统的第二个步骤——通过VS的Custom Tool实现数据(保存消息条目的XML)向代码文件的自动转换。 一、让MessageCodeGenerator继承BaseCodeGeneratorWithSite 在《上篇》我们创建了MessageCodeGen
蒋金楠
2018-01-16
9710
从数据到代码——通过代码生成机制实现强类型编程[下篇]
文档驱动式代码设计器——代码是设计出来的!
  代码是敲出来的吗?是批量生成出来的吗?   No no no,代码是设计出来的!   如果说到代码生成器,大家可能会想到三层、动软代码生成器、数据库表等等。其一般的思路是,先有数据库然后根据库里的表自动生成一系列的代码,包括实体类、持久化、业务层(空函数)、页面代码等,还可以生成数据库文档。这个确实很好很强大,可以免除程序员的机械式的敲代码的工作。 (“主要实现在对应数据库中表的基类代码的自动生成,包括生成属性、添加、修改、删除、查询、存在性、Model类构造等基础代码片断,支持不同3种架构代码生成,使
用户1174620
2018-02-08
9590
20个代码生成框架 (.NET JAVA)
1.1 CodeSmith 一款人气很旺国外的基于模板的dotnet代码生成器 官方网站:http://www.codesmithtools.com 官方论坛:http://forum.codesmithtools.com/default.aspx 版权形式:30天试用 开源:否 需要先注册确认后才能下载 1.2 MyGenerator MyGenerator是又一个国外很不错的代码生成工具,有人觉得比CodeSmith简单、好用。所有api可以在帮助菜单中找到。 官方网站:http://www.mygen
庞小明
2018-03-07
4K0
20个代码生成框架
官方论坛:http://forum.codesmithtools.com/default.aspx
三哥
2019-05-31
2.9K0
代码重构之道
导语 最近看到有同学提问:“代码重构有意义吗?”,“关于代码重构有什么好的方法论吗?”,个人对代码重构非常感兴趣,在13年就开发接触代码重构的概念,学习相关理论方法,一直在坚持实践,现在基本已养成一种习惯了,所以周末系统梳理了重构原理、相关概念和操作技巧,抛砖引玉,跟大家分享交流。 什么是重构? Refactoring是对软件内部结构的一种调整,目的是在不改变外部行为的前提下,提高其可理解性,降低其修改成本。 为什么重构? 1.改进软件的设计 《重构》里有一段话非常有启发性:“一开始我所做的重构都像这样停
QQ音乐前端团队
2020-07-21
1K0
创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]
在《上篇》中我们通过T4模板为我们指定的数据表成功生成了我们需要的用于添加、修改和删除操作的存储过程。但是这是一种基于单个文件的解决方案,即我们必须为每一个生成的存储过程建立一个模板。如果我们提供一种基于多文件的代码生成方式,将会为编程人员带来极大的便利。借助于T4 ToolBox这个开源工具箱,多文件的SQL Generator的实现变得异常简单。[文中的例子可以从这里下载] 目录 一、多文件代码生成器会带来多大的便利? 二、创建自定义的Generator 三、ProcedureGenerator
蒋金楠
2018-02-08
8550
创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]
代码重构的艺术
所谓重构是这样一个过程:在不改变代码外在行为的前提下,对源代码做出修改,以改进程序的内部结构,从而使代码变得易于理解,可维护和可扩展。本质上来说重构就是在代码写好之后改进它的设计。
coder_koala
2020-12-17
7700
代码重构的艺术
《程序员修炼之道 - 从小工到专家》吐血解读
本篇文章是对《程序员修炼之道:从小工到专家》一书的总结和解读。 该书作者是 Andrew Hunt 和 David Thomas。他们都是敏捷宣言的17个创始者之一。Andrew还是敏捷联盟(Agile Alliance)的创始人。David 则是著名的 DRY(Don't Repease Yourself) 一词的发明者。这本书也广泛出现在各类计算机推荐书单之中,其受欢迎程度不言自明。 该书目前有两个版本,我阅读的是第一版: 第二版是这样的: 两版内容稍有不同。 刚毕业那会读过一遍,但有很多地方没看明
博文视点Broadview
2023-05-06
2470
《程序员修炼之道 - 从小工到专家》吐血解读
推荐阅读
代码生成器原理及示例
8840
手把手教你开发代码生成器,学不会的来怼我!
5030
ASP.NET MVC5+EF6+EasyUI 后台管理系统(59)-BLL层重构
1.2K0
我用过很多代码生成器,还是选了他
3700
广告
云开发个人版 免费体验1个月
数据字典生成工具之旅(7):NVelocity实现代码生成器
7680
.NET对存储过程的调用抽象封装
6620
代码重构之道
9200
JeecgBoot低代码平台 v3.6.0大版本发布—1024 程序员节快乐~
3500
使用 Source Generator 在编译你的 .NET 项目时自动生成代码
3940
从数据到代码——通过代码生成机制实现强类型编程[下篇]
9710
文档驱动式代码设计器——代码是设计出来的!
9590
20个代码生成框架 (.NET JAVA)
4K0
20个代码生成框架
2.9K0
代码重构之道
1K0
创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]
8550
代码重构的艺术
7700
《程序员修炼之道 - 从小工到专家》吐血解读
2470
广告
相关产品与服务
短信
腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档