设计原理上

Java设计模式

1 前言

1.1 目的

image-20230412224011189

2 七大原则

image-20230412223344569

2.1 单一职责原则

image-20230412224454356

方案一

package com.feng.principle.singleresponsibility;

/**
 * @Author feng peng
 * @Date 2023/4/12
 * @Time 22:53
 */
public class singleResponsibility01 {
    public static void main(String[] args) {
        Vehicle vehicle = new Vehicle();
        vehicle.run("摩托车");
        vehicle.run("汽车");
        vehicle.run("飞机");

    }
}
// 交通工具类
// 方式1
// 1.在方式1 的run方法中,违反了单一职责原则
// 2.解决的方案非常的简单,根据交通工具运行的方法不同,分解成不同类即可
class Vehicle{
    public void run(String vehicle){
        System.out.println(vehicle + " 在公路上运行...");
    }
}

方案二

package com.feng.principle.singleresponsibility;

/**
 * @Author feng peng
 * @Date 2023/4/12
 * @Time 22:53
 */
public class singleResponsibility02 {
    public static void main(String[] args) {
        RoadVehicle roadVehicle = new RoadVehicle();
        roadVehicle.run("摩托车");
        roadVehicle.run("汽车");

        AirVehicle airVehicle = new AirVehicle();
        airVehicle.run("飞机");

    }
}

//方案2的分析
//1.遵守单一职责原则
//2.但是这样做的改动很大,即将类分解,同时修改客户端
//3.改进:直接修改Vehicle 类,改动的代码会比较少 => 方案3
class RoadVehicle{
    public void run(String vehicle){
        System.out.println(vehicle + " 在公路上运行...");
    }
}

class AirVehicle{
    public void run(String vehicle){
        System.out.println(vehicle + " 在空中运行...");
    }
}

class WaterVehicle{
    public void run(String vehicle){
        System.out.println(vehicle + " 在水中运行...");
    }
}

方案三

package com.feng.principle.singleresponsibility;

/**
 * @Author feng peng
 * @Date 2023/4/12
 * @Time 22:53
 */
public class singleResponsibility03 {
    public static void main(String[] args) {
        Vehicle2 vehicle2 = new Vehicle2();
        vehicle2.run("摩托车");
        vehicle2.runWater("轮船");
        vehicle2.runAir("飞机");

    }
}

// 方式3的分析
// 1.这种修改方法没有对原来的类做大的修改,只是增加方法
// 2.这里虽然没有在类这个级别上遵守单一职责原则,但是在方法级别上,仍然是遵守单一职责
class Vehicle2{
    public void run(String vehicle){
        System.out.println(vehicle + " 在公路上运行...");
    }

    public void runAir(String vehicle){
        System.out.println(vehicle + " 在天空运行...");
    }

    public void runWater(String vehicle){
        System.out.println(vehicle + " 在水中运行...");
    }
}

image-20230412232342870

2.2 接口隔离原则

image-20230423212548446

image-20230423212639923

package com.feng.principle.segregation;

/**
 * @Author feng peng
 * @Date 2023/4/23
 * @Time 21:28
 */
public class Segregation01 {
    public static void main(String[] args) {

    }
}

interface Interface1{
    void operation1();
    void operation2();
    void operation3();
    void operation4();
    void operation5();
}

class B implements Interface1{

    @Override
    public void operation1() {
        System.out.println("B 实现了 operation1");
    }

    @Override
    public void operation2() {
        System.out.println("B 实现了 operation2");
    }

    @Override
    public void operation3() {
        System.out.println("B 实现了 operation3");
    }

    @Override
    public void operation4() {
        System.out.println("B 实现了 operation4");
    }

    @Override
    public void operation5() {
        System.out.println("B 实现了 operation5");
    }
}

class D implements Interface1{

    @Override
    public void operation1() {
        System.out.println("D 实现了 operation1");
    }

    @Override
    public void operation2() {
        System.out.println("D 实现了 operation2");
    }

    @Override
    public void operation3() {
        System.out.println("D 实现了 operation3");
    }

    @Override
    public void operation4() {
        System.out.println("D 实现了 operation4");
    }

    @Override
    public void operation5() {
        System.out.println("D 实现了 operation5");
    }
}

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

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


image-20230423220726185

image-20230423224315694

package com.feng.principle.segregation.improve;

/**
 * @Author feng peng
 * @Date 2023/4/23
 * @Time 21:28
 */
public class Segregation02 {
    public static void main(String[] args) {
        // 使用一把
        A a = new A();
        a.depend1(new B()); //A类通过接口去依赖B类
        a.depend2(new B());
        a.depend3(new B());

        C c = new C();
        c.depend1(new D()); // C类通过接口去依赖(使用)D类
        c.depend4(new D());
        c.depend5(new D());
    }
}

interface Interface1{
    void operation1();
}
//接口2
interface Interface2{
    void operation2();
    void operation3();
}
//接口3
interface Interface3{
    void operation4();
    void operation5();
}

class B implements Interface1,Interface2{

    @Override
    public void operation1() {
        System.out.println("B 实现了 operation1");
    }

    @Override
    public void operation2() {
        System.out.println("B 实现了 operation2");
    }

    @Override
    public void operation3() {
        System.out.println("B 实现了 operation3");
    }

}

class D implements Interface1,Interface3{

    @Override
    public void operation1() {
        System.out.println("D 实现了 operation1");
    }

    @Override
    public void operation4() {
        System.out.println("D 实现了 operation4");
    }

    @Override
    public void operation5() {
        System.out.println("D 实现了 operation5");
    }
}

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

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

运行结果

image-20230423224605641

2.3 依赖倒转原则

image-20230504201534867

image-20230504201641820

实现方案1代码

package com.feng.principle.inversion;

public class DependecyInversion {
    public static void main(String[] args) {
        Persion persion = new Persion();
        persion.receive(new Email());
    }
}

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

//完成Person接收消息的功能
//方式1分析
// 1.简单,比较容易想到
// 2.如果我们获取的对象是 微信,短信等等,则新增类,同时Person也要增加相应的接收方法
// 3.解决思路:引入一个抽象的接口IReceiver, 表示接收者,这样Person类与接口IReceiver发生依赖
// 因为Email,WeChat 等等属于接收的范围,他们各自实现IReceiver 接口就OK,这样我们就符合依赖倒转原则
class Persion{
    public void receive(Email email){
        System.out.println(email.getInfo());
    }
}

实现方案2改进代码

package com.feng.principle.inversion.improve;

public class DependecyInversion {
    public static void main(String[] args) {
        //客户端无需改变
        Persion persion = new Persion();
        persion.receive(new Email());
        persion.receive(new WeChat());
    }
}

//定义接口
interface IReceiver{
    public String getInfo();
}
class Email implements IReceiver{
    public String getInfo(){
        return "电子邮件信息:hello,world";
    }
}

//增加微信
class WeChat implements IReceiver{

    @Override
    public String getInfo() {
        return "微信消息:hello,ok";
    }
}

//方式2
class Persion{
    //这里我们是对接口的依赖
    public void receive(IReceiver receiver){
        System.out.println(receiver.getInfo());
    }
}

运行结果

image-20230504210812210

image-20230504215736211

代码实现

package com.feng.principle.inversion.improve;

public class ThreeMethod {

}

// 方式1:通过接口传递实现依赖
// 开关的接口
 interface IOpenAndClose{
    public void open(ITV tv); //抽象方法,接收接口
}

interface ITV{ //ITV接口
    public void play();
}

