早前发文说要分享,马上进入了财务系统的开发,拖到现在,见笑了。

我在月初离职了,所以到处跑,找工作,想想南京、苏州、无锡(去玩的)、杭州(路过)、上海、珠海、深圳、广州。觉得找工作也差不多尾声了,就留点时间把这篇发出来吧。

总体来说,就是我在毕业三个月后来到这里,然后从零开始造轮子造了一个还算健全但不算完整的OA系统。

做了不少系统/模块,有很多都能写好多篇文章。毕业后这两年太神奇了,简直是在刷.NET,从一开始WPF,然后WCF、WF、MVC、EF、前端越刷越多。刷多了也有缺点,深入不足吧,总得有得失。

流水账是个好方式,那就流水吧,这里是我最后一份工作,23个月的事情。

初出茅庐

  作为一个应届毕业生,我不知道公司会给到什么资源,会有什么话语权,会有什么安排,一开始到来必定是战战兢兢的。虽然我知道招聘的时候说明就是做OA,公司标榜自由平等开放,开始也会无所适从。我以为会分派具体任务,不过协助了一个即将发布的项目后,马上就开始了OA的旅程。那种精确具体的节奏到发散的节奏,从一家外企跳过来,还是无所适从。

  不过,我很大胆,或者说,哪怕在上家公司那么严谨,技术上的看法我从不掩饰。我只是个程序员,没有比不能坚持和直述自己技术意见更糟糕的了吧。

  我当然会跟感谢上司对于我的信任和公司提供的机会,换个地方或许我被炒好多次了。

蓝图,大系统变成“小系统s”

  这是我和上司和老员工们的第一个争吵点。

  我和一些同事交流,了解过公司的“快”文化,也了解了项目寿命不长的问题。作为创业公司,拿到最后一轮融资到上市不过一下子,并没有暴利支撑着公司可以持续地“输”,但创业时期的“快”方式根深蒂固,很多项目为了快速完成,要么外包,要么是实习生或者快速搭建快速失败的。公司的主业务尚好,可以有持续投入,但OA显然不是主业务。虽不至于有“上了贼船”的感觉,但是我非常清楚地感觉到,我们只有一颗子弹,打中了才会发给你下一颗。

  我会去开这一枪吗?没有,这不是会不会的问题。如果规则本身有问题,我就直说,然后解决它。所以我提出了,将系统设计为业务分布式的系统。这也促成了OA的第一个子系统——Message Center的诞生。MC就是这个整个OA的消息中间件,也是至今Bug最少的系统,因为它的功能很简单,就是一个发布/订阅模式的消息中转系统。

  我的想法就是把OA拆成多个功能独立的子系统,不仅功能独立,运行也独立,仅仅通过MC进行服务的发布和订阅来通信、协作,也就是一种SOA概念的实现。为了实现单一原则,基本上,连系统调用自身的功能,都要通过中转调用服务。

  敢这么做的另一个原因是我预计公司封顶也就1000个员工,那么这些系统都不是高负载型的,业务的变化率才是系统的性能瓶颈。

  技术人员的天真我也有,你以为你的想法很容易,但是要别人接受却不容易。伙伴的想法原本是一个大型的系统,而且以往开发的做法和大家对OA原本的设想也是如此。实际上如果出一个需求做一个,最后形成的结果估计是一堆系统共用一个数据库,然后业务复杂度和数据库复杂度都在膨胀。甚至我觉得这不叫B/S,干脆就是B/D,不过就是堆砌的事务脚本。这给我感觉就是前人挖坑后人填坑再挖坑。

  好在我有耐性,大家也都有耐性,愿意为实现花时间讨论的团队其实挺幸福的。我不记得多少次从下班跟大家争论到9、10、11点,多少次长时间地说服、争论、设计、重构、妥协。是的,还有妥协。

  我的做法当然彻底,每个系统既然独立,那么该独立数据库、用EF而且允许UI层LINQ读操作而限制写操作、纯面向对象去除表存储概念、所有通信只通过消息中转、仅用Nuget同步子系统间的代码。为这个,大家开过会,我介绍了EF,说明过很多细节为什么要这么做。这个过程是很锻炼人的,因为要说服别人首先要说服自己,而说服自己的唯一方法是了解更多。特别是当双方“斗争”白热化的时候,双方思想都会迸发出最灿烂的火花,我从他们那里拿到的技术经验、业务经验、想法,对于项目成功必不可少。

  这样,就有了第一个系统,作为中心的MC。如上所说,是个发布/订阅模式的消息中转,它不作任何状态保留,只转发消息,基于WCF实现,提供了一个Nuget上的Client。现在,它还有了同步/并发转发的功能,同时是一个可平行部署的系统。按照原本打算,二期的话应该具备日志、消息失败处理、异步消息、缓存的能力、.NET外平台客户端API。或许应该单独写一篇再分享吧。

  这是半年之前的图,如今,基本上OA就是在这基础上扩充的:

