尚硅谷设计模式学习---[设计模式七大原则](代码片段)

小智RE0 小智RE0     2023-01-05     411

关键词:

尚硅谷传送门==>B站尚硅谷Java设计模式

❤❤❤感谢尚硅谷❤❤❤

最近开始计划学习一下设计模式了,加油!!!



设计模式就是对软件设计中普遍存在(反复出现)的问题,提出的解决方案.

面向对象 = =>功能模块[设计模式+算法(数据结构)]
= =>框架[使用到多种设计模式]= = >架构 [服务器集群]

设计模式的目的是为了 提高代码的可重用性 (相同功能的代码提取出来), 可读性 (编写程序时规范书写),可扩展性 (方便扩展增加新功能), 可靠性 (增加新功能后不影响原来的代码),使得程序高内聚,低耦合.

七大原则是指==> 单一职责原则; 接口隔离原则 ;依赖倒置原则;里氏替换原则 ;开闭原则 ;迪米特原则;合成复用原则.

尽量针对接口编程


1.单一职责原则( Single Responsibility Principle)

通俗地说就是, 一个类就管理一件事, 职责单一;

比如说一个实体类User,它就只负责用户的属性和方法.

或者说在一个类中;每个方法仅负责自己的功能;各司其职;

降低了类的复杂性;提高了可读性

案例:比如说有个交通工具类Transport

/**
 * @Date: 2021/09/21/12:13
 * 单一职责原则学习
 */
public class SingleResponsibility01 
    public static void main(String[] args) 
        Transport transport = new Transport();
        transport.run("小汽车");
        transport.run("轮船");
        transport.run("飞机");
    


//交通工具类
class   Transport
    public void run(String transport)
        System.out.println(transport+"正在路上跑");
    

诶,运行后发现;明显不符合逻辑啊;违反了单一职责的原则.

小汽车正在路上跑
轮船正在路上跑
飞机正在路上跑

OK,接下来对它进行修改;
方式1;把交通工具这个类分解开;分成 路上跑的; 天上飞的; 水里游的 交通工具;

/**
 * @Date: 2021/09/21/12:28
 * 单一职责原则学习
 */
public class SingleResponsibility02 
    public static void main(String[] args) 
        RoundTransport roundTransport = new RoundTransport();
        roundTransport.run("小汽车");

        SkyTransport skyTransport = new SkyTransport();
        skyTransport.run("飞机");

        SwimTransport swimTransport = new SwimTransport();
        swimTransport.run("轮船");
    


//将原来的交通工具类分类;分为3个类;

//路上跑的交通工具类;
class RoundTransport
    public void run(String roundTransport)
        System.out.println(roundTransport+"在路上跑");
    

//在天上飞的工具;
class SkyTransport
    public void run(String skyTransport)
        System.out.println(skyTransport+"在天上飞");
    

//在水里游的工具;
class SwimTransport
    public void run(String swimTransport)
        System.out.println(swimTransport+"在水里游");
    

诶,每个类负责一种交通工具;

小汽车在路上跑
飞机在天上飞
轮船在水里游

虽然说遵守了单一职责原则,但是将原先的类分解,同时修改了客户端;

方式2;直接在交通工具类中扩展不同的方法;分别负责不同的功能;

public class SingleResponsibility03 
    public static void main(String[] args) 
        Transport transport = new Transport();
        transport.runRond("小汽车");
        transport.runSwim("轮船");
        transport.runSky("飞机");
    


//交通工具类
class   Transport
    //路上跑的交通工具执行方法;
    public void runRond(String transport)
        System.out.println(transport+"正在路上跑");
    
    //天上飞的交通工具执行方法;
    public void runSky(String transport)
        System.out.println(transport+"正在天上飞");
    
    //水里游的交通工具执行方法;
    public void runSwim(String transport)
        System.out.println(transport+"正在水里游");
    

每个方法负责实现一种功能;在方法上,遵守了单一职责原则

小汽车正在路上跑
轮船正在水里游
飞机正在天上飞

2.接口隔离原则(Interface Segregation Principle)

比如说,一个接口有许多方法,但是类 A 需要的功能只有几个方法,那么就需要把原来的接口拆分一下,让类A去通过他需要的接口去使用方法.