//实现接口
class OpenAndClose implements IOpenAndClose{
    @Override
    public void open(ITV tv) {
        tv.play();
    }
}

//方式2:通过构造方法依赖传递
interface IOpenAndClose{
    public void open();//抽象方法
}
interface ITV{ //ITV接口
    public void play();
}
class OpenAndClose implements IOpenAndClose{
    public ITV tv;
    public OpenAndClose(ITV tv){ //构造器
        this.tv = tv;
    }

    public void open(){
        this.tv.play();
    }
}

//方法3: 通过setter方法传递
interface IOpenAndClose{
    public void open(); //抽象方法
    public void setTv(ITV tv);
}

interface ITV{ //ITV接口
    public void play();
}

class OpenAndClose implements IOpenAndClose{
    private ITV tv;

    @Override
    public void setTv(ITV tv) {
        this.tv = tv;
    }

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

image-20230504220321779

2.4 里氏替换原则

image-20230504220947595

image-20230504221420875

image-20230505215103048

完整代码

package com.feng.principle.liskov;

public class Liskov {
    public static void main(String[] args) {
        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 = new B();
        System.out.println("11 -3="+ b.func1(11,3)); //这里本意是求出11-3
        System.out.println("1-8="+ b.func1(1,8)); // 1-8
        System.out.println("11+3+9="+ b.func2(11,3));
    }
}

// A类
class A{
    // 返回两个数的差
    public int func1(int num1,int num2){
        return num1 - num2;
    }
}

// B类继承了A
// 增加了一个新功能:完成两个数相加,然后和9求和
class B extends A {
    //这里,重写了A类的方法,可能是无意识
    public int func1(int a,int b){
        return a+b;
    }

    public int func2(int a,int b){
        return func1(a,b)+9;
    }
}

运行结果

image-20230505215200467

image-20230505215337643

改进方案

image-20230509211000738

改进代码

package com.feng.principle.liskov.improve;

public class Liskov {
    public static void main(String[] args) {
        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 = new B();
        //因为B类不再继承A类,因此调用者,不会再func1是求减法
        //调用完成的功能就会很明确
        System.out.println("11+3="+ b.func1(11,3)); //这里本意是求出11+3
        System.out.println("1+8="+ b.func1(1,8)); // 1+8
        System.out.println("11+3+9="+ b.func2(11,3));

        //使用组合仍然可以使用到A类相关方法
        System.out.println("11-3="+b.func3(11,3));//这里本意是求出11-3
    }
}

// A类
class A{
    // 返回两个数的差
    public int func1(int num1,int num2){
        return num1 - num2;
    }
}

// B类继承了A
// 增加了一个新功能:完成两个数相加,然后和9求和
class B extends A {
    //如果B需要使用A类的方法,使用组合关系
    private A a = new A();
    //这里,重写了A类的方法,可能是无意识
    public int func1(int a,int b){
        return a+b;
    }

    public int func2(int a,int b){
        return func1(a,b)+9;
    }

    //我们仍然想使用A的方法
    public int func3(int a,int b){
        return  this.a.func1(a,b);
    }
}

运行结果

image-20230509211105686

2.5 开闭原则

image-20230509211630578

案例一

package com.feng.principle.ocp;

public class Ocp {
    public static void main(String[] args) {
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
    }
}

//这是一个用于绘图的类
class GraphicEditor{
    //接收Shape对象,然后根据type,来绘制不同的图形
    public void drawShape(Shape s){
        if(s.m_type == 1){
            drawRectangle(s);
        }else if(s.m_type == 2){
            drawCircle(s);
        }
    }

    public void drawRectangle(Shape r){
        System.out.println("绘制矩形");
    }

    public void drawCircle(Shape r){
        System.out.println("绘制圆形");
    }
}

//Shape类,基类
class Shape{
    int m_type;
}

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

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

运行结果

image-20230509213606243

image-20230509214147515

完整代码

package com.feng.principle.ocp;

public class Ocp {
    public static void main(String[] args) {
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
        graphicEditor.drawShape(new Triangle());
    }
}

//这是一个用于绘图的类
class GraphicEditor{
    //接收Shape对象,然后根据type,来绘制不同的图形
    public void drawShape(Shape s){
        if(s.m_type == 1){
            drawRectangle(s);
        }else if(s.m_type == 2){
            drawCircle(s);
        }else if(s.m_type == 3){
            drawTriangle(s);
        }
    }

    public void drawRectangle(Shape r){
        System.out.println("绘制矩形");
    }

    public void drawCircle(Shape r){
        System.out.println("绘制圆形");
    }

    public void drawTriangle(Shape r){
        System.out.println("绘制三角形");
    }
}

//Shape类,基类
class Shape{
    int m_type;
}

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

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

//新增画三角形
class Triangle extends Shape{
    Triangle(){
        super.m_type = 3;
    }
}

image-20230509214452483

image-20230509215521411

完整代码

package com.feng.principle.ocp.imporve;

public class Ocp {
    public static void main(String[] args) {
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
        graphicEditor.drawShape(new Triangle());
        graphicEditor.drawShape(new OtherGraphic());
    }
}

//这是一个用于绘图的类[使用方]
class GraphicEditor{
    //接收Shape对象,调用draw方法
    public void drawShape(Shape s){
        s.draw();
    }
}

//Shape类,基类
abstract class Shape{
    int m_type;

    public abstract void draw();//抽象方法
}

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

    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}

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

    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

//新增画三角形
class Triangle extends Shape{
    Triangle(){
        super.m_type = 3;
    }

    @Override
    public void draw() {
        System.out.println("绘制三角形");
    }
}

//新增一个图形
class OtherGraphic extends Shape{
    OtherGraphic(){
        super.m_type = 4;
    }
    @Override
    public void draw() {
        System.out.println("绘制其他图形");
    }
}

2.6 迪米特法则

image-20230509221901813

image-20230509221954739

案例代码

package com.feng.principle.demeter;

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

//客户端
public class Demeter01 {
    public static void main(String[] args) {
        //创建了一个SchoolManager对象
        SchoolManager schoolManager = new SchoolManager();
        //输出学院的员工id 和 学校总部的员工信息
        schoolManager.printAllEmployee(new CollegeManager());
    }
}

//学校总部员工类
class Employee{
    private String id;

    public void setId(String id){
        this.id = id;
    }

    public String getId(){
        return id;
    }
}

//学院的员工类
class CollegeEmployee{
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

//管理学院员工的管理类
class CollegeManager{
    public List<CollegeEmployee> getAllEmployee(){
        //返回学院的所有员工
        List<CollegeEmployee> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {//这里我们增加了10个员工到list
            CollegeEmployee emp = new CollegeEmployee();
            emp.setId("学院员工id = " + i);
            list.add(emp);
        }
        return list;
    }
}

//学校管理类

//分析SchoolManager 类的直接朋友类(成员变量,传入参数,返回值 3个位置)有哪些  Employee CollegeManager
//CollegeEmployee 不是直接朋友 而是一个陌生类,这样违背了迪米特法则


class SchoolManager{
    //返回学校总部的员工
    public List<Employee> getAllEmployee(){
        List<Employee> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Employee emp = new Employee();
            emp.setId("学院总部员工id= "+ i);
            list.add(emp);
        }
        return list;
    }

