如何摆脱烂项目的纠缠

摆脱烂项目
服务器君一共花费了168.762 ms进行了5次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

有没有这样觉得,以前做过的,刚做完的,或者正在做的项目,简直就是狗屎,不想去维护,不想去看以前写的代码?如果有,那么我们可以继续下面的内容。

分析一下原因,项目为什么会烂,从纯技术上去看无非有以下两个问题:

  • 项目架构烂
  • 代码质量差

下面我们各个击破,分别说说我的一些愚见。项目架构往往是项目经理,架构师,团队中技术较好程序员,或者呆公司较久程序员的事,由于对架构的理解不同,做事方式不同,项目的周期不同,技术选型不同,所以架构也就形形色色,但以我看来较鲜明的也就是较为守旧的数据库先行,和时下流行的领域驱动。这两者有明显的区别,我觉得后者在架构上更有优势,前者在开发周期上更有优势,而且不需要很多前期设计,但是优雅程度远不及后者,但在外包公司或者遇到很急的预算不多的项目往往会选择前者。

数据库先行架构的一般流程:

  1. 需求分析
  2. 设计数据库
  3. 编写或使用工具生成实体类(DTO)
  4. 编写逻辑

领域模型架构的一般流程:

  1. 需求分析
  2. 分析业务,整理领域对象,划分对象之间关系(理出聚合根)
  3. 为领域对象写行为

两者共同点:都可以采用AOP,面向对象,设计模式来提升程序的可维护性,但后者面向对象的味道更浓,从架构上讲有先天的优势。

数据库先行给项目带来的问题

1. 由于依赖数据库,团队中多数人更喜欢写sql,写sql不是坏事,但是太多的sql,甚至逻辑都采用写sql去处理,势必造成可维护性降低,原因如下:

  • sql先天性决定,sql没有面向对象的概念,这意味着,它的抽象层次较低,流程式的代码很难做到高维护性,高封闭性,很多相同逻辑的代码需要重复写在不同的存储过程里面,虽然可以提炼到函数或者另外的存储过程中,但那是个不容易的事。
  • 既然很多逻辑写到数据层面,那比如时间的处理,数据的转换,验证,错误的处理,很大程度也都依赖数据库,很明显,数据库相对于面向对象的语言并不擅长。这样做几乎让项目的可维护性降到最低。
  • 缺少或薄弱的现代IDE的很多编码优势,如智能提示,编译期纠错,这一点使可测试性大大降低,你甚至很难做单元测试。

当然优点也有,那就是易于发布和性能会略高一筹。 

2. 较好的方式,是把逻辑写到代码里,数据库只用来持久化数据,这里又有两种风格

  • 使用ORM,sql为框架生成,这种方式普遍,好处是有成熟的ORM框架(如EF,NHibernate等)帮我们生成Sql,我们省去了在代码里写Sql造成如,可维护性低,被sql注入的风险,且能享受代码智能提示,编译期纠错等待遇。
  • 写存储过程,这里与上一点的不一样,这种方式只是将CRUD操作写成存储过程,逻辑写代码里,这种方式的优点是利于发布。缺点是要手动写实体类和存储过程,不过我们可以使用工具生成。

数据库先行的优点

  • 架构没什么复杂性,容易被团队成员理解,容易交流
  • 开发周期短,成本低

说说领域模型,它更像是一种思考问题的方式,它的出现就是为了为软件开发提供一个切实可行的指导思想,里面包含太多思想,包括软件开发原则,OO思想,解决问题的思路,如何易于测试,AOP,等,感兴趣的朋友可以去系统的学习一下,会有收获的。

以上是架构上的问题,如果你有空间和时间建议你的考虑了顺序为:

  1. 领域驱动
  2. 数据库驱动,采用ORM,逻辑写程序

其他方式慎用。

