如何使用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. 我们来看下运行结果:

  

结束语:

  希望我的文章能对你有所帮助,其实以上使用抽象类的例子也是一个设计模式的例子,好像是叫啥责任链吧。记得不太清楚。关于设计模式不能死记住,得做到“得其意,忘其形”。谢谢观看。

原文地址:https://www.cnblogs.com/norain/p/11441869.html

时间: 2024-10-13 18:52:49

如何使用Abstract类?抽象类的威力的相关文章

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

abstract类是抽象类,不能够实例化,大家都知道,abstract类往往和接口interface一块儿使用,针对接口中一些公共的方法进行实现,然后实体类去继承抽象类和接口.虽然abstract类不能实例化,但是abstract类可以有构造函数,其构造函数和实体类的构造函数没什么区别.如下: abstract class A { public A() { Console.Write("A "); } public virtual void Method() { Console.Wri

java中的abstract类

Abstract是Java中的一个重要关键字,可以用来修饰一个类或者一个方法.修饰一个方法时,表示该方法只有特征签名(signature),没有具体实现,而是把具体实现留给继承该类的子类.一个类中只要有一个abstract方法,那么这个类就要被声明为abstract,但是其中可以有非abstract方法.abstract类可以使得类的设计者能够创建方法的原型,而真正的实现留给使用这个类的人.继承一个abstract类的子类,要么实现父类的所有abstract方法,要么也声明为abstract类,

Interface与abstract类的区别

含有abstract修饰符的class即为抽象类,abstract 类不能创建的实例对象.含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的.abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法.如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型. 接口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须

python开发面向对象基础:接口类&amp;抽象类&amp;多态&amp;多继承

一,接口类 继承有两种用途: 一:继承基类的方法,并且做出自己的改变或者扩展(代码重用) 二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能 开发中容易出现的问题 1 class Alipay: 2 ''' 3 支付宝支付 4 ''' 5 def pay(self,money): 6 print('支付宝支付了%s元'%money) 7 8 class Applepay: 9 ''' 1

java 容器深入研究之使用Abstract类定制

package org.rui.collection3.map; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Linke

普通类 抽象类 接口

首先得搞懂什么是抽象类:一.概念:    在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样.并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类.    比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆.三角形这样一些具体概念.它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念.正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的

Java集合(3):使用Abstract类

每个java.util容器都有其自己的Abstract类,它们提供了该容器接口的部分实现.下面是一个定制自己的Map的例子(List set就省略了): 定制自己的Map实现AbstractMap-->Map,需要实现[Set<Map.Entry<K,V>> entrySet()]方法 实现[Set<Map.Entry<K,V>> entrySet()]方法分两步: (1) 实现Set<E>接口 (2) 实现Map.Entry<K,V

python 2018.7.25 接口类,抽象类

python 没有接口这个概念 接口类,抽象类: 制定一个规范. from abc import ABCMeta,abstractmethodclass Payment(metaclass=ABCMeta): # 抽象类(接口类): @abstractmethod def pay(self): pass # 制定了一个规范 class Alipay(Payment): def __init__(self,money): self.money = money def pay(self): prin

java中请给一个Abstract类实现接口的实例!

2.Abstract类实现接口 (视频下载) (全部书籍) 马克-to-win:如果实现某接口的类是abstract类,则它可以不实现该接口所有的方法.但其非abstract的子类中必须拥有所有抽象方法的实在的方法体:(当然它abstract爹的也算作是它的) If a class implements an interface, it must implement all of its methods in the interface, otherwise, this class must b