设计模式随笔


设计模式七大原则

第一章

设计模式的目的

设计模式的七大原则(要有印象)

1.开闭原则:用抽象构建架构,用实现扩展细节

2.依赖倒置原则:高层模块不应该依赖于底层模块,二者都应该依赖其抽象

3.单一职责原则:单个接口或类不应该有多个职责,应该尽可能的划分职责,通过组合的方式,完成更为复杂的业务

4.接口隔离原则:一个接口不要包含过多的职责,应合理划分,跟单一职责原则相辅相成

典型场景:动物、人、鸟,人和鸟都会吃,人会走路,鸟会飞,应该把走路和飞这两个行为抽象成接口,通过组合的方式让人拥有走路的行为,让鸟拥有飞的行为。再细划分,人有多个走路姿势,鸟有多个飞行方式,可以分别继承走路和飞的抽象行为扩展其具体的行为
5.迪米特法则:也就最少知道原则,一个对象尽量让其它对象保持最少的了解

典型场景:我点外卖,我只关心外卖员,不关系具体的店。我的类中只依赖外卖员,不会依赖具体的店。是不是静态代理。
6.里氏替换原则:在引用父类的地方,都可以替换为其子类。从而可以实现子类间的动态切换。换句话说就是要有面向接口的编程思维。结合“开闭原则”,完美

7.合成复用原则:多用组合,少用继承

单一职责原则

解释:

在面对对象编程中,每个对象只负责自己的任务,比如该提供数据的就只是提供数据,该负责提供服务的就只提供服务,或者只是维护对象之间的关系,这样的开发方式代码耦合度较低,较灵活,易扩展。

https://blog.csdn.net/zhengzhb/article/details/7278174

接口隔离原则

基本介绍

一个类通过接口去依赖另一个类,依赖应该建立在最小的接口下

https://blog.csdn.net/king123456man/article/details/81626059

https://www.cnblogs.com/alunchen/p/7115675.html

例子

image-20211105085952883
/**
 * @Author: suny
 * @Date: 2021/11/04 下午6:56
 * @Description:
 */
public class Segregation1 {

    public static void main(String[] args) {

    }
}
//接口 默认权限的修饰符是public
interface Interface1 {
    void operation1();
    void operation2();
    void operation3();
    void operation4();
    void operation5();
}
//类B
class B implements Interface1 {

    @Override
    public void operation1() {
        System.out.println("B实习了操作1");
    }

    @Override
    public void operation2() {
        System.out.println("B实习了操作2");
    }

    @Override
    public void operation3() {
        System.out.println("B实习了操作3");
    }

    @Override
    public void operation4() {
        System.out.println("B实习了操作4");
    }

    @Override
    public void operation5() {
        System.out.println("B实习了操作5");
    }
}
//类D
class D implements Interface1 {
    @Override
    public void operation1() {
        System.out.println("B实习了操作1");
    }

    @Override
    public void operation2() {
        System.out.println("B实习了操作2");
    }

    @Override
    public void operation3() {
        System.out.println("B实习了操作3");
    }

    @Override
    public void operation4() {
        System.out.println("B实习了操作4");
    }

    @Override
    public void operation5() {
        System.out.println("B实习了操作5");
    }
}

// A类通过接口Interface1 依赖(使用) B类,但是只会用到1,2,3方法
class A {
    public void depend1(Interface1 i) {
        i.operation1();
    }

    public void depend2(Interface1 i) {
        i.operation2();
    }

    public void depend3(Interface1 i) {
        i.operation3();
    }
}

// A类通过接口Interface1 依赖(使用) B类,但是只会用到1,4,5方法
class C {
    public void depend1(Interface1 i) {
        i.operation1();
    }

    public void depend2(Interface1 i) {
        i.operation4();
    }

    public void depend3(Interface1 i) {
        i.operation5();
    }
}

改进

image-20211105090724246
/**
 * @Author: suny
 * @Date: 2021/11/04 下午6:56
 * @Description: 接口隔离原则
 */
public class Segregation1Better {

    public static void main(String[] args) throws InterruptedException {
        A1 a1 = new A1();
        //A1类通过接口去依赖(使用)B1类
        a1.depend1(new B1());
        a1.depend2(new B1());
        a1.depend3(new B1());
        System.out.println("****************");
        C1 c1 = new C1();
        //C1类通过接口去依赖(使用)D类
        c1.depend1(new D1());
        c1.depend2(new D1());
        c1.depend3(new D1());
    }
}

//接口 默认权限的修饰符是public
interface Interface01 {
    void operation1();
}

interface Interface02 {
    void operation2();
    void operation3();
}

interface Interface03 {
    void operation4();
    void operation5();
}

class B1 implements Interface01,Interface02 {

    @Override
    public void operation1() {
        System.out.println("B实习了操作1");
    }

    @Override
    public void operation2() {
        System.out.println("B实习了操作2");
    }

    @Override
    public void operation3() {
        System.out.println("B实习了操作3");
    }
}
class D1 implements Interface01,Interface03 {

    @Override
    public void operation1() {
        System.out.println("D实习了操作1");
    }

    @Override
    public void operation4() {
        System.out.println("D实习了操作4");
    }

    @Override
    public void operation5() {
        System.out.println("D实习了操作5");
    }
}