回到开篇,再来说说如何写出优雅的代码,其实这是一个累积的过程,当然前提是你在进步,进步是因为你意识到自己写的代码不够优雅打算改进而采取学习和重构的结果。所以当你觉得代码烂的时候,不要放弃,不要破罐子破摔,重构吧。既然要重构,就得找到需要重构的代码,我能想到的烂代码有:

1. 过长的方法

这里是指,方法内容太长,发生这种情况,往往是封装不好的结果,往往在一个方法里去实现一个业务,而这个业务其实可是拆开到不同的对象中去,也就是这个操作不够原子性,举个例子,人喝可乐这个需求,业务流程应该是这样:给人一瓶可乐,人需要打开瓶子然后喝到不渴为止。

伪代码如下:

public class Person
{
	pubic void Drink(Bottle bottle)
	{
		if(bottle == null)
			 bottle = new Bottle();
		if(cola.Capacity <=0)
			 throw new Exception("没有可乐");             
		
		if(!bottle.IsOpen)
		 {
	         this.LeftHand(bottle); //左手拿瓶子
	             this.RightHand(bottle.Kou);//右手拉环
			  this.pull();//拉开
		 }
		 var needCapactity = xx+yy-zz;  //
		  while(cola.Capacity <=needCapactity )
		  {
				cola.Capacity--;
				cola.Refresh();
				this.ColaCapacity++;
				this.Refresh();
	      Thread.Sleep(1000);
		  }
	}  
}

当然这段代码并不长,只是为了说明方式,看得出来,这里的问题有,验证逻辑,获取需要喝的容量,开盖的方式都写到里面。

2. 硬编码的字符串和数字

if(age>50)
if(city.ToLower()=="shengzhen")

3. 职责不分明的类

4. 重复的代码

其实提高代码的重用,有几个途径:

  • 继承
  • 工具方法
  • 使用委托

前两点都很容易理解,说一下这一点,举个DataContext事务的例子。

using(var context = new DataContext())
{
     context .BeginTransaction();
     try
    {
      context.User.GetUser();
      context.User.add(new User{name="xian"}); 
      context.User.add(new User{name="hong"});
      context.Commit();
   }
  catch
  {
     context.Rollback();
  } 
}

以上代码很常见吧,是不是每个使用事务地方都需要这么写,其实这个时候我们可以利用委托来实现。

public class DbInvoker
{
	public void Transaction(Action<DataContext> aciton)
	{
		using (var context = new DataContext())
		{
			context.BeginTransaction();
			try
			{
				aciton(context);
				context.Commit();
			}
			catch
			{
				context.Rollback();
			}
		}
	}
}

以后用到事务的地方这样调用就行了。

DbInvoker.Transaction(context=>{
      context.User.Add(new User{name="xian"});
      context.User.Add(new User{name="hong"});
});

是不是方便了许多?

5. 意义不准确的命名

6. UI与逻辑隔离差

这个最典型的我觉得就是比如在做WEB时,用MVC框架,却在后端网前段输出js的引用,或者长篇js,客户端的东西了。

我就不一一举例子了,最后说一句,优秀的开源项目要多看,感谢你的阅读。

本文地址:http://www.nowamagic.net/librarys/veda/detail/2305,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/2305

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《PHP经典实例(第2版)》 斯克拉(David Sklar) (作者), 切贝特伯格(Adam Tracbtenberg) (作者), 李松峰 (译者), 秦绪文 (译者), 李丽 (译者)

PHP经典实例(第2版)能够为您节省宝贵的Web开发时间。有了这些针对真实问题的解决方案放在手边,大多数编程难题都会迎刃而解。《PHP经典实例(第2版)》将PHP的特性与经典实例丛书的独特形式组合到一起,足以帮您成功地构建跨浏览器的Web应用程序。在这个修订版中,您可以更加方便地找到各种编程问题的解决方案,《PHP经典实例(第2版)》中内容涵盖了:表单处理;Session管理;数据库交互;使用Web服务。

更多计算机宝库...