认证系统,从这里进去,从这里到任何地方去

  我的想法并不能完全实施,认证系统(Authorization)就是一部分。认证系统和考勤依然并在了一起,通过账户权限让它“看起来”是独立的数据库而已。不过这无伤大雅,对于一个连蛋都还不算的系统,在实现里该有一定妥协,时间会校验它的。

  认证系统是同MC相差不远,我要做的是一个对整个OA单点登录和权限的支撑。

  登录方面,它的主要问题是因为拆分系统产生的跨子域问题。我测试然后实现了跨域登录的问题,非共同公共域授权登录的问题,然后花了一段时间去解释登录失败的原理和跨域的原理。权限的话是一个权限-角色-用户的模型,想必许多权限系统也类似。前文下面也有权限管理界面的配图,顺带说一下我选择了使用Metro的扁平化风格,毕竟连设计师都没有,UI和交互得自己想。

  在上个星期,我又为权限添加了一个基于语法分析的动态授权模块,以解决业务授权太多管理膨胀的问题,还有业务规则变动太大的问题。这个模块的功能,就是把动态写的授权表达式如“Accounts(1).Groups("IT部门").Accounts(Role="经理")”,解析成“账户1在IT部的经理”,来进行或者确定业务的授权对象。由于是写了一套简单的语法设置、语义分析、表达式计算的功能,所以能支持更多的语法,也会陆续添加更多语法。算法自己还不是很满意,希望有做过编译器或者比较了解的朋友能提供点帮助或者交流下。

工作中心,从这出发

  工作中心(Work Station)就是传统意义上的Portal,是整个OA登录后的默认入口,同时还包含了考勤系统。考勤系统是我和同事以及外包同事共同开发的,是个业务类别系统,包含了考勤统计和审批的功能。

  在前文里可以看到WS的界面是平铺着各个系统的条目的,这不是设计原意,原意是留给一个用户订阅的主页,根据订阅获取到相关信息。不过看到这里你们也知道,这个系统还什么都没有,所以只能用连接填充。

即时通信引擎,就是现在

  可能在公司的设想中,我这是不务正业。在我看来,我们需要一个即时通信的系统,能够将系统消息第一时间推送给用户,这比定更多的业务规定有效得多,重要的是即时通信、即时解决。

  它完成在我不知道有SignalR之前,所以手写长轮询实现了。三周时间,我将它实现了,并挂上了Azure的试用账号做公开测试。它并不完美,因为我发现流量占用太大,所以不得不重写很多代码,把原来的全量获取值全部改成了增量算法。虽然不幸工作量突然大增,但成果让人满意,也走进了Callback Hell,至今还没解决。

  总体来说,它实现了即时添加好友、多人即时通信、系统消息、用户系统互相通信的功能。十分感谢当天参与测试的朋友。

  后来,同事做了微信的服务端后,这个系统也成功通过消息中转给微信用户推信息了。

