(设计模式)七大原则

一.设计模式的目的

在编写软件时,为了提高①代码重用性②可读性③可扩展性④可靠性⑤高内聚,低耦合的特性。设计模型原则,是程序员在编程时,应当遵守的原则,也是各种设计模型的基础。

二.单一职责原则

1.含义:
一个类应该只负责一项职责
2.代码演示

public class Hello {
        public static void main(String[] args){
            Vehicle.run("马萨拉蒂");
            Vehicle.run("波音737");
        }
}

class Vehicle{
    public static void run(String vehicle){
        System.out.println(vehicle+"在公路上跑...");
    }
}

//马萨拉蒂在公路上跑...
//波音737在公路上跑...

3.分析:
如果地上跑的,天上飞的,水上游的都同用同一个类的话,那么单从这个类的表示上就不合适
4.代码修改

public class Hello {
        public static void main(String[] args){
            Vehicle.runRoad("马萨拉蒂");
            Vehicle.runAir("波音737");
        }
}

class Vehicle{
    public static void runRoad(String vehicle){
        System.out.println(vehicle+"在公路上跑...");
    }
    public static  void runAir(String vehicle) {
        System.out.println(vehicle + "在天上飞...");
    }
}

//马萨拉蒂在公路上跑...
//波音737在天上飞...

5.总结:
①降低类的复杂度,一个类只负责一项职责
②提高类的可读性,可维护性
③降低变更引起的风险
④通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单一职责原则;只有类中的方法数量足够少,可以在方法级别保持单一职责原则

三.接口隔离原则

1.含义:
一个类对另一个类的依赖应该建立在最小的接口上
2.代码演示

public class Hello {
        public static void main(String[] args){
            C c=new C();
            c.depend2(new A());
            D d=new D();
            d.depend4(new B());
        }
}

interface interface1{
    void function01();
    void function02();
    void function03();
    void function04();
    void function05();
}

class A implements interface1{
    public void function01(){
        System.out.println("A用了function01");
    }
    public void function02(){
        System.out.println("A用了function02");
    }
    public void function03(){
        System.out.println("A用了function03");
    }
    public void function04(){
        System.out.println("A用了function04");
    }
    public void function05(){
        System.out.println("A用了function05");
    }
}

class B implements interface1{
    public void function01(){
        System.out.println("B用了function01");
    }
    public void function02(){
        System.out.println("B用了function02");
    }
    public void function03(){
        System.out.println("B用了function03");
    }
    public void function04(){
        System.out.println("B用了function04");
    }
    public void function05(){
        System.out.println("B用了function05");
    }
}

class C{
    public void depend1(interface1 i){
        i.function01();
    }
    public void depend2(interface1 i){
        i.function02();
    }
    public void depend3(interface1 i){
        i.function03();
    }
}

class D{
    public void depend1(interface1 i){
        i.function01();
    }
    public void depend4(interface1 i){
        i.function04();
    }
    public void depend5(interface1 i){
        i.function05();
    }
}

3.分析:
C通过A实现方法的调用,A实现了interface1的接口;D通过B实现方法的调用,B实现了interface1的接口;其中A和B重写了function1、2、3、4、5,但在主函数中C只需要A的function1、2、3而B只需要D的1、4、5,那么这样看来A和B中有不需要的实现方法,既然不需要,也考虑到低耦合那么可以把没有用到的方法分开
4.代码修改

public class Hello {
    public static void main(String[] args) {
        C c = new C();
        c.depend1(new A());
        c.depend2(new A());
        c.depend3(new A());
        D d = new D();
        d.depend1(new B());
        d.depend4(new B());
        d.depend5(new B());
    }
}

interface interface1 {
    void function01();
}

interface interface2 {
    void function02();

    void function03();
}

interface interface3 {
    void function04();

    void function05();
}

class A implements interface1, interface2 {
    public void function01() {
        System.out.println("A用了function01");
    }

    public void function02() {
        System.out.println("A用了function02");
    }

    public void function03() {
        System.out.println("A用了function03");
    }
}

class B implements interface1, interface3 {
    public void function01() {
        System.out.println("B用了function01");
    }

    public void function04() {
        System.out.println("B用了function04");
    }

    public void function05() {
        System.out.println("B用了function05");
    }
}

class C {
    public void depend1(interface1 i) {
        i.function01();
    }

    public void depend2(interface2 i) {
        i.function02();
    }

    public void depend3(interface2 i) {
        i.function03();
    }
}

class D {
    public void depend1(interface1 i) {
        i.function01();
    }

    public void depend4(interface3 i) {
        i.function04();
    }

    public void depend5(interface3 i) {
        i.function05();
    }
}

5.总结
一个类对另一个类的依赖应该建立在最小的接口上,以此原则对接口进行合理拆分

四.依赖转置原则

1.含义:
①高层模块不应该依赖底层模块,二者应该依赖其抽象
②抽象不依赖细节,细节依赖抽象
③依赖转置的中心思想是面向接口编程
④设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比细节为基础的架构要稳定的多
⑤使用接口或抽象类的目的是制定好规范,而不涉及任何具体操作,把展现细节的任务交给他们的实现类去完成
2.代码演示

public class Hello {
    public static void main(String[] args) {
        Person.receive(new Email());
    }
}

class Email{
    public static void getMessage(){
        System.out.println("收到了来自Email的消息");
    }
}

