如何使用Abstract类?抽象类的威力
简介:
今天我想谈谈如何使用抽象类,以及抽象类真正的威力。本文将结合具体业务来说明如何使用抽象类。
业务简述:
本人目前只接触过PMS(物业管理系统),公司主要业务的是美国的租房业务。由于美国租房和中国租房在后台可能有点差别,本文不做叙述。下面我们直入主题。
当用户点击租房之后,我们是要创建一个订单,而在创建订单的时候,需要做很多事,本文只做一个简化版的,避免偏离主题。当创建订单时,需要做以下几件事:
1.Available 检查是否可用
2.MinDay 检查 最小入住天数是否匹配
3.Check in/Check out 检查入住时间和离开时间是否匹配
4.quote 计算价格。
而针对前三中,只是判断该房可不可以租。而且有可能以后还会加入其它规则,如果把它们写在一起也是可以的,但不利于扩展。下面看下我如何使用abstract类来实现他的扩展性:
1.第一步,创建以下类
1.1 创建类 OrderAddDTO.cs
public class OrderAddDTO
{
/// <summary>
/// 物业Id
/// </summary>
public Guid PropertyId { get; set; }
/// <summary>
/// 入住时间
/// </summary>
public DateTime CheckInDate { get; set; }
/// <summary>
/// 离开时间
/// </summary>
public DateTime CheckOutDate { get; set; } //TODO:其它信息
}
1.2 创建抽象类 PropertyValidAbstract.cs
public abstract class PropertyValidAbstract
{
protected PropertyValidAbstract _baseValid;
public void SetNext(PropertyValidAbstract BaseValid)
{
this._baseValid = BaseValid;
}
public static string ErrorMsg { get; set; }
public abstract bool IsValid(OrderAddDTO dto);
}
1.3 创建Available 验证类:AvailableValid,并继承自PropertyValidAbstract
public class AvailableValid : PropertyValidAbstract
{
public override bool IsValid(OrderAddDTO dto)
{
//TODO:取出该property(物业)的 Available //if (计算该物业在dto.CheckInDate-dto.CheckOutDate时间内是否可用)
//{
//不可用,则对ErrorMsg赋值,并返回false;
//TODO:具体实现
//} //如果没有下一步验证了,则返回true
if (this._baseValid == null)
{
return true;
} //如果可用,则进入下一个验证
return this._baseValid.IsValid(dto); }
}
1.4 创建MinDay 验证类MinDayValid.cs,并继承自PropertyValidAbstract
public class MinDayValid : PropertyValidAbstract
{
public override bool IsValid(OrderAddDTO dto)
{
//TODO:取出该property(物业)的 MinDay规则 //模拟minday规则,具体的minday比这个复杂多了
var checkDays = (dto.CheckOutDate - dto.CheckInDate).Days + 1;
if (checkDays<3)
{
ErrorMsg = "stay at least 3 days";
return false;
} //如果没有下一步验证了,则返回true
if (this._baseValid == null)
{
return true;
} //如果满足,则进入下一个验证
return this._baseValid.IsValid(dto);
}
}
1.5 创建CheckIn/Out验证类:CheckInOutDateValid.cs,并继承自PropertyValidAbstract
public class CheckInOutDateValid : PropertyValidAbstract
{
public override bool IsValid(OrderAddDTO dto)
{ //模拟checkin/checkout规则判断
DayOfWeek checkInWeek = dto.CheckInDate.DayOfWeek;
DayOfWeek checkOutWeek = dto.CheckOutDate.DayOfWeek;
if (checkOutWeek!= DayOfWeek.Saturday||checkInWeek!= DayOfWeek.Tuesday)
{
ErrorMsg = "checkin/out Does not meet the";
return false;
}
//如果没有下一步验证了,则返回true
if (this._baseValid==null)
{
return true;
}
return this._baseValid.IsValid(dto);
}
}
1.6 最后在创建一个验证配置类:ValidSettings.cs,并继承自PropertyValidAbstract
public class ValidSettings: PropertyValidAbstract
{public override bool IsValid(OrderAddDTO dto)
{
//先进行AvailableValid
PropertyValidAbstract BaseValid = new AvailableValid();
//在验证MinDayValid
var mindayvalid = new MinDayValid();
BaseValid.SetNext(mindayvalid);
//最后是CheckInOutDateValid
var checkinOutvalid = new CheckInOutDateValid();
mindayvalid.SetNext(checkinOutvalid); return BaseValid.IsValid(dto);
}
}
2.在控制台模拟:
static void Main(string[] args)
{
///这个dto,是从客户端传过来的,在这模拟下
OrderAddDTO dto = new OrderAddDTO();
dto.CheckInDate = DateTime.Now;
dto.CheckOutDate = DateTime.Now.AddDays(1); PropertyValidAbstract baseValid = new ValidSettings(); if (baseValid.IsValid(dto)==false)
{
Console.WriteLine(PropertyValidAbstract.ErrorMsg);
}
else
{
//TODO:计算价格
Console.WriteLine("计算价格");
} Console.ReadKey();
}
3.运行结果:
3.1 测试不满足minday规则