    //该方法完成输出学校总部和学院员工信息(id)
    void printAllEmployee(CollegeManager sub){

        //分析问题
        //1. 这里的CollegeEmployee 不是 SchoolManager的直接朋友
        //2. CollegeEmployee 是以局部变量方式出现在 SchoolManager
        //3. 违反了迪米特法则


        //获取到学院员工
        List<CollegeEmployee> list1 = sub.getAllEmployee();
        System.out.println("---------------学院员工--------------");
        list1.forEach(e ->{
            System.out.println(e.getId());
        });
        //获取到学校总部员工
        List<Employee> list2 = this.getAllEmployee();
        System.out.println("-------------学校总部员工---------------");
        list2.forEach(e -> System.out.println(e.getId()));
    }
}

运行结果

image-20230509225843972

image-20230509225905994

改进完整代码

package com.feng.principle.demeter.improve;

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

//客户端
public class Demeter01 {
    public static void main(String[] args) {
        System.out.println("===使用迪米特法则的改进====");
        //创建了一个SchoolManager对象
        SchoolManager schoolManager = new SchoolManager();
        //输出学院的员工id 和 学校总部的员工信息
        schoolManager.printAllEmployee(new CollegeManager());
    }
}

//学校总部员工类
class Employee{
    private String id;

    public void setId(String id){
        this.id = id;
    }

    public String getId(){
        return id;
    }
}

//学院的员工类
class CollegeEmployee{
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

//管理学院员工的管理类
class CollegeManager{
    public List<CollegeEmployee> getAllEmployee(){
        //返回学院的所有员工
        List<CollegeEmployee> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {//这里我们增加了10个员工到list
            CollegeEmployee emp = new CollegeEmployee();
            emp.setId("学院员工id = " + i);
            list.add(emp);
        }
        return list;
    }

    //输出学院员工的信息
    public void printEmployee(){
        //获取到学院员工
        List<CollegeEmployee> list1 = getAllEmployee();
        System.out.println("---------------学院员工--------------");
        list1.forEach(e ->{
            System.out.println(e.getId());
        });
    }

}

//学校管理类

//分析SchoolManager 类的直接朋友类(成员变量,传入参数,返回值 3个位置)有哪些  Employee CollegeManager
//CollegeEmployee 不是直接朋友 而是一个陌生类,这样违背了迪米特法则


class SchoolManager{
    //返回学校总部的员工
    public List<Employee> getAllEmployee(){
        List<Employee> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Employee emp = new Employee();
            emp.setId("学院总部员工id= "+ i);
            list.add(emp);
        }
        return list;
    }

    //该方法完成输出学校总部和学院员工信息(id)
    void printAllEmployee(CollegeManager sub){

        //分析问题
        //1. 将输出学院的员工方法,封装到CollegeManager
        sub.printEmployee();

        //获取到学校总部员工
        List<Employee> list2 = this.getAllEmployee();
        System.out.println("-------------学校总部员工---------------");
        list2.forEach(e -> System.out.println(e.getId()));
    }
}

运行结果

image-20230509230958955

image-20230509231126676

2.7 合成复用原则

image-20230528225123064

image-20230528225039152

image-20230528225258591

3 UML类图

3.1 基本介绍

image-20230528225559719

image-20230528225956455

image-20230529213425893

3.2 类图

image-20230529213533768

image-20230529214606088

3.3 依赖

image-20230529221532304

image-20230529221640263

3.4 泛化

image-20230529222850299

image-20230529222801904

3.5 实现

image-20230529223502572

image-20230529223433191

3.6 关联

image-20230529223729669

3.7 聚合

image-20230529224832601

image-20230529224720096

3.8 组合

image-20230529225201136

image-20230529225636544

创建了一个人对象,那么头对象也随之创建好了,所以两者不能分开,所以是组合关系。

image-20230529225447293

4 设计模式

4.1 概述

image-20230529233612354

p28

5 代理模式

5.1 定义

image-20230604105756802

image-20230604105934432

5.2 静态代理

定义

image-20230604112002598

image-20230604110602220

代码实现

image-20230604112046272

ITeacherDao接口

package com.feng.proxy.staticproxy;

// 接口
public interface ITeacherDao {
    void teach();// 授课的方法
}

TeacherDao

package com.feng.proxy.staticproxy;

public class TeacherDao implements ITeacherDao{
    @Override
    public void teach() {
        System.out.println("老师授课中。。。。");
    }
}

TeacherDaoProxy

package com.feng.proxy.staticproxy;

//代理对象,静态代理
public class TeacherDaoProxy implements ITeacherDao{
    private  ITeacherDao target; // 目标对象,通过接口来聚合

    // 构造器
    public TeacherDaoProxy(ITeacherDao target) {
        this.target = target;
    }

    @Override
    public void teach() {
        System.out.println("开始代理。。。。");
        target.teach();
        System.out.println("提交。。。。。");

    }
}

Client

package com.feng.proxy.staticproxy;

public class Client {
    public static void main(String[] args) {
        //创建目标对象(被代理的对象)
        TeacherDao teacherDao = new TeacherDao();

        //创建代理对象,同时将被代理对象传递给代理对象
        TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);

        //通过代理对象,调用到被代理对象的方法
        //即:执行的是代理对象的方法,代理对象再去调用目标对象的方法
        teacherDaoProxy.teach();
    }
}

运行结果

image-20230604112234259

image-20230604112434247

5.3 动态代理

定义

image-20230604112701126

image-20230604112736250

image-20230604113122636

代码实现

image-20230604143530822

ITeacherDao接口

package com.feng.proxy.dynamic;

//接口
public interface ITeacherDao {
    void teach(); // 授课方法
}

TeacherDao

package com.feng.proxy.dynamic;

public class TeacherDao implements ITeacherDao{
    @Override
    public void teach() {
        System.out.println("老师授课中。。。。");
    }
}

ProxyFactory

package com.feng.proxy.dynamic;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {
    //维护一个目标对象,Object
    private Object target;

    //构造器,对target 进行初始化
    public ProxyFactory(Object target) {
        this.target = target;
    }

    //给目标对象 生成一个代理对象
    public Object getProxyInstance(){

        /***   说明
         *
         *     public static Object newProxyInstance(ClassLoader loader,
         *                                           Class<?>[] interfaces,
         *                                           InvocationHandler h)
         *
         *  1. ClassLoader loader : 指定当前目标对象使用的类加载器,获取加载器的方法固定
         *  2. Class<?>[] interfaces: 目标对象实现的接口类型,使用泛型方法确认类型
         *  3. InvocationHandler h : 事件处理,执行目标对象的方法时,会触发事件处理器方法,
         *                               会把当前执行的目标对象方法作为参数传入
         */
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("JDK代理开始~~");
                // 反射机制调用目标对象的方法
                Object returnVal = method.invoke(target, args);
                System.out.println("JDK代理提交~~");
                return returnVal;
            }
        });
    }
}

Client

package com.feng.proxy.dynamic;

public class Client {
    public static void main(String[] args) {
        //创建目标对象
        ITeacherDao target = new TeacherDao();

        //给目标对象,创建代理对象,可以转成ITeacherDao
        ITeacherDao proxyInstance = (ITeacherDao) new ProxyFactory(target).getProxyInstance();

        //结果:proxyInstance=class com.sun.proxy.$Proxy0 内存中动态生成了代理对象
        System.out.println("proxyInstance=" + proxyInstance.getClass());

        // 通过代理对象,调用目标对象的方法
        proxyInstance.teach();
    }
}

运行结果

image-20230604143753182

5.4 Cglib代理

定义

image-20230604144513237

image-20230604144636738

image-20230604144711417

image-20230604145149367

代码实现

image-20230604152148163

TeacherDao

package com.feng.proxy.cglib;

