简介:

  今天我想谈谈如何使用抽象类,以及抽象类真正的威力。本文将结合具体业务来说明如何使用抽象类。

业务简述:

  本人目前只接触过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类?抽象类的威力的更多相关文章

  1. 事实证明,abstract类除了不能用new实例化和类没什么区别

    abstract类是抽象类,不能够实例化,大家都知道,abstract类往往和接口interface一块儿使用,针对接口中一些公共的方法进行实现,然后实体类去继承抽象类和接口.虽然abstract类不 ...

  2. final方法,abstract方法和abstract类,native方法

    final方法 1.为了确保某个函数的行为在继承过程中保持不变,并且不能被覆盖(override),可以使用final方法. 2.为了效率上的考虑,将方法声明为final,让编译器对此方法的调用进行优 ...

  3. c# 事实证明,abstract类除了不能用new实例化和类没什么区别

    abstract类是抽象类,不能够实例化,大家都知道,abstract类往往和接口interface一块儿使用,针对接口中一些公共的方法进行实现,然后实体类去继承抽象类和接口.虽然abstract类不 ...

  4. Interface与abstract类的区别

    含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象.含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必 ...

  5. Java abstract关键字 抽象类 抽象方法

    用 abstract 修饰的类是抽象类,它不能生成对象 含有抽象方法的类称为抽象类 抽象方法使用 abstract 修饰 抽象类不能直接实例化,只能由子类实例化 举例 abstract class T ...

  6. Java abstract类的基本使用 和 [abstract类实现]打印1000以内的所有素数并输出时间

    笔记: /** 关键字abstract ,实现抽象类,相当于给出类的大纲,子类只管继承,但抽象类不可被实例化! * 1.抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写所有的抽 ...

  7. [转]C#中的abstract 类和方法

    转:https://www.cnblogs.com/zzy2740/archive/2005/09/20/240808.html C#中的abstract类不能被实例化,他只提供其他类的继承的接口 u ...

  8. java中abstract关键字(抽象类)

    需求 当父类某个方法,需要声明,但是又不确定如何实现时,可以用抽象方法,那么这个类就是抽象类 例如:父类是一个动物类,父类里面有很多方法,其中有一个方法是吃食物,但是不知道吃什么,需要子类继承的时候重 ...

  9. day27 多态 多继承 接口类 抽象类

    简单来说:多态就是指一个相同的方法名在不同的对象调用的时候实现一样或者不一样的方法实例1: 动物类有个方法 "嚎叫" 狗类也有个方法 "嚎叫" 猫类继承了动物类 ...

  10. python开发面向对象基础:接口类&抽象类&多态&钻石继承

    一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实 ...

随机推荐

  1. 8.maven上传jar包以及SNAPSHOT的一个坑

    1,手动上传包 如何将一些新的外部包上传到私服当中呢? 首先是要登录上去,然后点击 Upload,找到 maven-local将jar包找到选中,然后填写对应的三个定位信息即可上传. 在引用的时候,道 ...

  2. 通过Thread Pool Executor类解析线程池执行任务的核心流程

    摘要:ThreadPoolExecutor是Java线程池中最核心的类之一,它能够保证线程池按照正常的业务逻辑执行任务,并通过原子方式更新线程池每个阶段的状态. 本文分享自华为云社区<[高并发] ...

  3. localStorage概要

    在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localSt ...

  4. 使用 Spring Security 手动验证用户

    1.概述 在这篇快速文章中,我们将重点介绍如何在 Spring Security 和 Spring MVC 中手动验证用户的身份. 2.Spring Security 简单地说,Spring Secu ...

  5. cudaMemcpy cudaMalloc

    cudaMemcpy有四种类型:HostToHost, DeviceToHost, HostToDevice, DeviceToDevices 现在我有两个指针:h_ptr, d_ptr,分别指向ho ...

  6. hyperf-搭建初始化

    官方文档* https://hyperf.wiki/2.0/#/README 初步搭建1. 安装项目 composer create-project hyperf/hyperf-skeleton 2. ...

  7. go-zero docker-compose 搭建课件服务(六):完善jwt鉴权和返回结构

    0.转载 go-zero docker-compose 搭建课件服务(六):完善jwt鉴权和返回结构 0.1源码地址 https://github.com/liuyuede123/go-zero-co ...

  8. python批量加密文件

    1.文件名的加密与解密 #coding:utf-8 from docx import Document import os,sys from docx.oxml.ns import qn def fi ...

  9. C#中的装箱和拆箱

    什么是装箱和拆箱 装箱(boxing)和拆箱(unboxing)是C#类型系统的核心概念.是不同于C与C++的新概念!,通过装箱和拆箱操作,能够在值类型和引用类型中架起一做桥梁. 换言之,可以轻松的实 ...

  10. 在FreeSQL中实现「触发器」和软删除功能

    前言 最近做新项目,技术栈 AspNetCore + FreeSQL 这个ORM真的好用,文档也很完善,这里记录一下两个有关「触发器」的功能实现 修改实体时记录更新时间 模型代码 我的模型都是基于这个 ...