3.2 测试都满足

运行结果都没问题,这时候可能客户来需求,你再给我加个maxday(最大入住天数规则)。这时候我们可以这么做:
1. 新建一个maxday验证类:MaxDayValid.cs,并继承自PropertyValidAbstract
public class MaxDayValid : PropertyValidAbstract
{
public override bool IsValid(OrderAddDTO dto)
{
//TODO:取出该property(物业)的 MaxDay规则 //模拟maxday规则,具体的maxday比这个复杂多了
var checkDays = (dto.CheckOutDate - dto.CheckInDate).Days + 1;
if (checkDays >300)
{
ErrorMsg = "stay up to 300 days";
return false;
} //如果没有下一步验证了,则返回true
if (this._baseValid == null)
{
return true;
}
return this._baseValid.IsValid(dto);
}
}
2.修改ValidSettings.cs类
public class ValidSettings: PropertyValidAbstract
{ public override bool IsValid(OrderAddDTO dto)
{
//先进行AvailableValid
PropertyValidAbstract BaseValid = new AvailableValid();
//在验证MinDayValid
var mindayvalid = new MinDayValid();
BaseValid.SetNext(mindayvalid); //新增一个maxday
var maxdayvalid = new MaxDayValid();
mindayvalid.SetNext(maxdayvalid); //最后是CheckInOutDateValid
var checkinOutvalid = new CheckInOutDateValid();
maxdayvalid.SetNext(checkinOutvalid); return BaseValid.IsValid(dto);
}
}
3. 我们来看下运行结果:

