设计模式概述(7大设计原则细讲)

什么是设计模式?

软件设计模式,又称为设计模式,是一套被反复使用、多数人知晓的,经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案,也就是说,它是解决特定问题的一系列逃离,是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。

设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。

有什么好处?

正确使用设计模式具有以下优点:

1.可以提高程序员的思维能力,编程能力和设计能力;

2.使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期;

3.使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强;

设计模式的分类

创建型模式

用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”,有单例、原型、工厂方法、抽象工厂、建造者等五种创建型模式

结构型模式

用于描述如何将类或对象按某种布局组成更大的结构,有代理、适配器、桥接、装饰、外观、亨元、组合等7种结构型模式

行为型模式

用于描述类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务、以及怎样分配职责,有模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器等11种行为型模式;

设计原则

在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据下面7条原则来开发程序,从而提高软件开发效率、节约软件开发成本和维护成本

单一原则

一个对象应该只包含单一的职责,并且该职责被完整的封装在一个类里面;

一个类承担的职责越多,那么它被复用的概率也就越小,而且如果一个类承担的职责过多,相当于这些职责耦合在一起,当其中一个职责变化的时候,可能会影响其他职责的运作

类的职责主要包括两个方面:数据职责和行为职责,数据职责通过其属性来体现,而行为职责通过其方法来体现;

如果职责太多将导致系统非常脆弱,一个职责可能会影响其他职责,因此要将这些职责进行分离,将不同的职责根据类型封装在不同的类中,如果多个职责总是同时发生改变,则可将它们封装在同一类中;

例如经纪人、明星两个类中,经济人负责业务洽谈,接待广告,明星负责出席活动,演戏,拍摄广告,这两个类的职责就很分明,因此肯定是不能耦合在一起的;

单一职责是实现高内聚低耦合的指导方针;在很多代码的重构手法中都能找到它的存在,它是最简单但又是最难运用的原则,需要设计人员发现类的不同职责并将其分离;

开闭原则

对扩展开放,对修改关闭,在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果,简而言之就是为了使程序的扩展性好,易于维护和升级;

想要达到这样的效果,我们需要使用接口和抽象类

因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定,而软件中易变的细节可以从抽象派生成来的实现类来进行扩展,当软件需要发生变化的时候,只需要根据需求重新派生一个实现类来扩展就可以了;

里氏代换原则

任何基类可以出现的地方,子类一定可以出现;

子类可以扩展父类的功能,但是不能改变父类原有的功能!

也就是说子类继承父类的时候,除添加新的方法或者参数完成新增功能外,尽量不要重写父类的方法

如果通过重写父类的方法来完成新的功能,这样虽然方便,但是整个继承体系都会发生改变,这样的话整个体系的可复用性就会变得比较差,尤其是多态运用频繁的情况下,程序出错的概率大大增加;

依赖倒转原则

1.高层模块不应该依赖低层模块,两者都应该依赖其抽象;

2.抽象不应该依赖细节(具体的实现类或者子类),细节应该依赖抽象;

简单的来说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块之间的耦合

可以理解为,该原则是开闭原则的具体实现

例如,我们如果定义了一个教室类,我们在创建对象的时候想要去获取该教室类里面的学生:

按照最开始的做法我们就需要在该类里面去定义一个学生类的变量;

public class ClassRoom{
    private Student student;
}
public class Student(){
    private int count;
}

但是这个时候我如果想要获取该教室类里面的老师,那么我们就需要修改教室类里面的成员变量;

这并不满足依赖倒转原则,如果想要满足依赖倒转原则,那么我们就需要去对老师和学生进行抽象:

public interface Person{
    
}
public class Student implements Person{
    
}
public class Tearcher implements Person{
    
}

然后让学生和老师实现该接口进行扩展,然后在教室类中的成员变量就只需要定义该接口就行了,那么我们在使用的时候就可以更加的灵活,不用再去修改教室类里面的代码了;

public class ClassRoom{
    private Person perosn;
}
public static void main(String[] args){
    Person person = new Student;
    Person person = new Teacher;
}

接口隔离原则

客户端不应该被迫依赖与它不使用的方法;一个类对另一个类的依赖应该建立在最小的接口上

例如我们现在有一个立白洗衣液,该洗衣液具有杀菌、除螨、漂白、去黄、增香的功能,那么我们就将其功能提取成一个洗衣液功能通用接口,让立白品牌去实现它即可;

但是这个时候我们还需要创建一个strine品牌的洗衣液,让它也去实现了上面这个洗衣液接口,但是该品牌并没有去黄和增香的功能,也就是说这个新的strine品牌类被迫依赖于洗衣液接口中两个它不使用的方法,那么这就违背了接口隔离原则!

迪米特法则

又叫最少知识原则:只和你的直接朋友交谈,不跟陌生人说话;

也就是说,如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用,其目的是降低类之间的耦合,提高模块的相对独立性

朋友是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象同当前对象存在关联、聚合或者组合关系,可以直接访问这些对象的方法;

例如:房东、房产中介、租客三者的关系,房产中介与房东是朋友,负责发布租房信息,而租客看上房之后就联系房产中介进行租房,但是需要避免租客和房东的直接访问,也就是说如果租客有其他要求就需要中介进行传达租客与房东就是陌生人的关系,类似这种场景就适合使用迪米特法则;

合成复用原则

尽量先使用组合或者聚合等关联关系来实现,其次才考虑继承关系来实现;

通常类的复用分为继承复用合成复用两种;

继承的缺点:

1.继承复用破坏了类的封装性,因为继承会将父类的实现细节暴露给子类;父类对子类是透明的,因此这种复用又称为白箱复用

2.子类与父类的耦合度极高,父类的实现的任何改变都会导致子类的实现发生变化,这不利于类的扩展与维护,也容易破坏整个继承体系;

3.它限制了复用了灵活性,从父类继承而来的实现是静态的,在编译时已经定义,所以在运行的时候不可能发生变化;

采用组合或者聚合符合的时候,可以将已有的对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能;

聚合/组合复用的有点

1.它维持了类的封装性,因为成分对象的内部细节是新对象看不见的,所以这种复用又称为黑箱复用

2.对象间的耦合度低,可以在类的成员位置声明抽象

3.复用的灵活性高,这种复用可以在运行时动态进行,新对象可以动态地引用与成分对象类型相同的对象;

继承复用案例

例如我们车根据动力源可以分为电动汽车和汽油汽车,那么我们就需要创建一个车的公共父类,电动汽车和汽油汽车就分别是它的子类,但是这个时候如果每种车都对应着颜色,那么我们就需要将电动汽车和汽油汽车作为父类,再去衍生颜色的子类车型,例如白色电动汽车,黑色电动汽车等;

存在的问题

如果这个时候我们需要加一个太阳能的动力源汽车,那么我们不仅需要创建一个太阳能汽车类去继承车这个父类,还需要根据颜色去创建白色太阳能汽车,黑色太阳能汽车等去继承太阳能汽车这个父类

聚合复用

我们将颜色抽象到接口中,不同的颜色去创建不同的实现类,然后让车这个父类去聚合该颜色接口,然后子类再继承该父类,那么子类在创建对象的时候就可以去指定颜色了,那么如果之后要新增太阳能汽车,就让它去继承车这个父类,然后指定里面的颜色,如果要增加颜色,那么就生成一个实现类去实现颜色这个接口即可;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Strine

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值