java----设计模式

1 UML

在这里插入图片描述

1.1 UML定义

◆统一建模语言(英语: Unified Modeling Language,编写UML)
◆非专利的第三代建模和规约语言

1.2 UML特点

◆UML是一种开放的方法
◆用于说明、可视化、构建和编写一个正在开发的面向对象的、软件密集系统的制品的开放方法
◆UML展现了一系列最佳工程实践
这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效

1.3 UML22分类

UML22中一共定义了14种图示,分类如下:
◆结构式图形:强调的是系统式的建模
◆行为式图形:强调系统模型中触发的事件
◆交互式图形:属于行为式图形子集合,强调系统模型中资料流程

1.3.1 结构式图形

◆静态图(类图,对象图,包图)
◆实现图(组件图,部署图)
◆剖面图
◆复合结构图

1.3.2 行为式图形

◆活动图
◆状态图
◆用例图

1.3.3 交互式图形

◆通信图
◆交互概述图(UML20)
◆时序图(UML20)
◆时间图(UML20)

1.4 UML类图

在这里插入图片描述
在这里插入图片描述

Class Diagram:用于表示类、接口、实例等之间相互的静态关系
◆虽然名字叫类图,但类图中并不只有类

1.4.1 记忆技巧

◆UML箭头方向:从子类指向父类
◆提示:可能会认为子类是以父类为基础的,箭头应从父类指向子类

1.4.1.1 记忆技巧箭头方向

◆定义子类时需要通过 extends关键字指定父类
◆子类一定是知道父类定义的,但父类并不知道子类的定义
◆只有知道对方信息时才能指向对方

1.4.1.2 记忆技巧-箭头方向

◆定义子类时需要通过 extends关键字指定父类
◆子类一定是知道父类定义的,但父类并不知道子类的定义
◆只有知道对方信息时才能指向对方
◆所以箭头方向是从子类指向父类在这里插入图片描述

1.4.1.3 记忆技巧-实线-继承虚线-实现

◆空心三角箭头:继承或实现
◆实线-继承,is a关系,扩展目的,不虚,很结实
◆虚线实现,虚线代表”虚”无实体
在这里插入图片描述
在这里插入图片描述

1.4.1.4 记忆技巧-实线关联虚线依赖

◆虚线-依赖关系:临时用一下,若即若离,虚无缥缈,若有若无
◆表示一种使用关系,一个类需要借助另一个类来实现功能
◆一般是一个类使用另一个类做为参数使用,或作为返回值

1.4.1.5 记忆技巧-实线关联虚线依赖

◆实线关联关系:关系稳定,实打实的关系,铁哥们
◆表示一个类对象和另一个类对象有关联
◆通常是一个类中有另一个类对象做为属性

1.4.1.6 记忆技巧-空心萎形聚合实心菱形组合

◆菱形就是一个盛东西的器皿(例如盘子)
◆聚合:代表空器皿里可以放很多相同东西,聚在一起(箭头方向所指的类
◆组合:代表满器皿里已经有实体结构的存在,生死与共

在这里插入图片描述
在这里插入图片描述

1.4.1.7 记忆技巧-空心菱形-聚合

◆整体和局部的关系,两者有着独立的生命周期,是has-a的关系
◆弱关系
◆消极的词:弱空

1.4.1.8 记忆技巧-实心萎形-组合

◆整体与局部的关系,和聚合的关系相比,关系更加强烈
◆两者有相同的生命周期, contains-a的关系
◆强关系
◆积极的词:强-满

1.4.1.9 记忆技巧-实心菱形-组合

◆常见数字表达及含义,假设有A类和B类,数字标记在A类侧
◆0…1: 0或1个实例
◆0…*: 0或多个实例
◆ 1…1: 1个实例
◆1 只能有一个实例
◆1…*: 至少有一个实例

1.4.2 UML时序图

◆ Sequence Diagram:是显示对象之间交互的图,这些对象是按时间
顺序排列的。
◆时序图中包括的建模元素主要有:
对象( Actor)、生命线( Lifeline)、
控制焦点〔 Focus of control)、消息( Message)等