public class TeacherDao {
    public void teach(){
        System.out.println("老师授课中,我是cglib代理,不需要实现接口");
    }
}

ProxyFactory

package com.feng.proxy.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class ProxyFactory implements MethodInterceptor {

    // 维护一个目标对象
    private Object target;

    // 构造器,传入一个被代理的对象

    public ProxyFactory(Object target) {
        this.target = target;
    }

    // 返回一个代理对象:是 target 对象的代理对象
    public Object getProxyInstance(){
        // 1.创建一个工具类
        Enhancer enhancer = new Enhancer();
        // 2.设置父类
        enhancer.setSuperclass(target.getClass());
        // 3.设置回调函数
        enhancer.setCallback(this);
        // 4. 创建子类对象,即代理对象
        return enhancer.create();
    }

    // 重写 intercept 方法,会调用目标对象的方法
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("Cglib代理模式 开始~");
        Object returnVal = method.invoke(target, args);
        System.out.println("Cglib代理模式 提交~");
        return returnVal;
    }
}

Client

package com.feng.proxy.cglib;

public class Client {
    public static void main(String[] args) {
        //创建目标对象
        TeacherDao target = new TeacherDao();

        //获取到代理对象,并且将目标对象传递给代理对象
        TeacherDao proxyInstance = (TeacherDao) new ProxyFactory(target).getProxyInstance();

        //执行代理对象的方法,触发intecept 方法,从而实现对目标对象的调用
        proxyInstance.teach();
    }
}

运行结果

image-20230604152328082

5.5 变体

image-20230604152637617

6 单例模式

image-20231014214303575

image-20231014214337484

6.1 饿汉式静态变量

image-20231014214439673

public class SingletonTest01 {
    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); //true
    }

}

//饿汉式(静态变量)
class  Singleton{
    //1、构造器私有化,外部不能new
    private Singleton(){

    }

    //2.本类内部创建对象实例
    private final static  Singleton instance = new Singleton();

    //3.提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance(){
        return instance;
    }

}

image-20231014215951263

6.2 饿汉式静态代码块

image-20231014220313369

public class SingletonTest02 {
    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); //true
    }

}

//饿汉式(静态变量)
class  Singleton{
    //1、构造器私有化,外部不能new
    private Singleton(){

    }

    //2.本类内部创建对象实例
    private static  Singleton instance;

    static { //在静态代码块中,创建单例对象
        instance = new Singleton();
    }

    //3.提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance(){
        return instance;
    }

}

image-20231014220801468

6.3 懒汉式(线程不安全)

image-20231014221014679

public class SingleTest03 {
    public static void main(String[] args) {
        System.out.println("懒汉式,线程不安全~");
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); //true
    }
}

class Singleton{
    private static Singleton instance;

    public Singleton() {
    }

    //提供一个静态的公有方法,当使用到该方法时,才去创建instance
    //即懒汉式
    public static Singleton getInstance(){
        if (Objects.isNull(instance)){
            instance = new Singleton();
        }
        return instance;
    }

}

image-20231014221824471

6.4 懒汉式(线程安全,同步方法)

image-20231014222040823

public class SingleTest04 {
    public static void main(String[] args) {
        System.out.println("懒汉式2,线程安全~");
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); //true
    }
}

//懒汉式(线程安全,同步方法)
class Singleton{
    private static Singleton instance;

    public Singleton() {
    }

    //提供一个静态的公有方法,加入同步处理的代码,解决线程安全问题
    //即懒汉式
    public static synchronized Singleton getInstance(){
        if (Objects.isNull(instance)){
            instance = new Singleton();
        }
        return instance;
    }

}

image-20231014222608843

6.5 懒汉式(线程安全,同步代码块)

image-20231014222854826

image-20231014223023028

6.6 双重检查

image-20231014223213129

public class SingletonTest06 {
    public static void main(String[] args) {
        System.out.println("双重检查");
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); //true
    }
}

//懒汉式(线程安全,同步方法)
class Singleton{
    private static volatile Singleton instance; //volatile : 变量值一有修改,立即刷到主存中去

    public Singleton() {
    }

    //提供一个静态的公有方法,加入双重检查代码,解决线程安全问题,同时解决懒加载问题
    //同时保证了效率,推荐使用
    public static Singleton getInstance(){
        if (Objects.isNull(instance)){
            synchronized (Singleton.class){
                if(Objects.isNull(instance)){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

}

image-20231014224504167

6.7 静态内部类

image-20231014224623327

外部类装载,静态内部类不会立即被装载,外部类调用getInstance()时,静态内部类被装载,且只装载一次,且装载时线程安全

public class SingletonTest07 {
    public static void main(String[] args) {
        System.out.println("使用静态内部类完成单例模式");
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); //true
    }
}

//静态内部类完成,推荐使用
class Singleton{

    //构造器私有化
    public Singleton() {
    }

    //写一个静态内部类,该类中有一个静态属性 Singleton
    private static class SingletonInstance{
        private static final Singleton INSTANCE = new Singleton();
    }
    //提供一个静态的公有方法,直接返回SingletonInstance.INSTANCE
    public static Singleton getInstance(){
        return SingletonInstance.INSTANCE;
    }

}

image-20231014230516095

6.8 枚举

image-20231014230803630

public class SingletonTest08 {
    public static void main(String[] args) {
        Singleton instance = Singleton.INSTANCE;
        Singleton instance2 = Singleton.INSTANCE;
        System.out.println(instance == instance2);

        instance.sayOK();
    }
}

//使用枚举,可以实现单例,推荐
enum Singleton {
    INSTANCE;//属性
    public void sayOK(){
        System.out.println("ok~");
    }
}

image-20231014231328704

6.9 总结

image-20231014231730241

在JDK中RunTime类使用了饿汉式

7 工厂设计模式

7.1 简单工厂模式

image-20231015095036990

image-20231015095121914

传统方式

image-20231015103359560

image-20231015103329920

Pizza

//将Pizza 类做成抽象
public abstract class Pizza {
    protected String name;

    //准备原材料,不同的披萨不一样,因此,我们做成抽象方法
    public abstract void prepare();

    public void bake(){
        System.out.println(name + "  baking");
    }

    public void cut(){
        System.out.println(name + "  cutting");
    }

    public void box(){
        System.out.println(name + "  boxing");
    }

    public void setName(String name){
        this.name = name;
    }

}

GreekPizza

public class GreekPizza extends Pizza{
    @Override
    public void prepare() {
        System.out.println("给制作希腊披萨 准备原材料");
    }
}

CheesePizza

public class CheesePizza extends Pizza{
    @Override
    public void prepare() {
        System.out.println("给制作奶酪披萨 准备原材料");
    }
}

OrderPizza

public class OrderPizza {

    public OrderPizza() {
        Pizza pizza = null;
        String orderType; //订购披萨的类型
        do{
            orderType = getType();
            if(orderType.equals("greek")){
                pizza = new GreekPizza();
                pizza.setName("希腊披萨");
            }else if (orderType.equals("cheese")){
                pizza = new CheesePizza();
                pizza.setName("奶酪披萨");
            }else {
                break;
            }

            //输出pizza制作过程
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }while (true);
    }

    //写一个方法,可以获取客户希望订购的披萨种类
    private String getType(){
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type: ");
            String str = null;
            str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }

    }
}

PizzaStore

//相当于一个客户端,发出订购
public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza();
    }
}

运行结果

image-20231015103620945

image-20231015103719498

image-20231015104317710

image-20231015104503706

image-20231015120620604

