当前位置: 首页 > news >正文

【开发心得】筑梦上海:项目风云录(1)

前言

来到上海以后,从业这么多年,碰到和见到了很多人和事,一直想写个关于软件项目管理的长篇,不过人微言轻的缘故,估计写了也没人看,索性就一直忙于学习和工作。

现在经济状况不好了,似乎项目也没有之前那么多,正好趁这个机会,慢慢的写点儿东西出来,为了自己将来能够回忆一下当年的拼搏,也为了当年一起奋斗的兄弟和同事留个念想。

就从公交ERP这个项目开始吧。

项目之初的争论

这个项目是多年前就完成的,是涉及大型公交企业的ERP系统,当时.net平台刚刚推出,项目组就决定使用C#作为开发语言。

回想起来,这个风险是很高的,在那个foxpro流行的年代,直接用新的开发语言,开发一个默认领域的项目,如果现在让我选择是否做项目经理,大概是没有这个胆量的。

但在当时来说,几乎所有人都很乐观,尤其是年轻的组员,他们认为:

1、可以通过这个项目提升自己的从业经历;

2、又能够用到最新最流行的开发语言;

只这两点,就已经够大家兴奋了。后面他们的跳槽成功,也说明他们的兴奋是有道理的,当然我也从中得到了很多好处。

但当时,由于自己是项目负责人(当时分工没有那么精细,是现在产品经理+项目经理的复合体),只有我是比较担心的,虽然也看好上面的两点,但是更加重视下面两个问题:

1、新语言不熟悉,会拖慢项目进度;

2、缺少领域专家,对公交业务要从零开始学习,难度很高;

由于存在上面的顾虑,所以在项目之初,项目组内部进行了不少争论和吵架。包括组员也进行了不少变动,有组员被调到其他项目的,也有离职的。当然也有新招聘进来的,回头看,这些都是一个软件开发团队正常的变动,只是当时作为项目经理的我,感觉有点儿焦头烂额。

项目误区

再小的公司,也有办公室政治,在当时,虽然得到了直属领导和老板的信任,但由于项目成立之初的人员,并不是我挑选的,里面参杂了各个部门的精英。作为负责项目的我,一开始是很满意的,毕竟这么多牛叉的程序员都归我管。

只要大家一门心思的去开发,困难总是能解决的。不过事实发现,我想的太简单了。以下先说两个误区:

1、关于团结:比如团队里有两个比较要好的员工,平时他们除了睡觉,几乎形影不离,开始我认为是好事,但后来发现,一旦有什么要求不符合其中一人的口味,他们两个会团结起来反对我,造成我只能让步,严重影响了项目任务的分配和进度,也严重影响了我的权威。

2、关于工作气氛:项目之初,老板送给我3本书,名字不太记得了,但都是微软团队管理方面的书籍,我利用晚上的时间全部阅读了一遍。里面讲了很多调动团队气氛的方法,也就是“团建”。后来发现,国内团队应用最多的是“搓一顿”。因此,也经常请团队成员吃饭,甚至是自掏腰包。但并没有收到很好的效果,对项目的进展帮助不大。

造轮子

说了这么多非代码的事情,下面是关于开发上面的重点。

现在可能稍微有经验的程序员都知道,接触到一门新语言,开发一个新项目,最重要最紧急的事情就是赶紧造轮子。不过我这里说的造轮子可能还有一层含义,是项目管理的造轮子。

不过还是先说代码领域的造轮子吧。

记得当时又要学习新语言,还要跟着甲方学习业务,回到团队还要把任务分解安排好,并协调项目进度,有些心力憔悴,好在当时精力充沛,熬夜也扛得住。

前后团队共有2个程序员参与并编写了造轮子的工作,其中第一个员工还用他的名字拼音作为类库名称放在整个项目中,因为表现突出,我默许了。

