Skip to content

设计模式学习笔记

基本原则

行为模式

策略模式

观察者模式

创建者模式

工厂模式

工厂模式提供一种将对象的实例化过程封装在工厂类内的方式,可以将对象的创建和使用代码分离,提供统一接口来创建不同的对象。

我有三个室友,分别是Sui_AnranEnterYoungLylPower

Sui_Anran 不爱学习,总是睡醒再去学习

EnterYoung 喜欢写屎山代码

LylPower 喜欢用拼音给变量命名

他们三个继承于IRoommate接口,均实现writeCode方法。

在该程序中,我们可以召唤室友来写代码

室友接口

java
package com.gettler.dp.roommate;


/**
 * 室友接口
 *
 * @author Gettler
 * @date 2023/10/07
 */
public interface IRoommate {
  void writeCode();
}

EnterYoung 实现代码

java
package com.gettler.dp.roommate.impl;


import com.gettler.dp.roommate.IRoommate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 室友 EnterYoung
 *
 * @author Gettler
 * @date 2023/10/07
 */
public class EnterYoung implements IRoommate {
  private Logger logger = LoggerFactory.getLogger(EnterYoung.class);

  @Override
  public void writeCode() {
    logger.info("我拉屎山");
  }
}

LylPower 实现代码

java
package com.gettler.dp.roommate.impl;


import com.gettler.dp.roommate.IRoommate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 室友 LylPower
 *
 * @author Gettler
 * @date 2023/10/07
 */
public class LylPower implements IRoommate {
  private Logger logger = LoggerFactory.getLogger(LylPower.class);

  @Override
  public void writeCode() {
    logger.info("我用拼音命名");
  }
}

Sui_Anran 实现代码

Java
package com.gettler.dp.roommate.impl;

import com.gettler.dp.roommate.IRoommate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 室友 Sui_Anran
 *
 * @author Gettler
 * @date 2023/10/07
 */
public class Sui_Anran implements IRoommate {
  private Logger logger = LoggerFactory.getLogger(Sui_Anran.class);

  @Override
  public void writeCode() {
    logger.info("睡醒就写");
  }
}

工厂类

java
package com.gettler.dp;

import com.gettler.dp.roommate.IRoommate;
import com.gettler.dp.roommate.impl.EnterYoung;
import com.gettler.dp.roommate.impl.LylPower;
import com.gettler.dp.roommate.impl.Sui_Anran;

import java.util.HashMap;

/**
 * 室友工厂类
 *
 * @author Gettler
 * @date 2023/10/07
 */
public class RoommateFactory {

    private static HashMap<Integer, Class> roommateHashMap = new HashMap<>();

    static {
        roommateHashMap.put(93, EnterYoung.class);
        roommateHashMap.put(97, LylPower.class);
        roommateHashMap.put(94, Sui_Anran.class);
    }

    public IRoommate getRoommate(Integer stuNumber) throws Exception {
        Class who =  roommateHashMap.get(stuNumber) ;
        if (who == null) {
            throw new Exception("学号错误");
        }
        return (IRoommate) roommateHashMap.get(stuNumber).newInstance();
    }
}

就是现在,召唤室友!!!

java
package com.gettler.dp;


import org.junit.Test;

public class TestFactory {
    @Test
    public void test() throws Exception {
        RoommateFactory factory = new RoommateFactory();
        factory.getRoommate(97).writeCode();
        factory.getRoommate(97).writeCode();
        factory.getRoommate(93).writeCode();
        factory.getRoommate(94).writeCode();
    }
}

建造者模式

建造者模式就是通过将多个简单对象进行一步步组装构建出一个复杂对象

我的两个室友要考研了,两个人的科目都一样,数学、英语、政治和专业课,

但是由于两个人开始学习的时间点不一样,他们选择不一样的课程去学习。

课程接口

java
package com.gettler.dp;

/**
 * @author Gettler
 * @date 2023/10/19
 */
public interface Lesson {
    /**
     * 场景;数学、英语、专业课、政治
     */
    String scene();

    /**
     * 花费时间
     */
    Integer time();
}

数学课有三种

java
package com.gettler.dp.math;

import com.gettler.dp.Lesson;

/**
 * @author Gettler
 * @date 2023/10/19
 */
public class LiYongle implements Lesson {
    @Override
    public String scene() {
        return "数学课";
    }

    @Override
    public Integer time() {
        return 67;
    }
}
java
package com.gettler.dp.math;

import com.gettler.dp.Lesson;

/**
 * @author Gettler
 * @date 2023/10/19
 */
public class TangJiafeng implements Lesson {
    @Override
    public String scene() {
        return "数学课";
    }

    @Override
    public Integer time() {
        return 80;
    }
}
java
package com.gettler.dp.math;

import com.gettler.dp.Lesson;

/**
 * @author Gettler
 * @date 2025/01/24
 */
public class ZhangYu implements Lesson {
    @Override
    public String scene() {
        return "数学课";
    }

    @Override
    public Integer time() {
        return 75;
    }
}

英语课有三种

java
package com.gettler.dp.english;

import com.gettler.dp.Lesson;

/**
 * @author Gettler
 * @date 2023/10/19
 */
public class LiuXiaoyan implements Lesson {

    @Override
    public String scene() {
        return "英语课";
    }

    @Override
    public Integer time() {
        return 30;
    }
}
java
package com.gettler.dp.english;

import com.gettler.dp.Lesson;