前端框架,用jQuery造的轮子

  这是个大胆的做法,因为我抗拒了BootStrap。BootStrap很快,很全面,大家也都在用。网上社区里红红火火的,大家都会跟风说这个多好怎么好。

  但是,这不是我想要的。一方面,在前端我不相信有一个包含样式的框架能成为一套长久的标准,何况还是一种大众化的事物;另一方面,我不想将整个交互模式交予第三方之手,长久来说这将会有后遗症。我恐惧一种情形,就是在BootStrap的大框架前提下,整合了各种插件,最后为了一个又一个无聊的Bug打一个又一个连自己都不大理解不大能维护的补丁。

  所以我写了自己的一套简单的前端框架,命名很简单,就叫OA Style。

  OA Style为了实现一套扁平风格的样式,类似Metro,将主体集中在信息上,不作各种圆角什么的多余的样式,仅仅为了看起来简单、用起来简单。它的设计理念是兼容、原生、简单和易用。这套样式尽可能地兼容着原生的HTML控件样式,重写的成本一个控件套一个控件加一堆样式的方式让我心生厌倦。在此之上,我再继续开发着按钮、翻页表格、拖柜式弹出框、重写Alert、多重度色彩。它依然很轻,因为它依然在开发状态中。

  我从前认为这些简单的样式实现也简单,但当做起来的时候发现十分不一样。我不得不去“学习”审美,学习配色、对比、对齐、布局方式,才能满足最基础的视觉心理。

  这个学习的过程在项目中变化,大概可以让大家看到:

工作流引擎,赶上变化

  当然,是没办法做到网页工作流编辑器的了,这样就不是按月为单位算得工作能实现得了的。实现方式是在Windows Workflow上加皮,而且数据隔离开,因为未来可能会自写底层,现在先解决能用的问题吧。

  我实现的引擎,是实现了多个关于自有流程、审批等的Activity,再用VS设计器设计工作流,将XAML上传到工作流后台并提供该流程服务的引擎,所以我只叫它引擎。

  与它配合的,还有一套在财务系统中实现的动态申请单模块,动态的申请单加上动态的工作流,支撑了业务变动十分大的系统。当然,还有之前说的,动态分析授权的模块。

财务,最痛然后再站起来

  这是最痛的地方,因为它失败了一次。失败的版本由于计算正确性无法达到要求,所以我提出重做。

  我参与了一半需求的会议,不过中途就转回了上面系统的开发。在开发中途加入到了上一个版本的财务系统,当时是和外包同事协作。从看到项目起我已经产生了抗拒感,如果我是处女座,我已经被逼死了。反正,这个项目我有参与,但是它失败了,然后我提出重做,然后今年就由我来重做。

  但是到了今年,就没有外包的资源了,要求却定会比上一个高。这是财务预算控制的部分,也差不多是财务工作的一个大头,从定制预算到预算使用的审批。

  我从来都不怕尝试新鲜事物,所以我引入了DDD的方式。这是第一次这么做,是一直以来一个直觉,虽然到现在我都还没深入理解过DDD。

  首先是撰写了一份文档,这份文档定义了系统设计到得知识和我抽象“创造”的知识,比如货币、汇率、预算、周期预算。这份文档说明了对于这些知识的定义,对它们的操作方式,规则。你可以视为这是一份需求分析,但我更倾向于当做一份基于需求分析产生的共有知识体系。因为用这份文档,我做得更彻底。

  首先如上面所说,我用EF彻底“剔除了”数据存储的概念,纯粹地把领域对象用面向对象实现;然后,把代码,用文档“生成”。是的,文档将知识和层级分为了四部分,那么领域层就有四部分;文档定义了实体的关系如何,我在EF设计器中就如何设计模型;文档定义了怎么操作,我就怎么定义工作单元;虽然不用中文方法名和属性名,但是命名都是按照自然语言语义化的。

  这么彻底,仅仅为了统一整个知识体系。虽然我没有细读DDD,但是在我看到的、感觉到的和我想要的,就是这个样子。整个项目只有一个知识体系,没有什么表、关联、增删查改、读取插入、存储同步,只有创建、添加、更新、调整、转账、记录。

  后面工作越来越不在状态了,有公司的事,也有自己的事,慢慢放慢了节奏。

  现在离职了,项目是交接了,不知道成败如何。