前面忘记说了,当时BS结构还没有流行,浏览器也没有现在这么强大,考虑到业务的复杂性,最终采用了CS结构,所以轮子也集中在控件上,下面罗列一些古董级别的文本框代码欣赏一下吧:

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;namespace Traffic.ControlLib
{/// <summary>/// CTextBox 的摘要说明。/// </summary>[ToolboxBitmap(typeof(TextBox))]public class CTextBox : System.Windows.Forms.TextBox, Traffic.ControlLib.IDataControl{/// <summary> /// 必需的设计器变量。/// </summary>private System.ComponentModel.Container components = null;const int DEFAULT_COMPLETE_LENGTH = 0;private int m_CompleteLength = DEFAULT_COMPLETE_LENGTH;private Queue retQueue = null;public bool ValidateResult = true;public CTextBox(){// 该调用是 Windows.Forms 窗体设计器所必需的。InitializeComponent();}/// <summary> /// 清理所有正在使用的资源。/// </summary>protected override void Dispose( bool disposing ){if( disposing ){if(components != null){components.Dispose();}}base.Dispose( disposing );}#region Component Designer generated code/// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器 /// 修改此方法的内容。/// </summary>private void InitializeComponent(){// // CTextBox// this.Validated += new System.EventHandler(this.CTextBox_Validated);this.Enter += new System.EventHandler(this.CTextBox_Enter);}#endregionprivate String[] GetCustomList(Queue q){if(q.Count!=0){String[] retArray = new String[q.Count];q.CopyTo(retArray,0);return retArray;}return null;}private void CTextBox_Enter(object sender, System.EventArgs e){if(retQueue == null||(retQueue.Count==0))return;// create an AutoComplete objectShellLib.ShellAutoComplete ac = new ShellLib.ShellAutoComplete();// set edit handleac.EditHandle = this.Handle;// set optionsac.ACOptions = ShellLib.ShellAutoComplete.AutoCompleteOptions.None;ac.ACOptions |= ShellLib.ShellAutoComplete.AutoCompleteOptions.AutoSuggest;ac.ACOptions |= ShellLib.ShellAutoComplete.AutoCompleteOptions.AutoAppend;ac.ACOptions |= ShellLib.ShellAutoComplete.AutoCompleteOptions.UpDownKeyDropsList;// set sourceShellLib.SourceCustomList custom = new ShellLib.SourceCustomList();custom.StringList = GetCustomList(retQueue);ac.ListSource = custom;// activate AutoCompleteac.SetAutoComplete(true);}private void CTextBox_Validated(object sender, System.EventArgs e){if(this.retQueue == null)return;if(this.retQueue.Count>=this.CompleteLength)this.retQueue.Dequeue();this.retQueue.TrimToSize();this.retQueue.Enqueue(this.Text.Trim());this.ValidateResult = true;}private void OnKeyDown(object sender, System.Windows.Forms.KeyEventArgs e){//MessageBox.Show("keydown");}[	Category("Custom"),Description("To set or get the ListDown length for auto complete."),DefaultValue(DEFAULT_COMPLETE_LENGTH)]public int CompleteLength{get{return  m_CompleteLength;}set{m_CompleteLength = value;if(m_CompleteLength != DEFAULT_COMPLETE_LENGTH){retQueue = new Queue(m_CompleteLength);}}}[Category("Custom"),Description("To get or set the value of this control.")]public string DataValue{get{return this.Text.Trim();}}public bool PutEntityToValue(){try{this.Text = this.Tag.ToString().Trim();return true;}catch{this.Text = string.Empty;return false;}}public bool PutValueToEntity(){try{this.Tag = this.DataValue;return true;}catch{try{this.Tag = string.Empty;return false;}catch{this.Tag = 0;return false;}}}}
}

陆陆续续的,一共造成几十个各类轮子,给开发统一和快捷带来了极大的便利。这两位造轮子的同事,一直到现在都很欣赏他们,可惜后来各自都离开了公司,奔向了更大的前途空间。

未完待续。。。


http://www.mrgr.cn/news/12576.html

相关文章:

  • ARM程序的组成和执行过程
  • Kafka简单搭建及常用命令
  • 【数据结构与算法】深入理解归并排序(Merge Sort)
  • 一个简单的springboot项目(有源码)
  • Threadlocal+拦截器+JWT实现登录
  • 【Docker项目实战】使用Docker部署webtop桌面版Linux环境
  • 华为手机数据丢失如何恢复?
  • golang本地缓存fastcache高性能实现原理
  • sqlite3 在Python中使用
  • 筑牢技术防线:服务器故障后的应急响应与未来防范策略
  • 2024年8月22日嵌入式学习
  • Linux——文件系统层次结构,绝对路径
  • 视频提取字幕的软件有哪些?5款高识别率工具任你选
  • SpringBoot文档之构建包的阅读笔记
  • spring security怎么解决用户的权限问题
  • SAP 有趣的‘bug‘ 选择屏幕输入框没了
  • 小白之 FastGPT Windows 本地化部署
  • Linux内核定时器
  • 5G SSB(Synchronization Signal/PBCH, 同步广播块
  • HarmonyOs应用权限申请,system_grant和user_grant区别。本文附头像上传申请user-grant权限代码示例