class Person{
    public static void receive(Email email){
        email.getMessage();
    }
}

//收到了来自Email的消息

3.分析
在现实生活中,消息不会只来自Email,也可能来自微信,qq等其他途径。当我们代码像上面演示写的话,Person这个类里的receive方法只能接受Email对象,如果想对接受来自其他地方的消息提示,则需要再构建新的方法,这样就增加了工作量,不利于维护。
4.代码修改

public class Hello {
    public static void main(String[] args) {
        Person.receive(new Email());
        Person.receive(new Wechat());
    }
}

interface IReceive{
    public void getMessage();
}

class Email implements IReceive{
    public void getMessage(){
        System.out.println("收到了来自Email的消息");
    }
}

class Wechat implements  IReceive{
    public void getMessage(){
        System.out.println("收到了来自Wechat的消息");
    }
}

class Person{
    public static void receive(IReceive ireceive){
        ireceive.getMessage();
    }
}

//收到了来自Email的消息
//收到了来自Wechat的消息

5.总结
①底层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好
②变量的声明类型尽量使抽象类或接口,这样我们的变量引用或实际对象间,就存在一个缓冲层,利于程序扩展和优化
③继承时遵循里氏替换原则

五.里氏替换原则

1.含义
①所有引用基类的地方必须能够透明地使用其子类的对象
②子类中尽量不要重写父类的方法
③继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合、组合、依赖来解决问题
2.代码展示

public class Hello {
    public static void main(String[] args) {
        A a=new A();
        System.out.println("1+1="+a.sum(1,1));
        B b=new B();
        System.out.println("1+1="+b.sum(1,1));
        System.out.println("1-1="+b.minus(1,1));
    }
}

class Base{
    public int sum(int a,int b){
        return a+b;
    }
}

class A extends Base{
    A(){
        System.out.println("调用A");
    }
}

class B extends Base{
    B(){
        System.out.println("调用B");
    }
    public int minus(int a,int b){
        return a-b;
    }
}

//调用A
//1+1=2
//调用B
//1+1=2
//1-1=0

3.分析
A和B都继承了Base,且都没有修改sum方法
4.总结
如果A和B拥有相同的方法,尽量构建多一个更加通俗的基类,采用依赖、聚合、组合等关系代替

六.开闭原则

1.含义:
①开闭原是编程中最基础、最重要的设计原则。之前学习的几个原则组合起来可以集中体现这个原则
②一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节
③当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有代码来实现变化
④编程中遵循其他原则,以及使用设计模式的目的就是遵循开闭原则
2.代码演示:

public class Hello {
    public static void main(String[] args) {
        DrawShape drawShape=new DrawShape();
        drawShape.draw(new Rectangle());
        drawShape.draw(new Circle());
    }
}

class Shape{
    int type;
}

class Rectangle extends Shape{
    Rectangle(){
        super.type=1;
    }
}

class Circle extends  Shape{
    Circle(){
        super.type=2;
    }
}
class DrawShape {

    public void drawRectangle(){
        System.out.println("画了个长方形");
    }
    public void drawCircle(){
        System.out.println("画了个圆形");
    }
    public void draw(Shape shape){
        if(shape.type==1)
            drawRectangle();
        else if(shape.type==2)
            drawCircle();
    }
}

3.分析:
演示的代码非常繁杂,且不好维护。如果我们想添加画一个正方形,那么必须添加一个正方形的类、DrawShape添加画正方形的方法以及else if。这使得在后期需要对软件进行增添会有非常大的阻力
4.代码修改:

public class Hello {
    public static void main(String[] args) {
        DrawShape drawShape=new DrawShape();
        drawShape.draw(new Rectangle());
        drawShape.draw(new Circle());
    }
}

abstract class Shape{
    abstract public void draw();
}

class Rectangle extends Shape{
    @Override
    public void draw() {
        System.out.println("画了个长方形");
    }
}

class Circle extends Shape{
    @Override
    public void draw() {
        System.out.println("画了个圆形");
    }
}
class DrawShape {

    public void draw(Shape shape){
        shape.draw();
    }
}

5.总结:
遵循开闭原则对修改代码添加功能拥有非常好的帮助,也是对前几个原则的进行的集合

七.迪米特原则

1.含义
①一个对象对其他对象保持最少的了解。因为类与类关系越密切,耦合度越大
②又称最少知道原则,即一个类对自己以来的类知道越少越好。也就是说,对于被以来的类不管多么复杂,都尽量将逻辑封装在类的内部。除了提供的public,不对外泄露任何信息
③只与直接的朋友通信,我们称出现成员变量,方法参数,方法返回值中的类为直接朋友。陌生的类最好不要以局部变量的形式出现在类的内部
2.总结
降低非直接朋友的耦合度

八.合成复用原则

1.含义
①原则是尽量使用合成/聚合的方式,而不是使用继承

九.总结

通过对七大原则的学习,可以进行的总结就是:在设计软件前首先要对类的分工进行明确,类与类之间的耦合度通过合成/聚合尽可能的减少,顾及后期的维护需要对基础类进行构建。

PS:因为刚学习的设计模式,做出来的笔记并不深入,在后续的学习中会继续添加关于这七大原则的见解。

发布了19 篇原创文章 · 获赞 4 · 访问量 522

猜你喜欢

转载自blog.csdn.net/zhuangww05/article/details/104765801
今日推荐