class A1 {
    void depend1(Interface01 i){
        i.operation1();
    }
    void depend2(Interface02 i){
        i.operation2();
    }
    void depend3(Interface02 i){
        i.operation3();
    }
}

class C1 {
    void depend1(Interface01 i){
        i.operation1();
    }
    void depend2(Interface03 i){
        i.operation4();
    }
    void depend3(Interface03 i){
        i.operation5();
    }
}

依赖倒转原则

https://blog.csdn.net/king123456man/article/details/81626127

https://www.cnblogs.com/rmxd/p/12539269.html

例子

/**
 * @Author: suny
 * @Date: 2021/11/04 下午8:38
 * @Description:
 */
public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.receive(new Email());
    }
}

class Email {
    public String getInfo() {
        return "电子邮件信息:hello world!";
    }
}

//完成Person接受消息的功能
//方式 1
// 1.简单,容易
// 2 如果我们获取的对象是微信,短信, 增新增类,Person类要增加接受方法
// 3 解决思路: 引入一个抽象的接口 IReveiver,表示接受者,这样Person类和接口发生依赖
//  因为Email,WeiXin 等 都是接受范围,他们各自实习IReveiver接口就可以,这样就实现类符号依赖倒置原则
class Person {
    public void receive(Email email) {
        System.out.println(email.getInfo());
    }
}

改进

package com.inversion;

/**
 * @Author: suny
 * @Date: 2021/11/04 下午8:38
 * @Description:
 */
public class DependecyInversionBetter {
    public static void main(String[] args) {
        //=客户端不需要改变
        Person2 person = new Person2();
        person.receive(new Email2());
        person.receive(new WeiXin());

    }
}

//定义一个接口
interface IReceiver {
    public String getInfo();
}

class Email2 implements IReceiver{
    public String getInfo() {
        return "电子邮件信息:hello world!";
    }
}

class WeiXin implements IReceiver{

    @Override
    public String getInfo() {
        return "微信信息:Hi WeiXin!";
    }
}

class Person2 {
    public void receive(IReceiver receiver) {
        System.out.println(receiver.getInfo());
    }
}

依赖关系的传递3种:

接口传递依赖、构造方法、setter方法

import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
/**
 * @Author: suny
 * @Date: 2021/11/04 下午9:18
 * @Description: 依赖的传递方式
 */
public class Cdfs {
    public static void main(String[] args) {

        //接口依赖传递
        AppleTV appleTV = new AppleTV();
        OpenAndClose openAndClose = new OpenAndClose();
        openAndClose.open(appleTV);

        //构造器进行依赖传递  常用
        OpenAndClose2 openAndClose2 = new OpenAndClose2(new XiaoMiTV());
        openAndClose2.open();

        //setter方法依赖传递  常用
        OpenAndClose3 openAndClose3 = new OpenAndClose3();
        openAndClose3.setTv(new HuaWeiTV());
        openAndClose3.open();



    }
}

// 方式1 通过接口实现依赖传递

//开关的接口
interface IOpenAndCLose {
    public void open(ITV tv);
}
// ITV接口
interface ITV {
    public void play();
}

class AppleTV implements ITV {

    @Override
    public void play() {
        System.out.println("打开苹果TV");
    }
}
//接口的实现
class OpenAndClose implements IOpenAndCLose{

    @Override
    public void open(ITV tv) {
        tv.play();
    }
}

//方式2 通过构造方法实现依赖传递
interface IOpenAndCLose2 {
    public void open();
}
// ITV接口
interface ITV2 {
    public void play();
}
class XiaoMiTV implements ITV2{

    @Override
    public void play() {
        System.out.println("打开小米TV");
    }
}
//接口的实现
class OpenAndClose2 implements IOpenAndCLose2{

    public ITV2 itv2;
    public OpenAndClose2(ITV2 itv2){
        this.itv2 = itv2;
    }

    @Override
    public void open() {
        itv2.play();
    }
}

// 方式3 通过setter方法
interface IOpenAndCLose3 {
    public void open();

    public void setTv(ITV3 itv3);
}
// ITV接口
interface ITV3 {
    public void play();
}
class HuaWeiTV implements ITV3{
    @Override
    public void play() {
        System.out.println("打开华为TV");
    }
}

//接口的实现
class OpenAndClose3 implements IOpenAndCLose3{

    public ITV3 itv3;

    @Override
    public void setTv(ITV3 itv3) {
        this.itv3 = itv3;
    }
    @Override
    public void open() {
        this.itv3.play();
    }
}

里氏替换原则

原则:

用子类替换父类,对之前用父类的地方没有影响

子类尽量不要重写父类方法

原来的父类和子类都继承一个更通俗的父类,原有的继承关系去掉,采用依赖,聚合,组合的关系代替。

https://blog.csdn.net/zhengzhb/article/details/7281833

开闭原则

提供者提供修改,使用时关闭修改权限

http://c.biancheng.net/view/1322.html

迪米特法则

最少知道原则

https://blog.csdn.net/qq_38844728/article/details/88739574

合成复用原则

合成复用原则由成为组合/聚合复用原则,尽量使用对象组合,而不是继承来达到复用的目的

https://blog.csdn.net/atu1111/article/details/105360942/

https://www.cnblogs.com/yangda/p/11954137.html


文章作者: fejxc
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 fejxc !
评论
  目录