110.【十万字带你深入学习23种设计模式】(四)

简介: 110.【十万字带你深入学习23种设计模式】

实现类

package com.jsxs.principles.demo4.befor;
/**
 * @Author Jsxs
 * @Date 2023/4/16 10:15
 * @PackageName:com.jsxs.principles.demo4.befor
 * @ClassName: HeimaSaferDoor
 * @Description: TODO  实现类
 * @Version 1.0
 */
public class HeimaSaferDoor implements SafeDoor{
    @Override
    public void antiTheft() {
        System.out.println("防盗");
    }
    @Override
    public void fireProof() {
        System.out.println("防火");
    }
    @Override
    public void waterProof() {
        System.out.println("防水");
    }
}

测试类

package com.jsxs.principles.demo4.befor;
/**
 * @Author Jsxs
 * @Date 2023/4/16 10:17
 * @PackageName:com.jsxs.principles.demo4.befor
 * @ClassName: SafeDoorTest
 * @Description: TODO
 * @Version 1.0
 */
public class SafeDoorTest {
    public static void main(String[] args) {
        HeimaSaferDoor heimaSaferDoor = new HeimaSaferDoor();
        heimaSaferDoor.antiTheft();
        heimaSaferDoor.fireProof();
        heimaSaferDoor.waterProof();
    }
}

上面的设计我们发现问题: 黑马品牌的安全门具有防盗、防火、防水的功能。现在如果我们还需要再创建一个传智品牌的安全们,而它只具有防盗、防水的功能。很显然我们这里设计的接口就违反了接口隔离原则,那么我们如何进行修改呢?

正列:

接口1

package com.jsxs.principles.demo4.after;
/**
 * @Author Jsxs
 * @Date 2023/4/16 10:29
 * @PackageName:com.jsxs.principles.demo4.after
 * @ClassName: fireProof
 * @Description: TODO
 * @Version 1.0
 */
public interface fireProof {
    void fire();
}

接口2

package com.jsxs.principles.demo4.after;
/**
 * @Author Jsxs
 * @Date 2023/4/16 10:29
 * @PackageName:com.jsxs.principles.demo4.after
 * @ClassName: waterProof
 * @Description: TODO  防水
 * @Version 1.0
 */
public interface waterProof {
    void water();
}

接口三

package com.jsxs.principles.demo4.after;
/**
 * @Author Jsxs
 * @Date 2023/4/16 10:30
 * @PackageName:com.jsxs.principles.demo4.after
 * @ClassName: theafProof
 * @Description: TODO
 * @Version 1.0
 */
public interface theafProof {
    void thymef();
}

黑马门

package com.jsxs.principles.demo4.after;
/**
 * @Author Jsxs
 * @Date 2023/4/16 10:30
 * @PackageName:com.jsxs.principles.demo4.after
 * @ClassName: HeimaDoor
 * @Description: TODO
 * @Version 1.0
 */
public class HeimaDoor implements fireProof,waterProof{
    @Override
    public void fire() {
        System.out.println("防火");
    }
    @Override
    public void water() {
        System.out.println("防水");
    }
}

测试实验

package com.jsxs.principles.demo4.after;
/**
 * @Author Jsxs
 * @Date 2023/4/16 10:31
 * @PackageName:com.jsxs.principles.demo4.after
 * @ClassName: DoorTest
 * @Description: TODO
 * @Version 1.0
 */
public class DoorTest {
    public static void main(String[] args) {
        HeimaDoor heimaDoor = new HeimaDoor();
        heimaDoor.fire();
        heimaDoor.water();
    }
}

(5).迪米特法则 (直接与间接)

迪米特法则又叫最少知识原则

只和你的直接朋友交谈,不跟陌生人说话。 其含义是: 如果两个软件实体无需直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发调用。其目的是降低类之间的耦合度,提高模块的相对独立开发。

迪米特法则中的 "朋友"是指: 当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等。这些兑现同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。

eg: 明星和经纪人的关系实列

明星由于全身心的投入艺术、所以很多的日常事务都是由经纪人负责处理的,比如粉丝的见面会和媒体公司的业务洽谈等。这里的经纪人是明星的朋友,而粉丝和媒体公司是明星的陌生人,所以适合使用迪米特法则。

明星

package com.jsxs.principles.demo5;
/**
 * @Author Jsxs
 * @Date 2023/4/16 11:00
 * @PackageName:com.jsxs.principles.demo5
 * @ClassName: Star
 * @Description: TODO
 * @Version 1.0
 */