微信,这是个惊喜

  微信的服务端是同事实现的,这是个最大的惊喜。

  我们的微信客户端有打卡、考勤、投诉、查阅、简单办公的功能,而且在很短时间久实现了。这是同事的功劳,也是对我架构设计的最大肯定。

  一切功能,除了在微信实现,在底层,不过是接入了MC。上面所说,我们所有的功能都通过MC发布了,只需调用即可。我相信这样的设计不仅仅会对微信,还会对将来的移动客户端有着同样地推进效果。

OA还有更多

  要知道,我们是个共五人、正职二人的团队,所以同事还有其他方面的实现,主要是业务方面,他的经验阅历都更为老道,各有所长各尽其职吧。

  基于上面基础,同事完成了HR得人员管理系统、薪酬管理、传阅功能。同时,OA还支持着一个CRM。在计划中,公司原本游离在外的各自独立的系统会逐步统一账户体系接入OA,最后把从内到外的系统统一在一个SOA体系下。

  在计划中,我打算为MC加入上面所说的功能。MC集中了所有内容后,一切围绕它展开就变得轻松和理所当然了。你监控它就可以监控真个系统的运作,因为所有独立的系统必定要通过MC来跟其他支撑系统合作才能完成业务。所以你在MC可以监控、日志、缓存来让整个系统变得高效可靠,这也是我想去实现的。

  上面的系统,或者仅仅成为模块,都有很大的创造空间能做得更好。比如账户我想更丰富内容,我想做个社交化的办公环境,我想通过提供有限组件做个简单可靠的工作流设计器,......

  我还应该做一个文件系统,当然考虑的就是权限、吞吐量、存储的这些问题了,自当去学习便是。

我还有更多

  说真的,今年在公司过得确实不算开心。去年公司业绩不好,没有年终,...,好吧,有一个热水壶......

  在这之后,公司进入了一个紧张的状态,各种丑态“原形毕露”来形容不为过。然后IT部门一片一片地走,一开时是移动集体逃脱,然后前端群去了网y,接着Java的一片w品h,各自飞散,难得0离职的.NET团队抽调正在做iOS了。在薪酬的敏感问题上处理不当,更是让人不爽。

  我cc过全部门抗议过总监的安排、投诉过饭堂、和CEO直接谈过,这样还是符合个人性格的。我就是个程序员,有话最好直说,免得太别扭。

  公司也不差,给了我一个梦幻级的工作环境,至少秒杀大部分公司吧。今年拼命的机会少了,毕竟没那么好心情了,反而世界大了。跑步断断续续跑个二十几圈还可以,入门了钢琴,旅游了两次。人在广州啊,吃了不少东西,各种各样,挺不错的。

  下一份工作不知道会是什么样的,期待一下也不错。

  