结束语:
希望我的文章能对你有所帮助,其实以上使用抽象类的例子也是一个设计模式的例子,责任链模式。。关于设计模式不能死记住,得做到“得其意,忘其形”。谢谢观看。
如何使用Abstract类?抽象类的威力的更多相关文章
- 事实证明,abstract类除了不能用new实例化和类没什么区别
abstract类是抽象类,不能够实例化,大家都知道,abstract类往往和接口interface一块儿使用,针对接口中一些公共的方法进行实现,然后实体类去继承抽象类和接口.虽然abstract类不 ...
- final方法,abstract方法和abstract类,native方法
final方法 1.为了确保某个函数的行为在继承过程中保持不变,并且不能被覆盖(override),可以使用final方法. 2.为了效率上的考虑,将方法声明为final,让编译器对此方法的调用进行优 ...
- c# 事实证明,abstract类除了不能用new实例化和类没什么区别
abstract类是抽象类,不能够实例化,大家都知道,abstract类往往和接口interface一块儿使用,针对接口中一些公共的方法进行实现,然后实体类去继承抽象类和接口.虽然abstract类不 ...
- Interface与abstract类的区别
含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象.含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必 ...
- Java abstract关键字 抽象类 抽象方法
用 abstract 修饰的类是抽象类,它不能生成对象 含有抽象方法的类称为抽象类 抽象方法使用 abstract 修饰 抽象类不能直接实例化,只能由子类实例化 举例 abstract class T ...
- Java abstract类的基本使用 和 [abstract类实现]打印1000以内的所有素数并输出时间
笔记: /** 关键字abstract ,实现抽象类,相当于给出类的大纲,子类只管继承,但抽象类不可被实例化! * 1.抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写所有的抽 ...
- [转]C#中的abstract 类和方法
转:https://www.cnblogs.com/zzy2740/archive/2005/09/20/240808.html C#中的abstract类不能被实例化,他只提供其他类的继承的接口 u ...
- java中abstract关键字(抽象类)
需求 当父类某个方法,需要声明,但是又不确定如何实现时,可以用抽象方法,那么这个类就是抽象类 例如:父类是一个动物类,父类里面有很多方法,其中有一个方法是吃食物,但是不知道吃什么,需要子类继承的时候重 ...
- day27 多态 多继承 接口类 抽象类
简单来说:多态就是指一个相同的方法名在不同的对象调用的时候实现一样或者不一样的方法实例1: 动物类有个方法 "嚎叫" 狗类也有个方法 "嚎叫" 猫类继承了动物类 ...
- python开发面向对象基础:接口类&抽象类&多态&钻石继承
一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实 ...
随机推荐
- 存储卷PersistentVolume
概述 与管理计算资源相比,管理存储资源是一个完全不同的问题.为了更好的管理存储,Kubernetes 引入了 PersistentVolume 和 PersistentVolumeClaim 两个概念 ...
- vue-router query和params 传参和接收参数
1.params 方式传递和接收参数 //传参 this.$router.push({ name: 'checkDetailInfo', params:{ fkdNum:fkdNum, jyayStr ...
- 关于HM NISEDIT在新版系统下编译并运行提示权限不足问题的解决方案
如果你使用过NSIS为你的项目制作过安装包,那HM nisedit一定是你绕不过去的槛,作为NSIS号称的最佳免费IDE/编辑器,功能齐全,与NSIS配合性能强悍,实至名归.只是开发作者最后版本更新在 ...
- Java程序设计(五)作业
题目1:Lisa正在编写一个能够计算三科--数学.英语.程序设计基础--平均成绩(平均成绩=三科总成绩/3)和智育成绩(智育成绩=三科总成绩*0.7)的程序.由于两个成绩的获得都要先计算总成绩,因此她 ...
- 华为网关交换机开启DHCP server服务
华为网关交换机可以配置基于全局地址池的DHCP服务器,也可以配置基于接口地址池的DHCP服务器,本人比较倾向于配置基于接口地址池的DHCP服务器,因此在这里只介绍后者. 第一步:开启DHCP功能 [S ...
- 如何去了解Spring
对于你想了解的技术 官方总是一个合适的选择 首先,我们所指的Spring 一般指的是Spring Framework,伴随着的时代的进步,Spring全家桶也逐渐完善起来 Spring 1.Why S ...
- Hbase之shell基本操作
一.系统命令 启动hbase Shell ./bin/hbase shell 获取帮助 help 查询服务器状态 status 查询hbase版本 version 查询表 list 获取表描述 des ...
- LOJ2325「清华集训 2017」小Y和恐怖的奴隶主
题目链接 首先dp很显然,\(f(i,s)\)表示到了第i轮,各种血量人数的情况为s今后的期望攻击boss次数.那么有\(f(i,s)=\frac{1}{num+1}*\sum_{s->s'}( ...
- surging 将推出社区版微服务平台
前言 对于.NET大家并不陌生,有大批的企业选择.NET作为公司构建多种应用的开发平台,但是近几年随着微服务,大数据,移动端,物联网兴起,而后.NET社区生态没有跟上时代的步伐,已开始趋于没落,而其中 ...
- commons-fileupload组件和commons-io组件的详细下载
commons-fileupload组件和commons-io组件的详细下载 1. commons-fileupload组件的下载 下载地址:http://commons.apache.org/fil ...