/**
 * @author Gettler
 * @date 2023/10/19
 */
public class TangChi implements Lesson {
    @Override
    public String scene() {
        return "英语课";
    }

    @Override
    public Integer time() {
        return 20;
    }
}
java
package com.gettler.dp.english;

import com.gettler.dp.Lesson;

/**
 * @author Gettler
 * @date 2023/10/19
 */
public class TianJing implements Lesson {
    @Override
    public String scene() {
        return "英语课";
    }

    @Override
    public Integer time() {
        return 50;
    }
}

专业课有两种

java
package com.gettler.dp.major;

import com.gettler.dp.Lesson;

/**
 * @author Gettler
 * @date 2023/10/19
 */
public class LanMao implements Lesson {
    @Override
    public String scene() {
        return "专业课";
    }

    @Override
    public Integer time() {
        return 50;
    }
}
java
package com.gettler.dp.major;

import com.gettler.dp.Lesson;

public class WangZhuo implements Lesson {
    @Override
    public String scene() {
        return "专业课";
    }

    @Override
    public Integer time() {
        return 15;
    }
}

政治课有两种

java
package com.gettler.dp.politics;

import com.gettler.dp.Lesson;

public class XiaoXiurong implements Lesson {
    @Override
    public String scene() {
        return "政治课";
    }

    @Override
    public Integer time() {
        return 20;
    }
}
java
package com.gettler.dp.politics;

import com.gettler.dp.Lesson;

/**
 * @author Gettler
 * @date 2023/10/19
 */
public class XuTao implements Lesson {
    @Override
    public String scene() {
        return "政治课";
    }

    @Override
    public Integer time() {
        return 15;
    }
}

课程单接口

java
package com.gettler.dp;

/**
 * @author Gettler
 * @date 2023/10/19
 */
public interface IMenu {
    /**
     * 学数学课
     *
     * @param lesson
     * @return {@link IMenu}
     */
    IMenu studyMath(Lesson lesson);


    /**
     * 学英语课
     *
     * @param lesson
     * @return {@link IMenu}
     */
    IMenu studyEnglish(Lesson lesson);

    /**
     * 学专业课
     *
     * @param lesson
     * @return {@link IMenu}
     */
    IMenu studyMajor(Lesson lesson);

    /**
     * 学政治课
     *
     * @param lesson
     * @return {@link IMenu}
     */
    IMenu studyPolitics(Lesson lesson);


    /**
     * 明细
     *
     * @return {@link String}
     */
    String getDetail();
}

建造者模式实现课程单

java
package com.gettler.dp;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Gettler
 * @date 2023/10/25
 */
public class StudyPackageMenu implements IMenu {

    private List<Lesson> list = new ArrayList<>();  // 课程清单
    private BigDecimal sumTime = BigDecimal.valueOf(0);      // 学习时长

    @Override
    public IMenu studyMath(Lesson lesson) {
        list.add(lesson);
        sumTime = sumTime.add(BigDecimal.valueOf(lesson.time()));
        return this;
    }

    @Override
    public IMenu studyEnglish(Lesson lesson) {
        list.add(lesson);
        sumTime = sumTime.add(BigDecimal.valueOf(lesson.time()));
        return this;
    }

    @Override
    public IMenu studyMajor(Lesson lesson) {
        list.add(lesson);
        // 专业课有手就行,二倍速!
        sumTime = sumTime.add(BigDecimal.valueOf(lesson.time() / 2));
        return this;
    }

    @Override
    public IMenu studyPolitics(Lesson lesson) {
        list.add(lesson);
        // 政治要背,不喜欢背东西,时间会比预计长
        sumTime = sumTime.add(BigDecimal.valueOf(lesson.time() * 1.5));
        return this;
    }

    @Override
    public String getDetail() {
        StringBuilder detail = new StringBuilder(
                "\r\n-------------------------------------------------------\r\n" + "实际花费时间:" + sumTime + "\r\n" +
                "课程清单:\r\n");
        for (Lesson lesson : list) {
            detail.append(lesson.scene()).append("").append(lesson.getClass()).append(",预计花费时间:")
                    .append(lesson.time()).append(" 天。\n");
        }
        return detail.toString();
    }
}

俩室友开始选课!

java
package com.gettler.dp;

import com.gettler.dp.english.TangChi;
import com.gettler.dp.english.TianJing;
import com.gettler.dp.major.LanMao;
import com.gettler.dp.major.WangZhuo;
import com.gettler.dp.math.LiYongle;
import com.gettler.dp.math.TangJiafeng;
import com.gettler.dp.politics.XiaoXiurong;
import com.gettler.dp.politics.XuTao;
import org.junit.Test;

/**
 * @author Gettler
 * @date 2025/01/24
 */
public class TestBuilder {
    @Test
    public void test() throws Exception {
        System.out.println("Sui_Anran 选择的课程清单:" +
                           new StudyPackageMenu().studyMath(new TangJiafeng()).studyEnglish(new TianJing())
                                                 .studyPolitics(new XiaoXiurong()).studyMajor(new LanMao())
                                                 .getDetail());
        System.out.println();
        System.out.println("LylPower 选择的课程清单:" +
                           new StudyPackageMenu().studyMath(new LiYongle()).studyEnglish(new TangChi())
                                                 .studyPolitics(new XuTao()).studyMajor(new WangZhuo()).getDetail());
    }
}

原型模式

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。

单例模式

结构型模式

适配器模式