image-20231015120240492

PepperPizza

public class PepperPizza extends Pizza{

    @Override
    public void prepare() {
        System.out.println("给胡椒披萨准备原材料");
    }
}

SimpleFactory

//简单工厂类
public class SimpleFactory {

    //根据orderType  返回对应的Pizza 对象
    public Pizza createPizza(String orderType){
        Pizza pizza = null;

        System.out.println("使用简单工厂模式");
        if(orderType.equals("greek")){
            pizza = new GreekPizza();
            pizza.setName("希腊披萨");
        }else if (orderType.equals("cheese")){
            pizza = new CheesePizza();
            pizza.setName("奶酪披萨");
        }else if (orderType.equals("pepper")){
            pizza = new PepperPizza();
            pizza.setName("胡椒披萨");
        }

        return pizza;
    }
}

OrderPizza

public class OrderPizza {

    //定义一个简单工厂对象
    SimpleFactory simpleFactory;
    Pizza pizza = null;

    //构造器
    public OrderPizza(SimpleFactory simpleFactory){
        setFactory(simpleFactory);
    }

    public void setFactory(SimpleFactory simpleFactory){
        String orderType = "";//用户输入的

        this.simpleFactory = simpleFactory; //设置简单工厂对象
        do {
            orderType = getType();
            pizza = this.simpleFactory.createPizza(orderType);

            //输出pizza
            if(Objects.nonNull(pizza)){ //订购成功
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }else {
                System.out.println("订购披萨失败");
                break;
            }
        }while (true);
    }


    //写一个方法,可以获取客户希望订购的披萨种类
    private String getType(){
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type: ");
            String str = null;
            str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }

    }
}

PizzaStore

//相当于一个客户端,发出订购
public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza(new SimpleFactory());
        System.out.println("退出程序~~");
    }
}

运行结果

image-20231015120558257

7.2 工厂方法模式

image-20231015145446605

image-20231015145518202

image-20231015145648418

image-20231015160512991

image-20231015160532879

Pizza

//将Pizza 类做成抽象
public abstract class Pizza {
    protected String name;

    //准备原材料,不同的披萨不一样,因此,我们做成抽象方法
    public abstract void prepare();

    public void bake(){
        System.out.println(name + "  baking");
    }

    public void cut(){
        System.out.println(name + "  cutting");
    }

    public void box(){
        System.out.println(name + "  boxing");
    }

    public void setName(String name){
        this.name = name;
    }

}

BJCheesePizza

public class BJCheesePizza extends Pizza{
    @Override
    public void prepare() {
        setName("北京的奶酪Pizza");
        System.out.println(" 北京的奶酪Pizza 准备原材料");
    }
}

BJPepperPizza

public class BJPepperPizza extends Pizza{
    @Override
    public void prepare() {
        setName("北京的胡椒Pizza");
        System.out.println(" 北京的胡椒Pizza 准备原材料");
    }
}

LDCheesePizza

public class LDCheesePizza extends Pizza{
    @Override
    public void prepare() {
        setName("伦敦的奶酪Pizza");
        System.out.println(" 伦敦的奶酪Pizza 准备原材料");
    }
}

LDPepperPizza

public class LDPepperPizza extends Pizza{
    @Override
    public void prepare() {
        setName("伦敦的胡椒Pizza");
        System.out.println(" 伦敦的胡椒Pizza 准备原材料");
    }
}

OrderPizza

public abstract class OrderPizza {

    //定义一个抽象方法,createPizza,让各个工厂子类自己实现
    abstract Pizza createPizza(String orderType);

    //构造器
    public OrderPizza(){
       Pizza pizza = null;
       String orderType;

       do{
           orderType = getType();
           pizza = createPizza(orderType); //抽象方法,由工厂子类完成
           //输出pizza 制作过程
           pizza.prepare();
           pizza.bake();
           pizza.cut();
           pizza.box();
       } while (true);
    }

    //写一个方法,可以获取客户希望订购的披萨种类
    private String getType(){
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type: ");
            String str = null;
            str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }

    }
}

BJOrderPizza

public class BJOrderPizza extends OrderPizza{
    @Override
    Pizza createPizza(String orderType) {

        Pizza pizza = null;
        if (orderType.equals("cheese")) {
            pizza = new BJCheesePizza();
        }else if (orderType.equals("pepper")){
            pizza = new BJPepperPizza();
        }
        return pizza;
    }
}

LDOrderPizza

public class LDOrderPizza extends OrderPizza{
    @Override
    Pizza createPizza(String orderType) {

        Pizza pizza = null;
        if (orderType.equals("cheese")) {
            pizza = new LDCheesePizza();
        }else if (orderType.equals("pepper")){
            pizza = new LDPepperPizza();
        }
        return pizza;
    }
}

PizzaStore

public class PizzaStore {
    public static void main(String[] args) {
        //创建北京口味的各种Pizza
        new BJOrderPizza();

        //创建伦敦口味的各种Pizza
        //new LDOrderPizza();
    }
}

运行结果

image-20231015160901610

7.3 抽象工厂模式

image-20231015161037051

image-20231015164445152

image-20231015164424478

AbsFactory

//一个抽象工厂模式的抽象层(接口)
public interface AbsFactory {

    //让下面的工厂子类来 具体实现
    public Pizza createPizza(String orderType);
}

BJFactory

//这是工厂子类
public class BJFactory implements AbsFactory{
    @Override
    public Pizza createPizza(String orderType) {
        System.out.println("使用的是抽象工厂模式");
        Pizza pizza = null;
        if(orderType.equals("cheese")){
            pizza = new BJCheesePizza();
        }else if(orderType.equals("pepper")){
            pizza = new BJPepperPizza();
        }
        return pizza;
    }
}

LDFactory

//这是工厂子类
public class LDFactory implements AbsFactory{
    @Override
    public Pizza createPizza(String orderType) {
        System.out.println("使用的是抽象工厂模式");
        Pizza pizza = null;
        if(orderType.equals("cheese")){
            pizza = new LDCheesePizza();
        }else if(orderType.equals("pepper")){
            pizza = new LDPepperPizza();
        }
        return pizza;
    }
}

OrderPizza

public class OrderPizza {

    AbsFactory factory;

    //构造器
    public OrderPizza(AbsFactory factory){
        setFactory(factory);
    }

    private void setFactory(AbsFactory factory){
        Pizza pizza = null;
        String orderType = "";//用户输入
        this.factory = factory;

        do {
            orderType = getType();
            //factory 可能是北京的工厂子类,也可能是伦敦的工厂子类
            pizza = factory.createPizza(orderType);
            if(Objects.nonNull(pizza)){
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }else {
                System.out.println("订购失败");
                break;
            }
        }while (true);
    }

    //写一个方法,可以获取客户希望订购的披萨种类
    private String getType(){
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("input pizza type: ");
            String str = null;
            str = strin.readLine();
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }

    }

}

PizzaStore

public class PizzaStore {
    public static void main(String[] args) {
        new OrderPizza(new BJFactory());
    }
}

运行结果

image-20231015164726025

8 原型模式

8.1 案例

image-20240525181333839

输出结果

image-20240525181354960

image-20240525181540384

image-20240525181757669

image-20240525181948075

