复杂业务简单化

复杂业务简单化的一个小技巧

在复杂系统中,当对业务数据进行“删除”时(一般不允许对业务数据进行删除,只是举例) ,需要根据其它业务数据进行判断如:

  1.已生成出库单不允许删除,

  2.付款单已确认不允许删除,

  3.已经退换货则不允许删除。

  实际业务中可能会更加复杂。

当出现这种情况时将导致“删除”业务判断会非常多,而且会经常修改,很有可能当其它业务发生变化时需要重新去调整“删除”业务。

解决方法:为业务数据增加一个中间件“是否可以删除的标识”其它业务发生变化时修改此标识为false  其它业务修改时不能将此标识改为true 删除时只根据此标识做判断,可能会手动修改业务标识(高级操作)

不能将此标识改为true是因为 改为true需要去做很多验证,为了避免复杂性所以不能修改标识为true。

如:用户提出需求“自营店,可以修改价格,可以添加赠品,不扣预存款。非自营店,不能改价格,不能加赠品,扣款存款”

程序设计时最好别把 “自营或非自营”做为判断条件,而将“是否允许修改价格,是否允许添加赠品,是否扣除预存款”做为判断条件,对店铺(业务数据)增加相应的控制开关配置。

这样可能很好的提高程序扩展性,未来业务发生变化时可以不用修改代码。比如 需要"非自营店可能添加赠品"时。

对业务数据的控制开关配置可以使用key/value形式通一设计持久化保存,这些开关拒绝和业务数据的查询有联系。

注意事项:1.如果系统中大量使用开关配置,会经常会开关配置进行修改,需要考虑并发性,防止多个业务同时对相同的控制开发进行修改。

2.此类配置不会做为数据检索条件

以上是工作中记录内容,分享相应的处理代码,希望对你们有用

/// <summary>
/// 数据配置类
/// </summary>
public class SmartConfig : BaseEntity
{
/// <summary>
/// 类型
/// </summary>
[MaxLength(32)]
public string Type { get; set; }
/// <summary>
/// 类型标识
/// </summary>
[MaxLength(32)]
public string TypeIdentity { get; set; }
/// <summary>
/// 时间截
/// </summary>
[MaxLength(32)]
public string Timestamp { get; set; }
/// <summary>
/// 配置
/// </summary>
public string Config { get; set; }
}

这是Table对应的实体类,用于数据存储。

/// <summary>
/// 业务数据配置类
/// 请勿直接new这个对象,使用SmartConfigService.Get 方法获取对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks>2014-08-20 ywb 创建</remarks>
public class Smart<T>
{
/// <summary>
/// 请勿直接new这个对象,使用SmartConfigService.Get 方法获取对象
/// </summary>
/// <param name="typeIdentity"></param>
/// <param name="timestamp"></param>
/// <param name="config"></param>
public Smart(string typeIdentity, string timestamp, T config)
{
this.Timestamp = timestamp;
this.Type = typeof(T).Name.Replace("C_", "");
this.TypeIdentify = typeIdentity;
this.Config = config;
}
/// <summary>
/// 业务数据类型
/// </summary>
public string Type { get; private set; }
/// <summary>
/// 业务数据标识
/// </summary>
public string TypeIdentify { get; private set; }
/// <summary>
/// 时间戳
/// </summary>
public string Timestamp { get; private set; }
/// <summary>
/// 配置
/// </summary>
public T Config { get; private set; }
}

业务数据配置类

/// <summary>
/// 菜 配置
/// </summary>
/// <remarks>
/// 约定命名规则为 前缀“C_ ”+ “业务表名”
/// 这种方式不太符合规范但是好用,配合VS智能提示写代码方便
/// </remarks>
public class C_Dish
{
public C_Dish()
{
//在构造函数中设置配置项的默认值
NeedCooking = true;
EnabledPrint = true;
Return = false;
AllowToCart = true;
}
/// <summary>
/// 需要厨师烹饪
/// </summary>
[Description("需要厨师烹饪")]
public bool NeedCooking { get; set; }
/// <summary>
/// 状态为“完成”时可退
/// </summary>
[Description("状态“完成”时能退")]
public bool Return { get; set; }

/// <summary>
/// 启用打印
/// </summary>
[Description("启用打印")]
public bool EnabledPrint { get; set; }

/// <summary>
/// 允许顾客点餐
/// </summary>
[Description("允许顾客点餐")]
public bool AllowToCart { get; set; }

}

这是具体业务拥有的配置,在构造函数中设置业务数据配置项的默认值