从零到有——我的OA如何成长的更多相关文章

  1. OA发展史:由点到生态

    在当今无边界组织的商业背景下,企业与员工关系已经转化为联盟关系,以往通过工作场所.劳动合同等约束的形式已经逐步弱化,管理行为空前复杂,OA正是将一个个散点整合起来的看不见的手.那么,推动OA发展的核心 ...

  2. 浅谈OA系统与Portal门户的区别

    随着社会信息化的发展与进步,OA办公自动化软件打破了传统复杂的办公方式,使各个行业实现了高效的无纸化办公.由此一来OA快速成长为继财务软件.ERP软件之后的第三大管理软件.随着企业信息化系统的不断增多 ...

  3. 一秒钟看懂SaaS、CRM、OA、ERP、HR、进销存

    自2014年以来,SaaS.CRM.OA.ERP.HR.APM.进销存.财务系统等,这些名词大量出现在微信朋友圈.电视楼宇广告和千百万融资资讯中.它们到底是什么意思?相互之间又有什么区别?在这个飞速发 ...

  4. 九思老客户分享:部署OA办公系统的四大意义

    原文:http://www.jiusi.net/detail/472__776__4009__1.html 关键词:OA办公系统.oa系统 .九思OA 九思老客户分享:部署OA办公系统的四大意义 当今 ...

  5. OA系统在实际应用中可发挥出的协同应用价值

    OA软件引进国内已有二十多年,早期的OA软件更多地是扮演一个"文秘"的角色,只进行一些基本的行政事务处理,创造的价值不大.但随着OA软件理论和技术的日趋成熟,OA软件摆脱了原有的局 ...

  6. 作为一个零基础的新手,如何系统的自学Java和JavaEE开发技术?

    其实这个问题很简单,我用最简单的语言给大家描述一下,学习一样东西就要了解这样东西学完了要干什么事情,有什么作用.然后就是应该学习哪些必要的内容,该如何运用得当的方法进行有效率的学习不至于自己摸不着头脑 ...

  7. Android端IM应用中的@人功能实现:仿微博、QQ、微信,零入侵、高可扩展

    本文由“猫爸iYao”原创分享,感谢作者. 1.引言 最近有个需求:评论@人(没错,就是IM聊天或者微博APP里的@人功能),就像下图这样:   ▲ 微信群聊界面里的@人功能    ▲ QQ群聊界面里 ...

  8. 感悟优化——Netty对JDK缓冲区的内存池零拷贝改造

    NIO中缓冲区是数据传输的基础,JDK通过ByteBuffer实现,Netty框架中并未采用JDK原生的ByteBuffer,而是构造了ByteBuf. ByteBuf对ByteBuffer做了大量的 ...

  9. 开源OA办公系统的“应用市场”,能够为协同办公开拓什么样的“前路”?

    在我们的日常生活中,应用市场这个词,总是与智能手机划上等号,不管使用的是iPhone还是安卓,总会接触到手机上的APP应用市场,我们可以在应用市场中,选择自己所需要的APP应用软件,下载使用后,可以让 ...

随机推荐

  1. 百度推出新技术 MIP,网页加载更快,广告呢?

    我们在2016年年初推出了MIP,帮助移动页面加速(原理).内测数据表明,MIP页面在1s内加载完成.现在已经有十多家网站加入MIP项目,有更多的网站正在加入中.在我们收到的反馈中,大部分都提到了广告 ...

  2. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  3. HashSet HashTable 与 TreeSet

    HashSet<T>类 HashSet<T>类主要是设计用来做高性能集运算的,例如对两个集合求交集.并集.差集等.集合中包含一组不重复出现且无特性顺序的元素. HashSet& ...

  4. Android Ormlite 学习笔记1 -- 基础

    Ormlite 是一个开源Java数据实体映射框架.其中依赖2个核心类库: 1.ormlite-android-4.48.jar 2.ormlite-core-4.48.jar 新建项目,引用上面2个 ...

  5. zookeeper源码分析之二客户端启动

    ZooKeeper Client Library提供了丰富直观的API供用户程序使用,下面是一些常用的API: create(path, data, flags): 创建一个ZNode, path是其 ...

  6. 纸箱堆叠 bzoj 2253

    纸箱堆叠 (1s 128MB) box [问题描述] P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n, p, a 之后,即可自动化生产三边边长为 (a mod P, a^2 mod p ...

  7. 统计iOS项目的总代码行数的方法

    打开终端, 用cd命令 定位到工程所在的目录,然后调用以下命名即可把每个源代码文件行数及总数统计出来: find . "(" -name "*.m" -or - ...

  8. 借助GitHub托管你的项目代码

    PS:话说自己注册了GitHub都很久了,却没有怎么去弄,现在系统学习一下,也把自己的学习经历总结下来share给大家,希望大家都能把GitHub用起来,把你的项目代码happy地托管起来! 一.基本 ...

  9. Leetcode 笔记 113 - Path Sum II

    题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...

  10. 架构设计:一种远程调用服务的设计构思(zookeeper的一种应用实践)

    在深入学习zookeeper我想先给大家介绍一个和zookeeper相关的应用实例,我把这个实例命名为远程调用服务.通过对这种应用实例的描述,我们会对zookeeper应用场景会有深入的了解. 远程调 ...