案例;
一个接口有5个方法;类B和类D实现接口;
而类A依赖类B后,仅使用方法1,方法2,方法3;
而类C依赖类D后;仅使用方法1,方法4,方法5;

package com.lzq.principle.interfacesegregation;

public class InterfaceSegregation01 
    public static void main(String[] args) 

    


//接口'
interface Interface1
    void method1();
    void method2();
    void method3();
    void method4();
    void method5();


//类 B 实现接口;
class B implements Interface1
    public void method1() 
        System.out.println("类B实现接口的方法1 ");
    

    public void method2() 
        System.out.println("类B实现接口的方法2 ");
    

    public void method3() 
        System.out.println("类B实现接口的方法3 ");
    

    public void method4() 
        System.out.println("类B实现接口的方法4 ");
    

    public void method5() 
        System.out.println("类B实现接口的方法5 ");
    


//类 D 实现接口;
class D implements Interface1
    public void method1() 
        System.out.println("类D实现接口的方法1 ");
    

    public void method2() 
        System.out.println("类D实现接口的方法2 ");
    

    public void method3() 
        System.out.println("类D实现接口的方法3 ");
    

    public void method4() 
        System.out.println("类D实现接口的方法4 ");
    

    public void method5() 
        System.out.println("类D实现接口的方法5 ");
    


//类  A 通过参数接口 依赖 类B ; 仅需要方法1,方法2,方法3;
class A
    public  void depend1(Interface1 interface1)
        interface1.method1();
    
    public  void depend2(Interface1 interface1)
        interface1.method2();
    
    public  void depend3(Interface1 interface1)
        interface1.method3();
    


//类 C 通过参数接口 依赖 类D ,仅需要方法1,方法4,方法5;
class C
    public  void depend1(Interface1 interface1)
        interface1.method1();
    
    public  void depend4(Interface1 interface1)
        interface1.method4();
    
    public  void depend5(Interface1 interface1)
        interface1.method5();
    

但是,按着这样分配的话,那么类C没必要去写方法4和方法5;类D没有必要去写方法2和方法3;

优化

将接口拆分为3个接口;
一个接口放置方法1;
一个接口放置方法2和方法3;
一个接口放置方法4和方法5.

package com.lzq.principle.interfacesegregation;

/**
 * @Date: 2021/09/21/13:00
 */
public class InterfaceSegregation02 
    public static void main(String[] args) 
        //类A通过接口去使用类B;
        A a=new A();
        a.depend1(new B());
        a.depend2(new B());
        a.depend3(new B());
        //类C通过接口去使用类D;
        C c=new C();
        c.depend1(new D());
        c.depend4(new D());
        c.depend5(new D());
    


//接口'
interface Interface1
    void method1();

//接口拆分出的接口2;
interface Interface2
    void method2();
    void method3();


//接口拆分出的接口3;
interface Interface3
    void method4();
    void method5();


//类 B 实现接口;
class B implements Interface1,Interface2
    public void method1() 
        System.out.println("类B实现接口1的方法1 ");
    

    public void method2() 
        System.out.println("类B实现接口2的方法2 ");
    

    public void method3() 
        System.out.println("类B实现接口2的方法3 ");
    


//类 D 实现接口;
class D implements Interface1,Interface3
    public void method1() 
        System.out.println("类D实现接口1的方法1 ");
    

    public void method4() 
        System.out.println("类D实现接口3的方法4 ");
    

    public void method5() 
        System.out.println("类D实现接口3的方法5 ");
    


//类  A 通过参数接口 依赖 类B ; 仅需要方法1,方法2,方法3;
class A
    public  void depend1(Interface1 interface1)
        interface1.method1();
    
    public  void depend2(Interface2 interface2)
        interface2.method2();
    
    public  void depend3(Interface2 interface2)
        interface2.method3();
    


//类 C 通过参数接口 依赖 类D ,仅需要方法1,方法4,方法5;
class C
    public  void depend1(Interface1 interface1)
        interface1.method1();
    
    public  void depend4(Interface3 interface3)
        interface3.method4();
    
    public  void depend5(Interface3 interface3)
        interface3.method5();
    

输出

