【愚公系列】2021年12月 面向对象设计原则(六)-合成复用原则(Composite Reuse Principle or CRP)

简介: 【愚公系列】2021年12月 面向对象设计原则(六)-合成复用原则(Composite Reuse Principle or CRP)

文章目录

前言

一、合成复用原则(Composite Reuse Principle or CRP)

二、使用步骤

示例

总结

前言

常用的面向对象设计原则有七个,这七大设计原则都是以可维护性和可复用性为基础的,这些原则并不是孤立存在的,它们相互依赖相互补充,遵循这些设计原则可以有效地提高系统的复用性,同时提高系统的可维护性。


提示:以下是本篇文章正文内容,下面案例可供参考


一、合成复用原则(Composite Reuse Principle or CRP)

尽量使用对象组合,而不是继承来达到复用的目的。

合成复用原则是鼓励优先使用对象的组合,而不是使用继承。


二、使用步骤

示例

public abstract class BankCard {
    public string UserName { get; set; }//用户名
    public string Balance { get; set; }//余额
    public abstract void Transfer(BankCard card, double amount);//转账
    public abstract void Withdraw(double amount);//取款
    public abstract void Deposit(double amount);//存款
    public abstract void Overdraft(double amount);//透支
    public virtual void ShowMessage() {
        Console.WriteLine($"THis is {this.ToString()}!"); 
    }
}
//建设银行普通银行卡
public class CCBCard : BankCard {
    public override void Deposit(double amount) {
        Console.WriteLine("Deposit");
    }
    public override void Overdraft(double amount) {
        throw new NotImplementedException();
    }
    public override void Transfer(BankCard card, double amount) {
        Console.WriteLine("Transfer");
    }
    public override void Withdraw(double amount) {
        Console.WriteLine("Withdraw");
    }
}

以上这种设计将银行卡的大部分功能封装在抽象基类BankCard中,建设银行普通银行卡类CCBCard类继承这个基类,但是建行的普通银行卡显然没有透支功能,导致导致不得不为这个没有透支功能的银行卡添加一个默认的透支实现,这显然是不合理的。另外如果修改基类中任何一个功能,所有继承自BankCard的类可能都要重写,这显然也不符合开闭原则。转账方法使用BankCard类型的参数,显然不符合里氏替换原则。以下给出一个解决方案以供参考:

public abstract class BankCardBase {
    public string UserName { get; set; }//用户名
    public string Balance { get; set; }//余额
    public virtual void ShowMessage() {
        Console.WriteLine($"THis is {this.ToString()}!");     
    }
}

独立一个抽象基类BankCardBase,提供用户名、余额等基本功能。

public interface ICard {
    void Transfer(BankCardBase card, double amount);//转账
    void Withdraw(double amount);//取款
    void Deposit(double amount);//存款
}
public interface ICreditCard : ICard {
    void Overdraft(double amount);//透支
}

抽象出ICard银行卡基本操作接口,包含转账、取款和存款。ICreditCard信用卡接口,考虑到信用卡一定包含普通银行卡功能,所以继承ICard接口。

//建设银行普通银行卡
public class CCBCard : BankCardBase, ICard {
    public void Deposit(double amount) {
        Console.WriteLine("Deposit");
    }
    public void Transfer(BankCardBase card, double amount) {
        Console.WriteLine("Transfer");
    }
    public void Withdraw(double amount) {
        Console.WriteLine("Withdraw");
    }
}

建设银行普通银行卡实体类,继承自银行卡抽象基类并实现ICard银行卡接口。

//建设银行龙卡信用卡
public class CCBDragonCard : BankCardBase, ICreditCard {
    public void Deposit(double amount) {
        Console.WriteLine("Deposit");
    }
    public void Overdraft(double amount) {
        Console.WriteLine("Overdraft");
    }
    public void Transfer(BankCardBase card, double amount) {
        Console.WriteLine("Transfer");
    }
    public void Withdraw(double amount) {
        Console.WriteLine("Withdraw");
    }
}

建设银行龙卡信用卡实体类,继承自银行卡抽象基类并实现ICreditCard信用卡接口。


总结

经过以上的代码改造之后,银行卡基类BankCardBase只包含银行卡的基本功能,银行卡接口ICard只包含银行卡相关的业务操作,而信用卡接口ICreditCard则只包含与信用卡相关的业务操作,相互之间没有影响,修改普通银行卡或信用卡的功能,不会影响到其它类型的银行卡的业务逻辑,符合开闭原则。


转账方法使用基类参数BankCardBase,运用在“运行时子类对象替代父类对象”的特点,使得代码的可扩展性极高,符合里氏替换原则。在这个示例中,我们优先使用各种类和接口的组合来代替之前的单一基类的继承关系来打造普通银行卡和信用卡的功能,使得整个设计更干净利落,可维护性高,并且这些类和接口还可以被无限合理的复用,这就是合成复用原则。


相关文章
|
Java
六大设计原则-里式替换原则【Liskov Substitution Principle】
六大设计原则-里式替换原则【Liskov Substitution Principle】
34 0
|
设计模式 Oracle 关系型数据库
软件架构设计原则之合成复用原则
合成复用原则(Composite/Aggregate Reuse Principle,CARP)是指尽量使用对象组合(has-a)/聚合(contanis-a)而不是继承关系达到软件复用的目的。可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少。
111 0
|
设计模式 Oracle 关系型数据库
深入理解合成复用原则(Composition /Aggregate Reuse Principle)
深入理解合成复用原则(Composition /Aggregate Reuse Principle)
387 0
|
设计模式 XML JSON
【Java设计模式 经典设计原则】七 LOD迪米特法则
【Java设计模式 经典设计原则】七 LOD迪米特法则
112 0
|
设计模式 搜索推荐 安全
【Java设计模式 经典设计原则】三 SOLID-LSP里式替换原则
【Java设计模式 经典设计原则】三 SOLID-LSP里式替换原则
137 0
|
设计模式
设计模式 - 六大设计原则之LoD(迪米特法则原则)
迪米特法(Law Of Demeter , LoD)则又叫最少知道原则(Least Knowledge Principle),最早是在1987年由美国Northeastern University的Ian Holland提出。 通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。
193 0
设计模式 - 六大设计原则之LoD(迪米特法则原则)
|
设计模式
设计模式(7) -- 合成复用原则和七大原则总结
设计模式(7) -- 合成复用原则和七大原则总结
135 0
设计模式(7) -- 合成复用原则和七大原则总结
|
设计模式 uml
设计模式七大原则——合成复用原则
设计模式七大原则——合成复用原则
设计模式七大原则——合成复用原则
|
设计模式 Oracle 关系型数据库
软件架构设计原则--合成复用原则
本专栏内容参考自:咕泡学院Tom老师的《Spring5核心原理与30个类手写实战》,仅作个人学习记录使用,如有侵权,联系速删
设计原则与思想 --- 单一职责原则(SRP)
设计原则与思想 --- 单一职责原则(SRP)
设计原则与思想 --- 单一职责原则(SRP)