2013年上半年项目总结

哎 不得不感慨一下 入职两年 终于要接触一个正规的项目了!


首先说一下系统架构

这次的项目是C/S架构的,但是以后有可能要将大部分功能移植到Brower甚至移动终端上,所以这次采用了面向服务架构。
用Java搭建提供数据服务的后台服务器;而客户端则是C#,一堆WinForm拖控件搞定。
面向服务听起来挺洋气,实际上无非就是提供一个带有某种约定的公共数据接口,只要按照约定的请求方式(路径),就会获取到数据。
当然发送和获取的数据都是字符串,所以我们是传输JSON格式数据,然后双方在各自转换,如下图


人员构成

总共10人:一个产品经理兼ScrumLeader,两个小组负责人,7个开发人员

这两个小组负责人也是70%的时间开发,30%的时间帮助小组的开发(查看组员的开发进度等)


C#端架构

C#方面分为Model(实体),IDAL(数据接口),DAL(数据接口实现),BLL(业务),Tools(各种工具类),Test(单元测试),UI(表现)七部分

其中 DAL部分使用有一个数据操作的工具类RestHelper(功能相当于DBHelper),是为了Rest而存在的数据处理类

大部分的业务数据处理逻辑都放在了BLL中。谈到业务层,刚开始的时候也是很纠结的,明明规划的是所有业务逻辑都放到BLL中,UI只负责显示。

可是开发一段时间后发现这很不现实,因为很多UI的变化也是一种业务,难道要把对UI的更新也放到BLL中?最后索性只将业务的数据部分放到BLL。不知道有其他什么好方案否。。

单元测试是用的微软自带的测试工具(VS2010中,右键->创建单元测试   相当简单的说)

.Net Spring

出于面向接口编程考虑,在C#端采用了.Net Spring。

首先要添加两个引用:①Common.Logging ②Spring.Core (这个需要自己下载)

然后在项目下添加Spring配置文件Spring.xml.config,内容如下

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
  <object id="XXXService" type="com.DAL.XXXService,XXXUI"></object>
 
  <object id="XXXManager" type="com.BLL.XXXManager,XXXBLL">
    <property name="service" ref="XXXService"/>    <!--这里的XXXService与上面的XXXService相关联-->
  </object>
</objects>

注:

  • com.DAL.XXXService --> DAL层的数据接口实现类
  • XXXUI --> DAL层的工程名
  • XXXService --> 该实现类的代理名,在调用该数据接口的业务层代码里会用到
  • com.BLL.XXXManager --> 业务实现类
  • XXXBLL --> BLL层的工程名
  • XXXManager --> 业务实现类的代理名,在调用业务的UI层代码中会用到

还要在工程的配置文件里添加上Spring的相关信息

如果是Winform程序的话,则是App.config文件,如果是Web程序的话,则是Web.config

在根节点<configuration>下添加如下内容

  <configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />
    </sectionGroup>
  </configSections>
  <spring>
    <context>
      <resource uri="http://www.cnblogs.com/spring.xml.config" />
    </context>
  </spring>

到这里配置工作就OK了,最后是调用。

View Code
//IDAL数据接口层  提供数据接口方法
namespace com.IDAL
{
    public interface XXXIService
    {
        int GetCount();
    }
}

//DAL数据接口实现层  使用DBHelper通过传递WebService的相关资源路径请求数据
namespace com.DAL
{
    public class XXXService
    {
        public int GetCount()
        {
            return DBHelper.GetCount("RequestRoot");
        }
    }
}

//BLL业务层  细看一下就会发现 业务层里的数据接口没有使用固定的实现类
//而是接口,只将其声明为了一个属性却没有赋值。而这部分工作就是Spring做的
namespace com.BLL
{
    public class XXXManager
    {
        private IXXXService service;
        public IXXXService Service
        {
            get { return service; }
            set { service = value; }
        }

        public int GetCount()
        {
            return service.GetCount();
        }
    }
}

//UI层 注意要添加下面两个using
using Spring.Context;
using Spring.Context.Support;
namespace com.UI
{
    public partial class XXXForm : Form
    {
        private XXXManager manager;