Sheep.java

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Sheep implements Cloneable{
    private String name;
    private int age;
    private String color;

    /**
     * 克隆该实例,使用默认的clone方法来完成
     * @return
     */
    @Override
    protected Object clone(){
        Sheep sheep = null;
        try {
            sheep = (Sheep) super.clone();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return sheep;
    }
}

test

public class Client {
    public static void main(String[] args) {
        Sheep sheep = new Sheep("tom", 1, "白色");
        Sheep sheep2 = (Sheep) sheep.clone();
        Sheep sheep3 = (Sheep) sheep.clone();
        Sheep sheep4 = (Sheep) sheep.clone();
        Sheep sheep5 = (Sheep) sheep.clone();

        System.out.println(sheep);
        System.out.println(sheep2);
        System.out.println(sheep3);
        System.out.println(sheep4);
        System.out.println(sheep5);
    }
}

image-20240525202253559

以后实体类增加了一个属性,可以直接克隆

8.2 应用

image-20240525203215573

8.3 浅拷贝和深拷贝

image-20240525203609233

image-20240525203506938

image-20240525203907247

image-20240525204000340

方式1

image-20240525204211320

public class DeepCloneableTarget implements Serializable,Cloneable {

    private static final long serialVersionUID = 1L;
    private String cloneName;
    private String cloneClass;

    public DeepCloneableTarget(String cloneName,String cloneClass){
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }

    //因为该类的属性,都是String ,因此我们这里使用默认的clone完成即可
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

DeepProtoType

public class DeepProtoType implements Serializable,Cloneable {
    public String name;
    public DeepCloneableTarget deepCloneableTarget;//引用类型

    public DeepProtoType() {

    }

    //深拷贝 - 方式1 使用clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep = null;
        //这里完成对基本数据类型(属性)和String的克隆
        deep = super.clone();
        //对引用类型属性,进行单独处理
        DeepProtoType deepProtoType = (DeepProtoType) deep;
        deepProtoType.deepCloneableTarget = (DeepCloneableTarget)deepCloneableTarget.clone();

        return deepProtoType;
    }
}
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        DeepProtoType p1 = new DeepProtoType();
        p1.name = "fp";
        p1.deepCloneableTarget = new DeepCloneableTarget("大牛","小牛");

        //方式1 完成深拷贝
        DeepProtoType p2 = (DeepProtoType) p1.clone();

        System.out.println("p1.name="+p1.name+" p1.deepCloneableTarget="+p1.deepCloneableTarget.hashCode());
        System.out.println("p2.name="+p2.name+" p2.deepCloneableTarget="+p2.deepCloneableTarget.hashCode());
    }
}

实现了深拷贝

image-20240525211959791

方式2

DeepProtoType

public class DeepProtoType implements Serializable,Cloneable {
    public String name;
    public DeepCloneableTarget deepCloneableTarget;//引用类型

    public DeepProtoType() {

    }

    //深拷贝 - 方式1 使用clone方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep = null;
        //这里完成对基本数据类型(属性)和String的克隆
        deep = super.clone();
        //对引用类型属性,进行单独处理
        DeepProtoType deepProtoType = (DeepProtoType) deep;
        deepProtoType.deepCloneableTarget = (DeepCloneableTarget)deepCloneableTarget.clone();

        return deepProtoType;
    }


    //深拷贝 - 方式2 通过对象的序列化实现(推荐)
    public Object deepClone() {
        //创建流对象
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            //序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this); //当前这个对象以对象流的方式输出
            //反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            DeepProtoType copyObj = (DeepProtoType) ois.readObject();
            return copyObj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            //关闭流
            try {
                if (bos != null) {
                    bos.close();
                }
                if (oos != null) {
                    oos.close();
                }
                if (bis != null) {
                    bis.close();
                }
                if (ois != null) {
                    ois.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

    }
}

Client

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        DeepProtoType p1 = new DeepProtoType();
        p1.name = "fp";
        p1.deepCloneableTarget = new DeepCloneableTarget("大牛","小牛");

        //方式1 完成深拷贝
        /*DeepProtoType p2 = (DeepProtoType) p1.clone();

        System.out.println("p1.name="+p1.name+" p1.deepCloneableTarget="+p1.deepCloneableTarget.hashCode());
        System.out.println("p2.name="+p2.name+" p2.deepCloneableTarget="+p2.deepCloneableTarget.hashCode());*/

        //方式2 完成深拷贝
        DeepProtoType p3 = (DeepProtoType)p1.deepClone();
        System.out.println("p1.name="+p1.name+" p1.deepCloneableTarget="+p1.deepCloneableTarget.hashCode());
        System.out.println("p3.name="+p3.name+" p3.deepCloneableTarget="+p3.deepCloneableTarget.hashCode());

    }
}

序列化方式深拷贝成功(如果属性是多个对象类型,更适用,推荐)

image-20240525213640076

image-20240525213848714

9 建造者模式

image-20240525215435329

AbstractHouse

public abstract class AbstractHouse {
    //打地基
    public abstract void buildBasic();
    //建墙
    public abstract void buildWalls();
    //建屋顶
    public abstract void roofed();

    public void build(){
        buildBasic();
        buildWalls();
        roofed();
    }
}

CommonHouse

public class CommonHouse extends AbstractHouse {
    @Override
    public void buildBasic()
    {
        System.out.println(" 普通房子打地基");
    }

    @Override
    public void buildWalls()
    {
        System.out.println(" 普通房子砌墙");
    }

    @Override
    public void roofed()
    {
        System.out.println(" 普通房子盖屋顶");
    }
}

Client

public class Client {
    public static void main(String[] args) {
        CommonHouse commonHouse = new CommonHouse();
        commonHouse.build();
    }
}

image-20240525221352654

image-20240525221406735

image-20240525221535882

image-20240525221701770

image-20240525222017500

House 产品

//产品 -> Product
@Data
@AllArgsConstructor
@NoArgsConstructor
public class House {
    private String basic;
    private String wall;
    private String roofed;
}

HouseBuilder 建造者

public abstract class HouseBuilder {
    protected House house = new House();
    //建造流程
    public abstract void buildBasic();
    public abstract void buildWalls();
    public abstract void roofed();

    //建造好房子,将产品(房子)返回
    public House buildHouse(){
        return house;
    }
}

两个具体建造者

CommonHouse

public class CommonHouse extends HouseBuilder{
    @Override
    public void buildBasic() {
        System.out.println("普通房子打地基");
    }

    @Override
    public void buildWalls() {
        System.out.println("普通房子砌墙");
    }


    @Override
    public void roofed() {
        System.out.println("普通房子盖屋顶");
    }
}

HighBuilding

public class HighBuilding extends HouseBuilder {

    @Override
    public void buildBasic() {
        System.out.println("高楼的基座");
    }

    @Override
    public void buildWalls() {
        System.out.println("高楼的墙");
    }

    @Override
    public void roofed() {
        System.out.println("高楼的屋顶");
    }
}

HouseDirector 指挥者

//指挥者,这里去指定建房子的流程,返回产品
public class HouseDirector {

    HouseBuilder houseBuilder = null;

    //构造器传入houseBuilder
    public HouseDirector(HouseBuilder houseBuilder){
        this.houseBuilder = houseBuilder;
    }
    //通过setter 传入houseBuilder
    public void setHouseBuilder(HouseBuilder houseBuilder){
        this.houseBuilder = houseBuilder;
    }

    //如何处理建造房子的流程,交给指挥者
    public House constructHouse(){
        //1. 打地基
        houseBuilder.buildBasic();
        //2. 砌墙
        houseBuilder.buildWalls();
        //3. 封顶
        houseBuilder.roofed();
        //建造房子将产品(房子)返回
        return houseBuilder.buildHouse();
    }


}

Client 客户