public class Star {
    private String name;
    public Star(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

粉丝

package com.jsxs.principles.demo5;
/**
 * @Author Jsxs
 * @Date 2023/4/16 11:01
 * @PackageName:com.jsxs.principles.demo5
 * @ClassName: Fans
 * @Description: TODO  粉丝类
 * @Version 1.0
 */
public class Fans {
    private String name;
    public Fans(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

公司

package com.jsxs.principles.demo5;
/**
 * @Author Jsxs
 * @Date 2023/4/16 11:02
 * @PackageName:com.jsxs.principles.demo5
 * @ClassName: Bussiness
 * @Description: TODO  媒体公司类
 * @Version 1.0
 */
public class Company {
    private String name;
    public Company(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

经纪人

package com.jsxs.principles.demo5;
/**
 * @Author Jsxs
 * @Date 2023/4/16 11:03
 * @PackageName:com.jsxs.principles.demo5
 * @ClassName: Agent
 * @Description: TODO  经纪人类
 * @Version 1.0
 */
public class Agent {
    private Star star;
    private Fans fans;
    private Company company;
    public void setStar(Star star) {
        this.star = star;
    }
    public void setFans(Fans fans) {
        this.fans = fans;
    }
    public void setCompany(Company company) {
        this.company = company;
    }
    // 1.和粉丝见面
    public void meeting(){
        System.out.println(star.getName()+"见面粉丝"+fans.getName());
    }
    //2.和媒体公司洽谈
    public void business(){
        System.out.println(star.getName()+"洽谈公司"+company.getName());
    }
}

测试

package com.jsxs.principles.demo5;
/**
 * @Author Jsxs
 * @Date 2023/4/16 11:06
 * @PackageName:com.jsxs.principles.demo5
 * @ClassName: StarTest
 * @Description: TODO
 * @Version 1.0
 */
public class StarTest {
    public static void main(String[] args) {
        Fans fans = new Fans("李明");
        Company company = new Company("CKQN");
        Star star = new Star("及你太美");
        Agent agent = new Agent();
        agent.setStar(star);
        agent.setCompany(company);
        agent.setFans(fans);
        agent.business();
        agent.meeting();
    }
}

(6).合成复用原则

合成复用原则是指: 尽量先使用组合或则和聚合等关系来实现,其次再开率使用继承关系来实现

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

继承复用虽然有简单和容易实现的优点,但它也存在以下缺点:

  1. 继承复用破坏了类的封装性。因为继承会将父类的实现细节暴露给子类,父类对子类是透明的,所以这种复用又称为"白箱"复用
  2. 子类与父类的耦合度高。父类的实现的任何改变都会导致子类的实现发生变化,这不利于类的扩展和维护
  3. 它限制了复用的灵活性。从子类继承而来的实现是静态的,在编译时已经定义,所以再运行时不可能发生变化。

采用组合或聚合复用时,可以将已有对象纳入新的对象中,使之称为对象的一部分,新对象可以调用已有对象的功能,它有以下的优点:

  1. 它维持了类的封装性。因为成分对象的内部细节时新对象看不见的,所以这种服用又称为"黑箱"复用。
  2. 对象的耦合度低。可以在类的成员位置声明抽象。
  3. 复用的灵活性高。这种复用可以在运行时动态进行,新对象可以动态地引用与成分对象类型相同的对象。

汽车按动力源划分可分为汽油汽车、电动汽车;按"颜色"划分为白色汽车、黑色汽车和红色汽车等。如果同时看i哦率这两种分类,其组合就很多。类图如下:

继承复用: 假如新增填一个汽车动力、会牵扯到很多的子类

将继承复用更改为集合复用

相关文章
|
3月前
|
设计模式 监控 安全
多线程设计模式【多线程上下文设计模式、Guarded Suspension 设计模式、 Latch 设计模式】(二)-全面详解(学习总结---从入门到深化)
多线程设计模式【多线程上下文设计模式、Guarded Suspension 设计模式、 Latch 设计模式】(二)-全面详解(学习总结---从入门到深化)
84 0
|
2月前
|
设计模式 存储 算法
设计模式学习心得之五种创建者模式(2)
设计模式学习心得之五种创建者模式(2)
23 2
|
2月前
|
设计模式 uml
设计模式学习心得之前置知识 UML图看法与六大原则(下)
设计模式学习心得之前置知识 UML图看法与六大原则(下)
18 2
|
2月前
|
设计模式 安全 Java
设计模式学习心得之五种创建者模式(1)
设计模式学习心得之五种创建者模式(1)
19 0
|
2月前
|
设计模式 数据可视化 程序员
设计模式学习心得之前置知识 UML图看法与六大原则(上)
设计模式学习心得之前置知识 UML图看法与六大原则(上)
18 0
|
3月前
|
设计模式 安全 Java
【JAVA学习之路 | 基础篇】单例设计模式
【JAVA学习之路 | 基础篇】单例设计模式
|
3月前
|
设计模式 安全 Java
【设计模式学习】单例模式和工厂模式
【设计模式学习】单例模式和工厂模式
|
3月前
|
设计模式 算法 程序员
Python从入门到精通:2.1.3深入学习面向对象编程——设计模式的学习与实践
Python从入门到精通:2.1.3深入学习面向对象编程——设计模式的学习与实践
|
3月前
|
设计模式 存储 前端开发
JS的几种设计模式,Web前端基础三剑客学习知识分享,前端零基础开发
JS的几种设计模式,Web前端基础三剑客学习知识分享,前端零基础开发
|
3月前
|
设计模式 存储 前端开发
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式
Java从入门到精通:2.2.1学习Java Web开发,了解Servlet和JSP技术,掌握MVC设计模式