在这里插入图片描述

2 设计原则

在这里插入图片描述

2.1 开闭原则

◆定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭
◆用抽象构建框架,用实现扩展细节
◆优点:提高软件系统的可复用性及可维护性

在这里插入图片描述

代码实现

  • ICourse的接口类和实现类
package com.design.principle.openclose;

public interface ICourse {
    Integer getId();
    String getName();
    Double getPrice();
}

package com.design.principle.openclose;

public class JavaCourse implements ICourse{
    private Integer id;
    private String name;
    private Double price;

    public JavaCourse(Integer id, String name, Double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    @Override
    public Integer getId() {
        return this.id;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public Double getPrice() {
        return this.price;
    }
}

  • 遵循开闭原则,新增子类JavaDiscountCourse
package com.design.principle.openclose;

public class JavaDiscountCourse extends JavaCourse{
    public JavaDiscountCourse(Integer id, String name, Double price) {
        super(id, name, price);
    }

    // 获取原价格
    public Double getOriginPrice() {
        return super.getPrice();
    }
 
    // 获取打折价格
    @Override
    public Double getPrice() {
        return super.getPrice()*0.8;
    }
}

  • 测试类
package com.design.principle.openclose;

public class Test {
    public static void main(String[] args) {
        ICourse iCourse = new JavaDiscountCourse(96,"JAVA",348d);
        JavaDiscountCourse javaCourse = (JavaDiscountCourse) iCourse;
        System.out.println("课程ID:" + javaCourse.getId() + " 课程名称:" + javaCourse.getName() + " 课程原价格:" + javaCourse.getOriginPrice() + " 课程折扣价格:" + javaCourse.getPrice());
    }
}

2.2 依赖倒置原则

◆定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象
◆抽象不应该依赖细节;细节应该依赖抽象
◆针对接口编程,不要针对实现编程
◆优点:可以减少类间的耦合性、提高系统稳定性,提高代码可读性和可维护性,可降低修改程序所造成的风险
在这里插入图片描述

  • 低层模块类----ICourse
package com.design.principle.dependenceinversion;

public interface ICourse {
    void studyCourse();
}

  • ICourse的实现类
package com.design.principle.dependenceinversion;

public class JavaCourse implements ICourse{
    @Override
    public void studyCourse() {
        System.out.println("Geely在学习Java课程");
    }
}

package com.design.principle.dependenceinversion;

public class FECourse implements ICourse{
    @Override
    public void studyCourse() {
        System.out.println("Geely在学习FE课程");
    }
}

  • 不动类----Geely
package com.design.principle.dependenceinversion;

public class Geely {
    public void setiCourse(ICourse iCourse) {
        this.iCourse = iCourse;
    }

    private ICourse iCourse;

    public void learnCourse() {
        iCourse.studyCourse();
    }
}

  • 高层模块类----Test
package com.design.principle.dependenceinversion;

public class Test {
    // version_1
    // public static void main(String[] args) {
    //     Geely geely = new Geely();
    //     geely.studyJavaCourse();
    //     geely.studyFECourse();
    // }

    // version_2
    // public static void main(String[] args) {
    //     Geely geely = new Geely();
    //     geely.learnCourse(new JavaCourse());
    //     geely.learnCourse(new FECourse());
    // }

    // version_3
    // public static void main(String[] args) {
    //     Geely geely = new Geely(new JavaCourse());
    //     geely.learnCourse();
    // }

    // version_4
    public static void main(String[] args) {
        Geely geely = new Geely();
        geely.setiCourse(new JavaCourse());
        geely.learnCourse();

        geely.setiCourse(new FECourse());
        geely.learnCourse();
    }
}

2.3 单一职责原则

◆定义:不要存在多于一个导致类变更的原因
◆一个类/接口/方法只负责一项职责
◆优点:降低类的复杂度、提高类的可读性、提高系统的可维护性、降低变更引起的风险

在这里插入图片描述

2.3.1 类----单一职责原则

package com.design.principle.singleresponsibility;

public class Bird {
    public void mainMoveMMode(String birdName) {
        if ("鸵鸟".equals(birdName)) {
            System.out.println(birdName + "用脚走");
        } else {
            System.out.println(birdName + "用翅膀飞");
        }
    }
}

  • 遵循类的单一职责原则,可能会造成类爆炸
package com.design.principle.singleresponsibility;

public class FlyBird {
    public void mainMoveMode(String birdName) {
        System.out.println(birdName + "用翅膀飞");
    }
}

package com.design.principle.singleresponsibility;

public class WalkBird {
    public void mainMoveMode(String birdName) {
        System.out.println(birdName + "用脚走");
    }
}

2.3.2 接口----单一职责原则(推荐)

package com.design.principle.singleresponsibility;

public interface ICourse {
    String getCourseName();
    byte[] getCourseVideo();

    void studyCourse();
    void refundCourse();
}

  • 遵循接口的单一职责原则
package com.design.principle.singleresponsibility;

public interface ICourseManager {
    void studyCourse();
    void refundCourse();
}

package com.design.principle.singleresponsibility;

public interface ICourseContent {
    String getCourseName();
    byte[] getCourseVideo();
}

2.3.3 方法----单一职责原则(推荐)

package com.design.principle.singleresponsibility;

public class Method {
    private void updateUserInfo(String userName, String address) {
        userName = "geely";
        address = "beijing";
    }

    // ====================方法----单一职责原则============================
    private void updateUserInfo(String userName, String... properties) {
        userName = "geely";
    }

    private void updateUserName(String userName) {
        userName = "geely";
    }

    private void updateUserAddress(String address) {
        address = "beijing";
    }

    private void updateUserInfo(String userName, String address, boolean bool) {
        if (bool) {
            // todo something1
        } else {
            // todo something2
        }
        userName = "geely";
        address = "beijing";
    }
}

2.4 接口隔离原则

◆定义:用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接囗
◆一个类对一个类的依赖应该建立在最小的接口上
◆建立单一接口,不要建立庞大臃肿的接口
◆尽量细化接口,接口中的方法尽量少
◆注意适度原则,一定要适度
◆优点:符合我们常说的高内聚低耦合的设计思想,从而使得类昊有很好的可读性、可扩展性和可维护性。

注: 高内聚:减少对外的交互;接口最少的方法,完成最多的实现
在这里插入图片描述

package com.design.principle.interfacesegregation;

public interface IAnimalAction {
    void eat();
    void fly();
    void swim();
}

package com.design.principle.interfacesegregation;

public class Bird implements IAnimalAction{
    @Override
    public void eat() {

    }

    @Override
    public void fly() {

    }

    @Override
    public void swim() {

    }
}


package com.design.principle.interfacesegregation;

public interface ISwimAnimalAction {
    void swim();
}

package com.design.principle.interfacesegregation;

public interface IEatAnimalAction {
    void eat();
}

package com.design.principle.interfacesegregation;

public interface IFlyAnimalAction {
    void fly();
}

package com.design.principle.interfacesegregation;

public class Dog implements ISwimAnimalAction,IEatAnimalAction{
    @Override
    public void eat() {

    }

    @Override
    public void swim() {

    }
}

2.5 迪米特原则

◆定义:一个对象应该对其他对象保持最少的了解。又叫最少知道原则
◆尽量降低类与类之间的耦合
优点: 降低类之间的耦合
◆强调只和朋友交流,不和陌生人说话
◆朋友: 出现在成员变量、方法的输入、输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类。
在这里插入图片描述

package com.design.principle.demeter;

import java.util.ArrayList;
import java.util.List;

public class Boss {
    public void commandCheckNumber(TeamLeader teamLeader) {
        List<Course> courseList = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            courseList.add(new Course());
        }
        teamLeader.checkNumberOfCourse(courseList);
    }
}

package com.design.principle.demeter;

import java.util.List;

public class TeamLeader {
    public void checkNumberOfCourse(List<Course> courseList) {
        System.out.println("在线课程的数量是:" + courseList.size());
    }
}

package com.design.principle.demeter;

public class Course {
}

package com.design.principle.demeter;

public class Test {
    public static void main(String[] args) {
        Boss boss = new Boss();
        TeamLeader teamLeader = new TeamLeader();
        boss.commandCheckNumber(teamLeader);
    }
}


在这里插入图片描述

package com.design.principle.demeter;

public class Boss {
    public void commandCheckNumber(TeamLeader teamLeader) {
        teamLeader.checkNumberOfCourse();
    }
}

package com.design.principle.demeter;

import java.util.ArrayList;
import java.util.List;

public class TeamLeader {
    public void checkNumberOfCourse() {
        List<Course> courseList = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            courseList.add(new Course());
        }
        System.out.println("在线课程的数量是:" + courseList.size());
    }
}