public class Client {
    public static void main(String[] args) {
        //盖普通房子
        CommonHouse commonHouse = new CommonHouse();
        //准备创建房子的指挥者
        HouseDirector houseDirector = new HouseDirector(commonHouse);
        //完成盖房子,返回产品(普通房子)
        House house = houseDirector.constructHouse();

        System.out.println("-----------------------");
        //盖高楼
        HighBuilding highBuilding = new HighBuilding();
        //重置建造者
        houseDirector.setHouseBuilder(highBuilding);
        //完成盖房子,返回产品(高楼)
        House house2 = houseDirector.constructHouse();

    }
}

image-20240525225753427

image-20240525230550306

image-20240525230908430

10 适配器模式

image-20240526094344728

image-20240526094402708

10.1 类适配器模式

image-20240526094828938

image-20240526095426245

Voltage220V

//被适配器
public class Voltage220V {
    // 输出220V电压
    public int output220V(){
        int src=220;
        System.out.println("电压="+src+"伏特");
        return src;
    }
}

IVoltage5V接口

public interface IVoltage5V {
    public int output5V();
}

VoltageAdapter

//适配器类
public class VoltageAdapter extends Voltage220V implements IVoltage5V{
    @Override
    public int output5V() {
        int srcV = output220V();//获取到220V电压
        int dstV = srcV / 44; //转成5V
        return dstV;
    }

}

Phone

public class Phone {
    public void charging(IVoltage5V v5){
        int adapterV5 = v5.output5V();
        if(adapterV5 == 5){
            System.out.println("充电中");
        }else{
            System.out.println("充电失败");
        }
    }
}

Client

public class Client {
    public static void main(String[] args) {
        System.out.println("类适配器模式测试:");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter());
    }
}

image-20240526100719117

image-20240526100754195

10.2 对象适配器模式

image-20240526101021828

image-20240526101148085

image-20240526102004419

Voltage220V

public class Voltage220V {
    // 输出220V电压
    public int output220V(){
        int src=220;
        System.out.println("电压="+src+"伏特");
        return src;
    }
}

IVoltage5V

// 适配接口
public interface IVoltage5V {
    public int output5V();
}

VoltageAdapter

//适配器类
public class VoltageAdapter implements IVoltage5V {
    private Voltage220V voltage220V;

    //通过构造器,传入一个220V的实例
    public VoltageAdapter(Voltage220V voltage220V){
        this.voltage220V = voltage220V;
    }
    @Override
    public int output5V() {
        int dst = 0;
        if(Objects.nonNull(voltage220V)){
            //获取220V的电压
            int src = voltage220V.output220V();
            //转成5V
            dst = src / 44;
            System.out.println("使用对象适配器适配220V电压到5V");
        }
        return dst;
    }

}

Phone

public class Phone {
    public void charging(IVoltage5V v5){
        int adapterV5 = v5.output5V();
        if(adapterV5 == 5){
            System.out.println("充电中");
        }else{
            System.out.println("充电失败");
        }
    }
}

Client

public class Client {
    public static void main(String[] args) {
        System.out.println("对象适配器模式测试:");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter(new Voltage220V()));
    }
}

image-20240526102648427

image-20240526102708421

10.3 接口适配器模式

image-20240526102802209

image-20240526103012358

image-20240526103146436

image-20240526110605036

Interface4

public interface Interface4 {
    public void m1();
    public void m2();
    public void m3();
    public void m4();
}

AbsAdapter

//在AbsAdapter 我们将Interface4的方法进行默认实现
public abstract class AbsAdapter implements Interface4{

    @Override
    public void m1() {

    }
    @Override
    public void m2() {

    }
    @Override
    public void m3() {

    }
    @Override
    public void m4() {

    }
}

Client

public class Client {
    public static void main(String[] args) {
        //抽象类不能直接实例化,但可以通过继承和匿名内部类的方式来创建它的实例。
        //通过匿名内部类创建抽象类的实例时,必须实现所有抽象方法
        //对于抽象类中的普通方法,可以选择性地重写,但不是必须的
        AbsAdapter absAdapter = new AbsAdapter() {
            //只需要去覆盖我们 需要使用 接口方法
            @Override
            public void m1() {
                System.out.println("使用了m1的方法");
            }
        };
        absAdapter.m1();
    }
}

image-20240526111052770

image-20240526113204698

11 桥接模式

11.1 简介

image-20240602211640426

image-20240602211905393

image-20240602212005488

image-20240602212142746

image-20240602214319483

image-20240602214702419

11.2 代码实现

Brand

public interface Brand {
    void open();
    void close();
    void call();
}

Vivo

public class Vivo implements Brand{
    @Override
    public void open() {
        System.out.println("vivo手机开机");
    }

    @Override
    public void close() {
        System.out.println("vivo手机关机");
    }

    @Override
    public void call() {
        System.out.println("vivo手机打电话");
    }
}

XiaoMi

public class XiaoMi implements Brand{
    @Override
    public void open() {
        System.out.println("小米手机开机");
    }

    @Override
    public void close() {
        System.out.println("小米手机关机");
    }

    @Override
    public void call() {
        System.out.println("小米手机打电话");
    }
}

Phone

public abstract class Phone {
    //组合品牌
    private Brand brand;

    public Phone(Brand brand) {
        this.brand = brand;
    }

    public void open(){
        this.brand.open();

    }

    public void close(){
        this.brand.close();
    }

    public void call(){
        this.brand.call();
    }
}

FoldedPhone

// 折叠式手机类,继承抽象类Phone
public class FoldedPhone extends Phone {

    /**
     * 当你创建一个子类时,编译器会隐式地调用父类的无参构造方法。如果父类没有无参构造方法,
     * 子类必须显式地调用父类的其中一个构造方法,并且要匹配父类构造方法所需要的参数。
     * 由于 Phone 类没有无参构造方法,所以 FoldedPhone 类必须显式地调用 Phone 类的构造方法,
     * 并传递一个 Brand 对象作为参数。这就是为什么 FoldedPhone 类必须实现构造方法,并且这个构造方法要调用 	       super(brand)。
     * @param brand
     */
    public FoldedPhone(Brand brand) {
        super(brand);
    }

    @Override
    public void open() {
        super.open();
        System.out.println("折叠式手机开机");
    }

    @Override
    public void close() {
        super.close();
        System.out.println("折叠式手机关机");
    }

    @Override
    public void call() {
        super.call();
        System.out.println("折叠式手机打电话");
    }
}

Client

public class Client {
    public static void main(String[] args) {
        //获取折叠式手机(样式 + 品牌)
        Phone phone = new FoldedPhone(new XiaoMi());
        phone.open();
        phone.call();

        System.out.println("--------------------");

        Phone phone1 = new FoldedPhone(new Vivo());
        phone1.open();
        phone1.call();
        phone1.close();

    }
}

image-20240602222956295

新增一个手机样式

UpRightPhone

public class UpRightPhone extends Phone{

    public UpRightPhone(Brand brand) {
        super(brand);
    }

    @Override
    public void open() {
        System.out.println("直立手机开机");
    }

    @Override
    public void close() {
        super.close();
        System.out.println("直立手机关机");
    }

    @Override
    public void call() {
        super.call();
        System.out.println("直立手机打电话");
    }
}

Client

