如何使用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,接口类中定义了一些接口名(就是函数名)且并未实 ...
随机推荐
- 使用supervisor管理tomcat,nginx等进程详解
1,介绍 官网:http://supervisord.org Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时 ...
- 在 CentOS 8/RHEL 8 上安装和使用 Cockpit
Cockpit 是一个基于 Web 的服务器管理工具,可用于 CentOS 和 RHEL 系统.最近发布的 CentOS 8 和 RHEL 8,其中 cockpit 是默认的服务器管理工具.它的软件包 ...
- 改变一个数组内元素的位置,不通过splice方法。
这个数据 现在已经完成了,将本来在第一位的18代金券改到第31位,下面说一下怎么实现的. //currHotRightsTypeSorted这个是数据源头,legalRightsType这个是数据的分 ...
- .NET下数据库的负载均衡(有趣实验)
相关下载: 数据库的负载均衡-示例代码(dp1-DbBalance.rar) 数据库的负载均衡-示例代码(dp1-DbBalance.rar) 支持.Net/.Net Core/.Net Framew ...
- C++ 右值引用与 const 关键字
C++11 新增了另一种引用:右值引用(rvalue reference),这种引用可指向右值,是使用 && 声明的.使用右值引用可以减少复制操作,延长临时对象生命周期,提升程序性能. ...
- POJ1185 [NOI2001] 炮兵阵地 (状压DP)
又是一道有合法性检测的状压题. dp[i][j][k]表示第i行状态为j,i-1行状态为k时前i行放置的最大数量. 注意22行统计二进制数中1的个数时的巧妙方法. 1 #include<cstd ...
- JUI(6)线程池
文章目录 1.SynchronousQueue 2.线程池(重点) 2.1 使用单例 2.2.使用固定大小的线程 2.3.缓存线程池 2.4 七大参数 1.SynchronousQueue packa ...
- 齐博x1如何录制阿里等第三方直播流
暂时只支持windows录制,可以在你本地电脑进行录制体验.点击下面的网址,下载录制程序文件,直接解压到任何一个目录都可以.里边同时包含自建直播服务器的功能,不用自建直播流的话,就可以忽视相关配置即可 ...
- 折腾黑苹果-小新Pro13
最近在闲鱼上购入了一台2020版的联想小新 Pro13,i5 10200u 16g 512g配置,Ax201网卡.这台机子原生硬件就可以完美黑苹果了,不需要更换配件.只是Ax201网卡不能随航和隔空投 ...
- vue中push()和splice()的使用方法
vue中push()和splice()的使用方法 push()使用 push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度.注意:1. 新元素将添加在数组的末尾. 2.此方法改变数组的长度 ...