/// <summary>
/// 配置Service
/// </summary>
public static class SmartConfigService
{
/// <summary>
/// 更新 SySmartConfig
/// 如果返回false 很可能是并发引起的,需要业务终止执行。
/// </summary>
/// <param name="type">业务类型</param>
/// <param name="typeIdentity">业务类型标识</param>
/// <param name="config">配置</param>
/// <param name="timestamp">更新前的时间戳</param>
/// <param name="newTimestamp">更新后的时间戳</param>
/// <returns></returns>
public static bool Update(string type, string typeIdentity, string config, string timestamp, string newTimestamp)
{

var flag = DB.Wdd.Database.ExecuteSqlCommand("update SmartConfigs set Config={0},Timestamp={1} where Type={2} and TypeIdentity={3} and Timestamp={4}"
, config, newTimestamp, type, typeIdentity, timestamp) == 1;
CacheMemory.Remove(string.Format(CacheKey.Domain_SmartConfig, type, typeIdentity));
return flag;

}
/// <summary>
/// 获取 SySmartConfig 如果数据库中没有,则创建并返回SySmartConfig
/// </summary>
/// <param name="type">业务类型</param>
/// <param name="typeIdentity">业务类型标识</param>
/// <param name="timestamp">时间戳</param>
/// <returns></returns>
public static SmartConfig Get(string type, string typeIdentity, string timestamp)
{
var cacheKey = string.Format(CacheKey.Domain_SmartConfig, type, typeIdentity);
return CacheMemory.Get<SmartConfig>(cacheKey, () =>
{
var config = DB.Wdd.SmartConfigs.FirstOrDefault(p => p.Type == type && p.TypeIdentity == typeIdentity);
if (config != null) return config;

config = new SmartConfig()
{
Config = string.Empty,
Timestamp = timestamp,
Type = type,
TypeIdentity = typeIdentity
};
DB.Wdd.AddEntity<SmartConfig>(config);
return config;
}, new TimeSpan(24, 0, 0));
}

/// <summary>
/// 保存 业务数据配置
/// 如果返回false 很可能是并发引起的,需要业务终止执行。
/// </summary>
/// <param name="smart">业务数据配置.</param>
public static bool Save<T>(Smart<T> smart)
{
if (smart == null) throw new ArgumentNullException("smart");
return Update(smart.Type, smart.TypeIdentify, Newtonsoft.Json.JsonConvert.SerializeObject(smart.Config), smart.Timestamp, Timestamp(DateTime.Now));
}

/// <summary>
/// 获取 业务数据配置
/// </summary>
/// <param name="typeIdentity">业务类型标识.</param>
public static Smart<T> Get<T>(string typeIdentity)
{
var type = typeof(T).Name.Replace("C_", "");
var smartConfig = Get(type, typeIdentity, Timestamp(DateTime.Now));
if (string.IsNullOrEmpty(smartConfig.Config)) smartConfig.Config = "{}";

//转换出错异常不处理
var config = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(smartConfig.Config);
return new Smart<T>(typeIdentity, smartConfig.Timestamp, config);
}

/// <summary>
/// 获取时间戳.
/// </summary>
/// <param name="dt">时间.</param>
/// <returns></returns>
private static string Timestamp(DateTime dt)
{
DateTime dt1 = new DateTime(1970, 1, 1);
TimeSpan ts = dt - dt1;
return ts.TotalMilliseconds.ToString();
}
}

这是接口层代码实现,开发人员只需要关心以下二个方法

public static bool Save<T>(Smart<T> smart)

public static Smart<T> Get<T>(string typeIdentity)

其它方法不需要关心,可改为private。

调用代码如下:

            var dish = SmartConfigService.Get<C_Dish>("1");
            dish.Config.NeedCooking = true;
            SmartConfigService.Save(dish);

保存的时候可以判断一下返回值如果为false,可能是因为并发,应结束业务处理

时间: 2024-10-11 10:31:15

复杂业务简单化的相关文章

复杂业务简单化的一个小技巧

在复杂系统中,当对业务数据进行“删除”时(一般不允许对业务数据进行删除,只是举例) ,需要根据其它业务数据进行判断如: 1.已生成出库单不允许删除, 2.付款单已确认不允许删除, 3.已经退换货则不允许删除. 实际业务中可能会更加复杂. 当出现这种情况时将导致“删除”业务判断会非常多,而且会经常修改,很有可能当其它业务发生变化时需要重新去调整“删除”业务. 解决方法:为业务数据增加一个中间件“是否可以删除的标识”其它业务发生变化时修改此标识为false  其它业务修改时不能将此标识改为true 

金诺物业收费管理系统软件V7.0官方最新破解版【无小区数限制】

软件使用的是SQL数据库,既支持单机使用也支持局域网或互联网多用户联机使用!需要的话请联系QQ:1811326220,可以淘宝交易! 金诺物业收费管理软件是针对物业管理公司的实际情况开发的.关于小区物业收费管理的软件.只要是物业收费,均可以在软件中实现,采用自定义.无限制的物业收费项目设置:采用打印模板,可以定制各种打印票据.俗话说,金钱无小事.收费管理是物业公司的核心业务,工作量大,容易出差错.我们专注于物业的收费管理,去掉人事.服务.安保.工程 .文件.保洁绿化管理等不太适合也没有必要进行计