public class Client {
    public static void main(String[] args) {
        //获取折叠式手机(样式 + 品牌)
        Phone phone = new FoldedPhone(new XiaoMi());
        phone.open();
        phone.call();

        System.out.println("--------------------");

        Phone phone1 = new FoldedPhone(new Vivo());
        phone1.open();
        phone1.call();
        phone1.close();


        System.out.println("--------------------");

        Phone phone2 = new UpRightPhone(new XiaoMi());
        phone2.open();
        phone2.call();
        phone2.close();

        System.out.println("--------------------");
        Phone phone3 = new UpRightPhone(new Vivo());
        phone3.open();
        phone3.call();
        phone3.close();

    }
}

image-20240602223315743

11.3 实际运用

image-20240602223454324

image-20240602224157339

image-20240602224227251

image-20240602224401837

12 装饰者模式

12.1 简介

image-20240604221355061

image-20240605220932027

image-20240606220116048

image-20240606220327555

image-20240606220808462

image-20240606221136070

image-20240606221622939

image-20240606221822850

12.2 案例

Drink

public abstract class Drink {
    public String des;//描述
    private float price = 0.0f;//价格

    //计算费用的抽象方法
    //子类必须实现该方法
    public abstract float cost();
}

Coffee

public class Coffee extends Drink{
    @Override
    public float cost() {
        return super.getPrice();
    }
}

咖啡种类

LongBlack

public class LongBlack extends Coffee{
    public LongBlack() {
        setDes("美式咖啡");
        setPrice(5.0f);
    }
}

ShortBlack

public class ShortBlack extends Coffee{

    public ShortBlack() {
        setDes("ShortBlack");
        setPrice(5.0f);
    }
}

Espresso

public class Espresso extends Coffee{

    public Espresso() {
        setDes("意大利咖啡");
        setPrice(6.0f);
    }
}

装饰者

Decorator

public class Decorator extends Drink{

    private Drink drink;
    public Decorator(Drink drink) { //组合
        this.drink = drink;
    }

    @Override
    public float cost() {
        //getPrice() 自己的价格
        return super.getPrice() + drink.cost();
    }

    @Override
    public String getDes() {
        //super.des 自己的描述 drink.getDes() 输出被装饰者的信息
        return super.des + " " + super.getPrice() + " && " + drink.getDes();
    }
}

调料

Chocolate

public class Chocolate extends Decorator {
    public Chocolate(Drink obj) {
        super(obj);
        setDes("巧克力");
        setPrice(3.0f); //调味品的价格
    }
}

Milk

public class Milk extends Decorator {
    public Milk(Drink obj) {
        super(obj);
        setDes("牛奶");
        setPrice(2.0f);
    }
}

Soy

public class Soy extends Decorator {
    public Soy(Drink obj) {
        super(obj);
        setDes("豆浆");
        setPrice(1.5f);
    }
}

测试

CoffeeBar

public class CoffeeBar {
    public static void main(String[] args) {
        //装饰者模式下的订单: 2份巧克力 + 1份牛奶的LongBlack

        //1. 点一份LongBlack
        Drink order = new LongBlack();
        System.out.println("费用1:" + order.cost());
        System.out.println("描述1:" + order.getDes());

        //2. 加入一份牛奶
        order = new Milk(order);
        System.out.println("order 加入一份牛奶 费用2:" + order.cost());
        System.out.println("order 加入一份牛奶 描述2:" + order.getDes());


        //3. 加入一份巧克力
        order = new Chocolate(order);
        System.out.println("order 加入一份牛奶 加入一份巧克力 费用3:" + order.cost());
        System.out.println("order 加入一份牛奶 加入一份巧克力 描述3:" + order.getDes());


        //4. 加入一份巧克力
        order = new Chocolate(order);
        System.out.println("order 加入一份牛奶 加入2份巧克力 费用4:" + order.cost());
        System.out.println("order 加入一份牛奶 加入2份巧克力 描述4:" + order.getDes());
    }
}

image-20240606225555643

12.3 应用

image-20240606230258928

image-20240606230906386

13 组合模式

13.1 简介

image-20240616145655947

image-20240616145841935

image-20240616145903684

image-20240616150407295

image-20240616150502463

image-20240616150611351

image-20240616151052279

13.2 代码实现

OrganizationComponent

@Data
@NoArgsConstructor
public abstract class OrganizationComponent {

    protected String name;//名字
    protected String desc;//说明

    public OrganizationComponent(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    protected void add(OrganizationComponent organizationComponent) {
        //默认实现
        throw new UnsupportedOperationException();
    }

    protected void remove(OrganizationComponent organizationComponent) {
        //默认实现
        throw new UnsupportedOperationException();
    }

    //方法print,做成抽象的,子类都需要实现
    protected abstract void print();
}

University

//University 就是 Composite, 可以管理College
public class University extends OrganizationComponent{
    List<OrganizationComponent> organizationComponents = new ArrayList();

    public University(String name, String des) {
        super(name, des);
    }

    @Override
    protected void add(OrganizationComponent organizationComponent) {
        organizationComponents.add(organizationComponent);
    }

    @Override
    protected void remove(OrganizationComponent organizationComponent) {
        organizationComponents.remove(organizationComponent);
    }

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

    @Override
    public String getDesc() {
        return super.getDesc();
    }

    //print方法,就是输出University 包含的学院
    @Override
    protected void print() {
        System.out.println("------" + getName() + "------");
        for (OrganizationComponent organizationComponent : organizationComponents) {
            organizationComponent.print();
        }
    }
}

College

public class College extends OrganizationComponent{
    List<OrganizationComponent> organizationComponents = new ArrayList();

    public College(String name, String des) {
        super(name, des);
    }

    @Override
    protected void add(OrganizationComponent organizationComponent) {
        //将来实际业务中,College的add 和 University 的add 不一定完全一样
        organizationComponents.add(organizationComponent);
    }

    @Override
    protected void remove(OrganizationComponent organizationComponent) {
        organizationComponents.remove(organizationComponent);
    }

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

    @Override
    public String getDesc() {
        return super.getDesc();
    }

    //print方法,就是输出University 包含的学院
    @Override
    protected void print() {
        System.out.println("------" + getName() + "------");
        for (OrganizationComponent organizationComponent : organizationComponents) {
            organizationComponent.print();
        }
    }
}

Department

public class Department extends OrganizationComponent{

    public Department(String name, String desc) {
        super(name, desc);
    }

    // add, remove就不用写了,因为他是叶子节点

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

    @Override
    public String getDesc() {
        return super.getDesc();
    }

    @Override
    protected void print() {
        System.out.println(getName());
    }
}

Client

public class Client {
    public static void main(String[] args) {
        //从大到小创建对象 学校
        OrganizationComponent university = new University("清华大学", "中国顶级大学");

        //创建学院
        OrganizationComponent computerCollege = new College("计算机学院", "计算机学院");
        OrganizationComponent infoEngineerCollege = new College("信息工程学院", "信息工程学院");

        //创建各个学院下面的系(专业)
        computerCollege.add(new Department("软件工程", "软件工程不错"));
        computerCollege.add(new Department("网络工程", "网络工程不错"));
        computerCollege.add(new Department("计算机科学与技术", "计算机科学与技术不错"));

        infoEngineerCollege.add(new Department("通信工程", "通信工程不错"));
        infoEngineerCollege.add(new Department("信息工程", "信息工程不错"));

        //将学院加入到学校
        university.add(computerCollege);
        university.add(infoEngineerCollege);

        university.print();
    }
}

运行结果

image-20240616154025137

13.3 应用

image-20240616154257331

image-20240616155022247

image-20240616155320510

image-20240616155547097

posted @ 2024-11-04 22:46  千夜ん  阅读(1)  评论(0编辑  收藏  举报