zoukankan      html  css  js  c++  java
  • 【抽象那些事】不必要的抽象

    mark

    不必要的抽象

    在软件设计中引入实际上不需要的抽象时,将导致这种坏味。

    为什么不可以有不必要的抽象?

    抽象实体应该具有单一而重要的职责。如果创建的没必要或是只是为了方便,它们承担的职责微不足道,甚至没有承担任何职责,这违反了抽象原则。

    不必要的抽象的潜在原因

    使用的是面向对象语言,思维却是过程型编程思维

    过程型思维常常会创建执行功能而不是表示事物的类。这种类通常只有一两个方法,而这些方法操作的数据位于独立地“数据类”中。

    使用不合适的语言功能

    例如,使用"常量类"而不是枚举。这增加了不必要的类。

    过度设计

    例如,为了表示与Customer对象相关联的客户ID,创建一个名为CustomerID的类。更好的设计是:在Customer对象中使用一个字符串来存储客户ID。

    示例分析一

    public class FormattableFlags
    {
        /// <summary>
        /// 禁止显式实例化这个类
        /// </summary>
        private FormattableFlags()
        {
        }
        /// <summary>
        /// 将输出左对齐
        /// </summary>
        public  const int LEFT_JUSTIFY = 1;
        /// <summary>
        /// 将输出转换为大写
        /// </summary>
        public const int UPPERCASE = 2;
        /// <summary>
        /// 要求输出使用替换类型
        /// </summary>
        public const int ALTERNATE = 3;
    }
    

    我们上面分析过,使用"常量类"而不是枚举,增加了不必要的类。可以使用枚举替换掉"常量类",消灭掉不必要的类。

    public enum FormattableFlagsEnum
    {
        /// <summary>
        /// 将输出左对齐
        /// </summary>
        LEFT_JUSTIFY = 1,
        /// <summary>
        /// 将输出转换为大写
        /// </summary>
        UPPERCASE = 2,
        /// <summary>
        /// 要求输出使用替换类型
        /// </summary>
        ALTERNATE = 3
    }
    

    示例分析二

    一个电子商务应用程序,其中包含两个类:BestSellerBook和Book。每当客户程序要创建畅销书时,都创建一个BestSellerBook实例。在BestSellerBook内部只是将所有方法都委托给Book类,别的什么都不做。显然抽象BestSellerBook是多余的,因为其行为和抽象Book完全相同。

    /// <summary>
    /// 图书类
    /// </summary>
    public class Book
    {
        /// <summary>
        /// 价格
        /// </summary>
        public decimal Price { get; private set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="price"></param>
        public Book(decimal price)
        {
            this.Price = price;
        }
        /// <summary>
        /// 修改图书价格
        /// </summary>
        /// <param name="price">图书价格</param>
        public void ModifyPrice(decimal price)
        {
            this.Price = price;
        }
    }
    /// <summary>
    /// 畅销图书类
    /// </summary>
    public  class BestSellerBook
    {
        private Book book = null;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="price"></param>
        public BestSellerBook(decimal price)
        {
            book = new Book(price);
        }
        /// <summary>
        /// 修改图书价格
        /// </summary>
        /// <param name="price">图书价格</param>
        public void ModifyPrice(decimal price)
        {
            book.ModifyPrice(price);
        }
    }
    

    对于功能有限,不值得创建的类,应将其删除。

    我们可以将BestSellerBook类删除,并且在Book类中添加属性IsBestSeller。这样在客户程序创建Book实例时需要指出图书是否为畅销书,可设置属性IsBestSeller,而不用像以前那样创建BestSellerBook类的实例。

    /// <summary>
    /// 图书类
    /// </summary>
    public class Book
    {
        /// <summary>
        /// 价格
        /// </summary>
        public decimal Price { get; private set; }
        /// <summary>
        /// 是否畅销书
        /// </summary>
        public bool IsBestSeller { get; private set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="price">价格</param>
        /// <param name="isBestSeller">是否畅销书</param>
        public Book(decimal price, bool isBestSeller)
        {
            this.Price = price;
            this.IsBestSeller = isBestSeller;
        }
        /// <summary>
        /// 修改图书价格
        /// </summary>
        /// <param name="price">图书价格</param>
        public void ModifyPrice(decimal price)
        {
            this.Price = price;
        }
        /// <summary>
        ///  修改是否畅销书
        /// </summary>
        /// <param name="isBestSeller">是否畅销书</param>
        public void ModifyIsBestSeller(bool isBestSeller)
        {
            this.IsBestSeller = isBestSeller;
        }
    }
    

    现实考虑

    设计模式中的委托抽象

    有些设计模式(如代理模式、门面模式和适配器模式)使用了委托,其中包含了一个看似不必要的类。例如,在对象适配器模式中,Adapter类看似只是将客户端请求委托给Adaptee类的相应方法。但是,Adapter类承担了明确而具体的职责:调整Adaptee类的接口,以满足客户端的需求。所以,判断抽象是否多余,还要具体情况具体分析。

    mark

    总结:

    1. 包含多余的抽象会增加设计的复杂性,影响整个设计的可理解性。

    2. 职责独特而明确的抽象有可能得到重用,而当抽象不承担任何职责或承担的职责微不足道时,就不太可能在其它地方重用。

    参考:《软件设计重构》

    来源:http://songwenjie.cnblogs.com/
    声明:本文为博主学习感悟总结,水平有限,如果不当,欢迎指正。如果您认为还不错,不妨点击一下下方的推荐按钮,谢谢支持。转载与引用请注明出处。
    微信公众号:
  • 相关阅读:
    MVC模板页
    MVC Razor 语法(转)
    Code First 更新数据库结构
    mvc5 HTML Helper
    mvc5经典教程再补充。。
    mvc5入门,经典教程。。
    关于“以管理员身份运行”。。。
    windows8无脑式双系统安装教程(转)
    vs2010 无法连接到asp.net development server
    VMware虚拟机下安装RedHat Linux 9.0
  • 原文地址:https://www.cnblogs.com/songwenjie/p/8998471.html
Copyright © 2011-2022 走看看