package com.design.principle.demeter;

public class Course {
}

package com.design.principle.demeter;

public class Test {
    public static void main(String[] args) {
        Boss boss = new Boss();
        TeamLeader teamLeader = new TeamLeader();
        boss.commandCheckNumber(teamLeader);
    }
}

2.6 里氏替换原则

◆定义
如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都替换成o2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型。
◆定义扩展
一个软件实体如果适用一个父类的话那一定适用于其子类,所有引用父类的地方必须能透明地使用其子类的对象,子类对象能够替换父类对象,而程序逻辑不变。

◆引申意义:子类可以扩展父类的功能,但不能改变父类原有的功能。
◆含义1:子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
◆含义2:子类中可以增加自己特有的方法。
◆含义3:当子类的方法重载父类的方法时,方法的前置条件
(即方法的输入/入参)要比父类方法的输入参数更宽松
◆含义4:当子类的方法实现父类的方法时重写/重载或实现抽象方法),
方法的后置条件(即方法的输出/返回值)要比父类更严格或相等

◆优点1:约束继承泛滥,开闭原则的一种体现
◆优点2:加强程序的健壮性,同时变更时也可以做到非常好的兼容性
提高程序的维护性、扩展性。降低需求变更时引入的风险

2.7 合成(组合)/聚合复用原则----黑箱复用

◆定义:尽量使用对象组合/聚合,而不是继承关系达到软件复用的目的
◆聚合has-A和组合 contains-A
◆聚合has-A、组合contains-A 继承is-A 继承:白箱复用
◆优点:可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少
在这里插入图片描述

public abstract class DBConnection {
    public abstract String getConnection();
}
package com.design.compositionaggregation;

public class MySQLConnection extends DBConnection{

    @Override
    public String getConnection() {
        return "MySQl数据库连接";
    }
}

package com.design.compositionaggregation;

public class PostgreSQLConnection extends DBConnection{

    @Override
    public String getConnection() {
        return "PostgreSQLConnection数据库连接";
    }
}

package com.design.compositionaggregation;

public class ProductDao {
    private DBConnection dbConnection;

    public void setDbConnection(DBConnection dbConnection) {
        this.dbConnection = dbConnection;
    }

    public void addProduct() {
        String conn = dbConnection.getConnection();
        System.out.println("使用" + conn + "增加产品");
    }
}

package com.design.compositionaggregation;

public class Test {
    public static void main(String[] args) {
        ProductDao productDao = new ProductDao();
        productDao.setDbConnection(new PostgreSQLConnection());
        productDao.addProduct();
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值