zoukankan      html  css  js  c++  java
  • 继承和复用

    目录

    背景设计的演化待重构的代码用继承消除重复用扩展类(Mixin)消除重复Ruby的鸭子类型 + Mixin的实现备注

    背景返回目录

    今天上午和以为朋友聊了一个设计问题:如何消除仓库相关的单据的Repository中的重复逻辑?如:入库单Repository和出库单Repository之间的重复。可以有很多方式消除重复,在不同级别消除重复,如:继承、组合、掺入、帮助类、帮助方法。本文只说出我的观点:不要为了复用而使用继承

    设计的演化返回目录

    下面我会演示:待重构的重复代码-》用继承消除重复-》用扩展类(Mixin)消除重复-》Ruby的鸭子类型 + Mixin的实现(元编程可以更牛叉,有机会再说)。

    待重构的代码返回目录

    注意:出库单仓储和入库单仓储的“根据编号获取单据”重复了。

    类图

    代码

    复制代码
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Linq.Expressions;
     7 
     8 namespace CSharpStudy.MixinStudy.V1
     9 {
    10     class Aggregate { }
    11 
    12     interface IRepository<T> where T : Aggregate
    13     {
    14         IEnumerable<T> Where(Expression<Func<T, bool>> condition);
    15     }
    16 
    17     class Repository<T> : IRepository<T>
    18         where T : Aggregate
    19     {
    20         public IEnumerable<T> Where(Expression<Func<T, bool>> condition)
    21         {
    22             throw new NotImplementedException();
    23         }
    24     }
    25 
    26     class 入库单 : Aggregate
    27     {
    28         public string 单据编号 { get; set; }
    29     }
    30 
    31     class 出库单 : Aggregate
    32     {
    复制代码

    用继承消除重复返回目录

    当我看到上面的重复代码的时候,第一印象是引入两个基类:仓库单据基类和仓库单据仓储基类。

    类图

    代码

    复制代码
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Linq.Expressions;
     7 
     8 namespace CSharpStudy.MixinStudy.V2
     9 {
    10     class Aggregate { }
    11 
    12     interface IRepository<T> where T : Aggregate
    13     {
    14         IEnumerable<T> Where(Expression<Func<T, bool>> condition);
    15     }
    16 
    17     class Repository<T> : IRepository<T>
    18         where T : Aggregate
    19     {
    20         public IEnumerable<T> Where(Expression<Func<T, bool>> condition)
    21         {
    22             throw new NotImplementedException();
    23         }
    24     }
    25 
    26     class 仓库单据基类 : Aggregate
    27     {
    28         public string 单据编号 { get; set; }
    29     }
    30 
    31     class 入库单 : 仓库单据基类 { }
    32 
    33     class 出库单 : 仓库单据基类 { }
    34 
    35     class 仓库单据仓储基类<T> : Repository<T>
    36         where T : 仓库单据基类
    37     {
    38         public IEnumerable<T> 根据编号获取单据(string 单据编号)
    39         {
    40             return this.Where(x => x.单据编号 == 单据编号);
    41         }
    42     }
    43 
    44     class 入库单仓储 : 仓库单据仓储基类<入库单> { }
    45 
    46     class 出库单仓储 : 仓库单据仓储基类<出库单> { }
    47 }
    复制代码

    用扩展类(Mixin)消除重复返回目录

    我对了吗?没有多态,只是为了复用就引入继承,是否合理呢?

    类图

    代码

    复制代码
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Linq.Expressions;
     7 
     8 namespace CSharpStudy.MixinStudy.V3
     9 {
    10     class Aggregate { }
    11 
    12     interface IRepository<T> where T : Aggregate
    13     {
    14         IEnumerable<T> Where(Expression<Func<T, bool>> condition);
    15     }
    16 
    17     class Repository<T> : IRepository<T>
    18         where T : Aggregate
    19     {
    20         public IEnumerable<T> Where(Expression<Func<T, bool>> condition)
    21         {
    22             throw new NotImplementedException();
    23         }
    24     }
    25 
    26     class 仓库单据基类 : Aggregate
    27     {
    28         public string 单据编号 { get; set; }
    29     }
    30 
    31     class 入库单 : 仓库单据基类 { }
    32 
    33     class 出库单 : 仓库单据基类 { }
    34 
    35     static class 仓库单据基类仓储扩展
    36     {
    37         public static IEnumerable<T> 根据编号获取单据<T>(this IRepository<T> that, string 单据编号)
    38             where T : 仓库单据基类
    39         {
    40             return that.Where(x => x.单据编号 == 单据编号);
    41         }
    42     }
    43 }
    复制代码

    Ruby的鸭子类型 + Mixin的实现返回目录

    代码

    复制代码
     1 # coding: utf-8
     2 
     3 class Aggregate
     4 end
     5 
     6 class Repository
     7     def Where(condition)
     8     end
     9 end
    10 
    11 class C仓库单据基类 < Repository
    12     attr_accessor :单据编号
    13 end
    14 
    15 class C入库单 < C仓库单据基类
    16 end
    17 
    18 class C出库单 < C仓库单据基类
    19 end
    20 
    21 module C仓库单据基类仓储扩展
    22     def 根据编号获取单据(单据编号)
    23         return self.Where({:单据编号 => 单据编号})
    24     end
    25 end
    26 
    27 class C入库单仓储 < Repository
    28     include C仓库单据基类仓储扩展
    29 end
    30 
    31 class C出库单仓储 < Repository
    32     include C仓库单据基类仓储扩展
    33 end
    复制代码

    Ruby正统的支持了Mixin,鸭子类型天生具备泛型的特点,比泛型强大,元编程更是牛叉(本文没有体现)。

    备注返回目录

     做一件事如果只有一个选择,就说明 有问题了,多思考几个方案,折中后考虑一个方案。

  • 相关阅读:
    How to alter department in PMS system
    Can't create new folder in windows7
    calculate fraction by oracle
    Long Wei information technology development Limited by Share Ltd interview summary.
    ORACLE BACKUP AND RECOVERY
    DESCRIBE:When you mouse click right-side is open an application and click left-side is attribution.
    ORACLE_TO_CHAR Function
    电脑BOIS设置
    JSP点击表头排序
    jsp+js实现可排序表格
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3277783.html
Copyright © 2011-2022 走看看