首页 > 其他分享 >设计原理上

设计原理上

时间:2024-11-04 22:43:22浏览次数:1  
标签:void System class 设计 println 原理 public out

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

标签:void,System,class,设计,println,原理,public,out
From: https://www.cnblogs.com/fengpeng123/p/18526907

相关文章

  • 【鸿蒙南向】移植案例与原理 - build lite源码分析 之 hb命令__main__.py
    ......
  • 【鸿蒙南向】移植案例与原理 - HPM包描述文件bundle.json
    ......
  • 计算机毕业设计java基于springboot的网上书店系统
    文章目录项目介绍技术介绍功能介绍核心代码数据库参考系统效果图项目介绍  本文致力于探讨基于SpringBoot框架的网上书店系统的全面设计与实现。随着网络技术的迅猛发展,网上书店作为一种便捷的购书方式受到了广泛关注。为了满足用户对于购书的需求,本文首先从用......
  • Golang channel底层原理
    1原理默认情况下,读写未就绪的channel(读没有数据的channel,或者写缓冲区已满的channel)时,协程会被阻塞。但是当读写channel操作和select搭配使用时,即使channel未就绪,也可以执行其它分支,当前协程不会被阻塞。ch:=make(chanint)select{case<-ch:default:}本文......
  • EPS原理笔记
    EPSUE(userequipment),移动用户设备LTE(LongTermEvolution),无线接入网部分,E-UTRANEPC(systemArchitectureEvolution、EvoloedPacketCore),核心网部分,主要包括MME、S-GW、P-GW、HSS,连接Internet等外部PDN(PacketDataNetwork)3GPP定义3GPP接入是指遵循3GPP制定......
  • 响应式网页设计案例
    文章目录概念核心理念响应式设计的优点实现方法代码案例解释概念响应式设计核心理念是一个网站能够根据访问者的设备特性自动调整布局、内容和功能,以提供最佳的用户体验。它依赖于CSS媒体查询、灵活的网格布局和可伸缩的图像,确保网页内容在不同设备上都能自动调整......
  • Java毕设项目案例实战II基于Java+Spring Boot+Mysql的果蔬作物疾病防治系统的设计与实
    目录一、前言二、技术介绍三、系统实现四、核心代码五、源码获取全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末一、前言随着现代农业的快速发展,果蔬作物的健康生长与高效管理......
  • Java毕设项目案例实战II基于Java+Spring Boot+Mysql的公司资产网站设计与实现(开发文档
    目录一、前言二、技术介绍三、系统实现四、核心代码五、源码获取全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末一、前言在当今信息化高速发展的时代,企业资产的高效管理和精确......
  • 基于matlab的人脸识别系统设计与仿真
    第一章绪论本章提出了本文的研究背景及应用前景。首先阐述了人脸图像识别意义;然后介绍了人脸图像识别研究中存在的问题;接着介绍了自动人脸识别系统的一般框架构成;最后简要地介绍了本文的主要工作和章节结构。1.1研究背景自70年代以来.随着人工智能技术的兴起.以及人类视觉......
  • 基于SpringBoot+Vue的可盈保险合同管理系统设计与实现毕设(文档+源码)
            目录一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、源码获取:        大家好呀,我是一个混迹在java圈的码农。今天要和大家分享的是一款基于SpringBoot+Vue的可盈保险合同管理系统,项目源码请点击文章末尾联系我哦~目前有各类......