zoukankan      html  css  js  c++  java
  • 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数据的双向解析方式有很多不同的地方。因为前期没有考虑到类似的问题会占用好多时间,所以队友的工期就会出现较大的出入。

  • 相关阅读:
    Java基础系列1:Java基本类型与封装类型
    深入理解设计模式六大原则
    分布式系统ID生成方案汇总
    微服务入门
    Web攻击技术
    Jedis与Redisson选型对比
    Hystrix分布式系统限流、降级、熔断框架(二)
    可重入锁ReentrantLock实现原理
    Hystrix分布式系统限流、降级、熔断框架(一)
    Redis过期策略、持久化、集群与常见缓存问题
  • 原文地址:https://www.cnblogs.com/TiestoRay/p/2986490.html
Copyright © 2011-2022 走看看