B实现接口1的方法1B实现接口2的方法2B实现接口2的方法3D实现接口1的方法1D实现接口3的方法4D实现接口3的方法5 

3.依赖倒置原则(Dependence Inversion Principle)

核心就是面向接口编程;
让细节的具体实现类去依赖(使用)抽象类或者接口;而不是让接口或抽象类去依赖细节的具体实现类.

案例;

不用依赖倒置原则的案例;
比如说,有一个短信类,一个QQ消息类;
在用户Person类中需要不同的方法接受不同的消息.

public class DependenceInversion01 
    public static void main(String[] args) 
        Person person=new Person();
        person.getMes(new QQ());
        person.getMes(new Message());
    


//短信类;
class Message
    public String show()
       return "收到短信了";
    


//QQ消息;
class QQ
    public String show()
       return "收到QQ消息了";
    


//具体的人;
class Person
    //接收短信;
    public void getMes(Message message)
        System.out.println(message.show());
    
    //接收QQ消息;
    public void getMes(QQ qq)
        System.out.println(qq.show());
    

虽然输出没什么问题;但是一旦又需要接受电子邮件信息呢,接受电话呢…;又要在Person类中重新写方法吗?

收到QQ消息了
收到短信了

根据依赖倒置原则进行案例优化

将接受消息的方法提取;变为接口GetMes;
这样,即使需要接受别的消息,也不用在Person类中再去增加方法;

public class DependenceInversion02 
    public static void main(String[] args) 
        Person person=new Person();
        person.getMes(new QQ());
        person.getMes(new Message());
    


//接收消息的接口;
interface GetMes
    //看看收到的消息;
    String show();


//短信类;
class Message implements GetMes
    public String show()
       return "收到短信了";
    


//QQ消息;
class QQ implements GetMes
    public String show()
       return "收到QQ消息了";
    


//具体的人;
class Person
    //接收消息;
    public void getMes(GetMes getMes)
        System.out.println(getMes.show());
    


关于依赖倒置原则中的依赖关系传递三种方式;
接口传递 ;构造方法传递 ;setter方法传递


4.里氏替换原则(Liskov Substitution Principle)

在面向对象编程语言的继承关系中,父类已经实现的方法,若子类进行修改,可能会产生问题.

使用继承虽然是比较方便的,但是会出现入侵,程序的可移植性降低,程序间的耦合性过高.

根据里氏替换原则,子类中尽量不要重写父类的方法;
所有引用父类的位置,要做到可以透明地使用子类的对象.
如果说子类还是需要父类的方法,可采用聚合,组合,依赖的方式.


案例;类 B 继承了类 A后,没有注意到已经重写了类A的方法 func1();
而且在重写的方法内修改了具体实现.

public class LiskovSubstitution01 
    public static void main(String[] args) 
        System.out.println("类A调用方法");
        A a = new A();
        System.out.println("11-3=" + a.func1(11, 3));
        System.out.println("1-8=" + a.func1(1, 8));
        System.out.println("类B调用方法");
        B b = new B();
        System.out.println("11-3=" + b.func1(11, 3));
        System.out.println("1-8=" + b.func1(1, 8));
        System.out.println("11+3+9=" + b.func2(11, 3));
    


//类 A 完成两数相减的任务;
class A 
    public int func1(int num1, int num2) 查看详情  

尚硅谷设计模式学习---[uml类图](代码片段)

...#x1f680;🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤🛴🛴🛴最近开始计划学习一下设计模式了,加油!!!目录UML类图类和类之间的依赖关系(Dependence)类与类之间的泛化关系(继承)(Ge... 查看详情

尚硅谷设计模式学习---[单例模式](代码片段)

...#x1f680;🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤🛴🛴🛴最近开始计划学习一下设计模式了,加油!!!目录单例模式🛴1.饿汉式(静态常量版)🛴2.饿汉式(静态代码块版)&#x... 查看详情

尚硅谷设计模式学习---[装饰者模式](代码片段)

...#x1f680;🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤🕒🕑🕐最近开始计划学习一下设计模式了,加油!!!目录📢情景引入⚡装饰者模式装饰者模式在Io中的应用📢情景引入... 查看详情