系统架构师-基础到企业应用架构-业务逻辑层

一.上章回顾 上章我们主要讲述了系统设计规范与原则中的具体原则与规范及如何实现满足规范的设计,我们也讲述了通过分离功能点的方式来实现,而在软件开发过程中的具 体实现方式简单的分为面向过程与面向对象的开发方式,而目前更多的是面向对象的开发设计方式.并且我们也讲述了该如何通过设计手段去分析功能点及设计分离 点,应该如何在设计的过程中分析的角度及如何去满足设计规范与原则.首先我们通过下图来回顾下上章要点: 二.摘要 本文将已架构的方式去分析分层结构中的业务层的设计,如何写出来内聚度,高耦合的业务逻辑层

架构设计-业务逻辑层简述

如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 业务逻辑层是专门处理软件业务需求的一层,处于数据库之上,服务层之下,完成一些列对Domain Object的CRUD,作为一组微服务提供给服务层来组织在暴露给表现层,如库存检查,用法合法性检查,订单创建. 业务逻辑层包含领域对象模型,领域实体,业务规则,验证规则,业务流程.1:领域对象模型为系统结构描述,包含实体功能描述,实体之间的关系.领域模型处于天生的复杂性:2:领域实体:业务层是一些操

Http结合业务签名、请求JavaBean、List&lt;JavaBean&gt;等复杂对象

版权声明:转载必须注明本文转自严振杰的博客:http://blog.yanzhenjie.com 本文已授权 严振杰的公众首发,微信搜索严振杰即可关注. 本文篇幅较长,大概需要10分钟的时间才能阅读完,请做好心里准备. 今天群里小伙伴说我好久没更新文章了,赶紧翻了下自己的博客主页,发现真的成一个月一篇的更新了,加上群里小伙伴问Http怎么直接请求JavaBean.List<JavaBean>或者Map<>这种复杂对象,对于这个问题的解决方案,其实在2016年我就直播过了,并把视频和

【编程语言业务逻辑分类】

1. 面向过程 按照业务逻辑和实现过程步骤来逐步垒代码,代码编写的逻辑即对应于实际实现的步骤过程,核心是过程两个字,从代码执行顺序上体现出设计者的逻辑过程,整个程序就是把若干个过程串起来的效果.本质上像是构建了一条生成流水线,每一道工序都通过代码块严格定义. 优点: 复杂问题简单化,把大的任务逐步分解成一个一个小的任务分步实现,实现了每个小的步骤即可完成整体任务.逻辑思想符合日常生活中的常规过程化思维,因而代码可读性较高. 缺点: 由于实现逻辑是自上而下的分步过程,任何一个环节的变动,都可能涉及

爱上MVC~业务层刻意抛出异常,全局异常的捕获它并按格式返回

对于业务层的程序的致命错误,我们一直的做法就是直接抛出指定的异常,让程序去终断,这种做法是对的,因为如果一个业务出现了致命的阻塞的问题,就没有必要再向上一层一层的返回了,但这时有个问题,直接抛异常,意味着服务器直接500了,前端如何去显示,或者如果你是API的服务,如果为前端返回,如果是500,那直接就挂了,哈哈! 下面是在MVC环境下优化的全局异常捕获代码(非API) /// <summary> /// 全局异常捕获 /// </summary> public class Glo

架构师之路--视频业务介绍,离线服务架构和各种集群原理

先聊聊业务.我们媒资这边目前的核心数据是乐视视频的乐视meta和专门存储电视剧,综艺节目,体育赛事这种长视频的作品库.乐视视频的数据都是多方审核的,需要很多运营.但是作品库部分却是弱运营的,运营都不超过10个人.结果做了两个app,日活都有四五百万的样子.我们其实都有各样的技术储备,很容易可以抓取人家数据,自己套上一个壳子在线解码.但是我们逼格很高,都不这么做的.乐视是个非常注重版权的公司.我名下都有近百个专利了. 撇开这个项目,先看这边一般web项目的常用JVM配置. <jvm-arg>-X

合理的用户业务研发团队搭配

1.前言 用户业务指的就是面向用户的产品展示及用户操作入口,简单点说就是APP,微信,H5活动页等一系列前端展现入口的集合.用户是多变的,用户是神秘的,没有任何产品能从一开始就把握住用户的需求,任何好的产品和功能都是不断试错,不断调整出来的,所以我们需要一个能快速反应的用户业务开发团队,新需求快速上线,已有业务快速调整,响应越快才越有可能在竞争中走到别人前面,产品才有胜出的可能. 用户业务业务研发团队可以称为广义上的前端团队. 2.团队意义 用户业务研发团队(后文如无特殊说明,用前端团队简称),