        public XXXForm()
        {
            InitializeComponent();
            IApplicationContext context = ContextRegistry.GetContext();
            manager = (XXXManager)context.GetObject("XXXManager");
            ooo();
        }

        public void ooo()
        {
            MessageBox.Show(manager.GetCount().ToString());
        }
    }
}

日志模块

在C#里,日志模块使用的log4net。这个网上的介绍很多 就不多说了。

这样C#端就大功告成了!

细节方面

Model层,IDAL层都需要各自的基类,如Model层需要一个基类定义可序列化(在类名上面加[Serializable])和分页属性(数据检索的大部分场合)
获取数据的时候会将对象序列化后的信息作为参数传递,这样后台就会得到分页数据了。
IDAL层中的基类是用于提供一些公用的方法,如单个对象的增删改,根据检索条件获取结果量等等。为了可以被其他类公用,必须是要有泛型的。

View Code
using System;
using System.Collections.Generic;

namespace com.IDAL.Base
{
    public interface ServiceBase<T>
    {
        /// <summary>
        /// 查询所有对象集合
        /// </summary>
        /// <returns>对象集合</returns>
        IList<T> SelectAll();

        /// <summary>
        /// 返回总行数
        /// </summary>
        /// <returns>总行数</returns>
        int SelectAllCount();

        /// <summary>
        /// 根据条件返回总行数
        /// </summary>
        /// <param name="item">条件对象</param>
        /// <returns>总行数</returns>
        int SelectAllCount(T item);

        /// <summary>
        /// 查询符合条件的对象集合
        /// </summary>
        /// <param name="item">条件对象</param>
        /// <returns>对象集合</returns>
        IList<T> SelectByObj(T item);

        /// <summary>
        /// 以一个对象作为条件修改对象数据
        /// </summary>
        /// <param name="item">条件对象</param>
        /// <returns>成功与否</returns>
        bool Update(T item);

        /// <summary>
        /// 以多个对象作为条件修改对象数据
        /// </summary>
        /// <param name="list">对象集合</param>
        /// <returns>成功与否</returns>
        bool Update(IList<T> list);

        /// <summary>
        /// 以一个对象作为条件删除对象数据
        /// </summary>
        /// <param name="item">条件对象</param>
        /// <returns>成功与否</returns>
        bool Delete(T item);

        /// <summary>
        /// 以多个对象作为条件删除对象数据
        /// </summary>
        /// <param name="list">对象集合</param>
        /// <returns>成功与否</returns>
        bool Delete(IList<T> list);

        /// <summary>
        /// 插入一个对象
        /// </summary>
        /// <param name="item">对象</param>
        /// <returns>成功与否</returns>
        bool Insert(T item);

        /// <summary>
        /// 插入多个对象
        /// </summary>
        /// <param name="list">对象集合</param>
        /// <returns>成功与否</returns>
        bool Insert(IList<T> list);

        /// <summary>
        /// 根据主键查询数据
        /// </summary>
        /// <param name="id">数据主键</param>
        /// <returns>单个对象</returns>
        T SelectById(int id);
    }
}

项目开发中的问题总结

1.不管是使用SVN还是VSS,代码的提交最好有一个固定的周期或固定的场合。
如每天下班前提交能成功运行的代码(要保证队友如果获取全部最新代码也能成功运行),或者一个功能模块完成后提交。
但是有些蛋疼的队友,自己都无法运行的代码你也提交上去,这不是害人呢么。别人获取之后就无法调试了,还要等你修改完,相当的不好。

2.项目开始前 对技术的了解不够。例如这次后台用Java,前台用C# 二者之间用JSON格式字符串传递数据。说起来简单,但实际开发起来之后就发现

C#与JAVA处理JSON格式数据时,实体类与JSON数据的双向解析方式有很多不同的地方。因为前期没有考虑到类似的问题会占用好多时间,所以队友的工期就会出现较大的出入。

原文地址:https://www.cnblogs.com/TiestoRay/p/2986490.html