尚硅谷设计模式学习(17)---[迭代器模式(iteratorpattern)](代码片段)

尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤最近开始计划学习一下设计模式了,加油!!!ml情景引入迭代器模式ArrayList集合中应用的迭代器模式情景引入这次的案例就是之前学习组合模式用到的案例=... 查看详情

尚硅谷设计模式学习---[桥接模式(bridge)](代码片段)

...#x1f680;🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤👀最近开始计划学习一下设计模式了,加油!!!目录📢情景引入⚡桥接模式桥接模式在JDBC中的应用📢情景引入现在市面上有各... 查看详情

尚硅谷设计模式学习(24)---[职责链模式(chainofresponsibilitypattern)](代码片段)

尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤最近开始计划学习一下设计模式了,加油!!!ml情景引入职责链模式情景引入首先看一个案例学校OA系统的采购审批项目:需求是1采购员采购教学器材2如果... 查看详情

尚硅谷设计模式学习(10)---[组合模式(compositepattern)](代码片段)

...#x1f680;🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤🕐🕑🕒最近开始计划学习一下设计模式了,加油!!!目录📢情景引入🌈组合模式组合模式在HashMap中的应用📢情景... 查看详情

尚硅谷设计模式学习---[建造者模式(builderpattern)](代码片段)

...#x1f680;🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤🛴🛴🛴最近开始计划学习一下设计模式了,加油!!!目录📢情景引入🏡建造者模式使用建造者模式的jdk案例📢情... 查看详情

尚硅谷设计模式学习(11)---[外观模式(facade)](代码片段)

...#x1f680;🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤🕐🕑🕒最近开始计划学习一下设计模式了,加油!!!目录📢情景引入🌈外观模式📢情景引入组建一个家庭影院ÿ... 查看详情

尚硅谷设计模式学习(22)---[状态模式(statepattern)](代码片段)

尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤最近开始计划学习一下设计模式了,加油!!!状态模式来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为一一对应,状态之间... 查看详情

尚硅谷设计模式学习(14)---[模板方法模式(templatemethodpattern)](代码片段)

尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤最近开始计划学习一下设计模式了,加油!!!目录模板方法模式模板方法模式中的钩子方法先看一个流程化豆浆的制作问题制作豆浆的流程选材—>添加配料—... 查看详情

尚硅谷设计模式学习(15)---[命令模式(commandpattern)](代码片段)

尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤最近开始计划学习一下设计模式了,加油!!!先看一个案例买了一套智能家电,有照明灯、风扇、冰箱、洗衣机,只要在手机上安装app就可以控制对这些... 查看详情

尚硅谷设计模式学习(12)---[享元模式(flyweightpattern)](代码片段)

...#x1f680;🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤🕐🕑🕒最近开始计划学习一下设计模式了,加油!!!目录📢情景引入🌈享元模式享元模式在Integer中的应用📢情景... 查看详情

尚硅谷设计模式学习---[简单工厂模式,工厂方法模式,抽象工厂模式](代码片段)

...#x1f680;🚀🚀尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤🛴🛴🛴最近开始计划学习一下设计模式了,加油!!!目录🚗简单工厂模式🚗工厂方法模式🚗抽象工厂模式🚗... 查看详情

尚硅谷设计模式学习(19)---[中介者模式(mediatorpattern)](代码片段)

尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤最近开始计划学习一下设计模式了,加油!!!案例智能家庭项目:智能家庭包括各种设备,闹钟、咖啡机、电视机、窗帘等例如看电视之前,各个设... 查看详情

尚硅谷设计模式学习(21)---[解释器模式(interpreterpattern)](代码片段)

尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤最近开始计划学习一下设计模式了,加油!!!解释器模式给定语言(表达式),定义它的表示,并定义解释器,使用该解释器来解释语言中的句子(表达... 查看详情

尚硅谷设计模式学习(18)---[观察者模式(observerpattern)](代码片段)

尚硅谷传送门==>B站尚硅谷Java设计模式❤❤❤感谢尚硅谷❤❤❤最近开始计划学习一下设计模式了,加油!!!ml情景引入观察者模式情景引入天气预报项目需求:1气象站可以将每天测量到的温度,湿度,气压等等以公... 查看详情