23种设计模式详解 代码例举 和 易混淆模式对比
构造类型:
单例模式、工厂模式、抽象工厂模式、原型模式、建造者模式。
单例:
单例写法有很多种,非线程安全的不推荐,部分依赖语言的也不推荐,建议使用饿汉式或者双if 检查写法
饿汉式写法:
package com.lomi.designModel.singleton;
/**
* 饿汉式
*
* @Author ZHANGYUKUN
* @Date 2022/10/18
*/
public class HungryTypeSingleton {
public static void main(String[] args) {
System.out.println("程序执行............");
//只要外部类被使用,内部静态字段和静态代码块就被调用了
HungryTypeService.t1();
HungryTypeService hungryTypeService = HungryTypeService.getInstance();
hungryTypeService.doSomeThing();
}
}
class HungryTypeService{
//饿汉式的初始化可以放到静态代码块中
private static HungryTypeService hungryTypeService = new HungryTypeService();
public HungryTypeService(){
System.out.println("HungryTypeSingleton............");
}
//饿汉式的写法2,可以在静态代码块中初始化
/* static{
hungryTypeService = new HungryTypeService();
System.out.println("静态代码块初始化......");
}*/
public static HungryTypeService getInstance(){
return hungryTypeService;
}
public static void t1(){
System.out.println("t1-------------");
}
public void doSomeThing(){
String msg = Thread.currentThread().getStackTrace()[1].getMethodName()+"调用了";
System.out.println(msg);
}
}
懒汉式写法(非线程安全):
package com.lomi.designModel.singleton;
/**
* 懒汉式写法(非线程安全)
*
* @Author ZHANGYUKUN
* @Date 2022/10/18
*/
public class LazyTypeSingleton {
public static void main(String[] args) {
LazyTypeService lazyTypeService = LazyTypeService.getInstance();
lazyTypeService.doSomeThing();
}
}
class LazyTypeService{
private static LazyTypeService lazyTypeService;
public static LazyTypeService getInstance(){
if( lazyTypeService == null ){
lazyTypeService = new LazyTypeService();
}
return lazyTypeService;
}
public void doSomeThing(){
String msg = Thread.currentThread().getStackTrace()[1].getMethodName()+"调用了";
System.out.println(msg);
}
}
懒汉式写法(线程安全):
package com.lomi.designModel.singleton;
/**
* 懒汉式写法sysnc写法,效率低(线程安全)
*
* @Author ZHANGYUKUN
* @Date 2022/10/18
*/
public class LazyTypeSingleton2 {
public static void main(String[] args) {
LazyTypeService2 lazyTypeService = LazyTypeService2.getInstance();
lazyTypeService.doSomeThing();
}
}
class LazyTypeService2{
private static LazyTypeService2 lazyTypeService;
public synchronized static LazyTypeService2 getInstance(){
if( lazyTypeService == null ){
lazyTypeService = new LazyTypeService2();
}
return lazyTypeService;
}
public void doSomeThing(){
String msg = Thread.currentThread().getStackTrace()[1].getMethodName()+"调用了";
System.out.println(msg);
}
}
懒汉式写法(双if检查写法):
package com.lomi.designModel.singleton;
/**
* 懒汉式 双if-check写法,效率高,但是又指令冲排序的问题,拿到的对象是内有初始化的对象(线程安全)
*
* @Author ZHANGYUKUN
* @Date 2022/10/18
*/
public class LazyTypeSingleton3 {
public static void main(String[] args) {
LazyTypeService3 lazyTypeService = LazyTypeService3.getInstance();
lazyTypeService.doSomeThing();
}
}
class LazyTypeService3{
private static LazyTypeService3 lazyTypeService;
public static LazyTypeService3 getInstance(){
if( lazyTypeService == null ){
synchronized ( LazyTypeService3.class ){
if( lazyTypeService == null ){
lazyTypeService = new LazyTypeService3();
}
}
}
return lazyTypeService;
}
public void doSomeThing(){
String msg = Thread.currentThread().getStackTrace()[1].getMethodName()+"调用了";
System.out.println(msg);
}
}
懒汉式(双if检查+volatile):
package com.lomi.designModel.singleton;
/**
* 懒汉式,双if-check 最终写法(线程安全),相比懒汉式写法不管用不用都会一直占用着内存
*
* @Author ZHANGYUKUN
* @Date 2022/10/18
*/
public class LazyTypeSingleton4 {
public static void main(String[] args) {
LazyTypeService4 lazyTypeService = LazyTypeService4.getInstance();
lazyTypeService.doSomeThing();
}
}
class LazyTypeService4{
private static volatile LazyTypeService4 lazyTypeService;
public static LazyTypeService4 getInstance(){
if( lazyTypeService == null ){
synchronized ( LazyTypeService4.class ){
if( lazyTypeService == null ){
lazyTypeService = new LazyTypeService4();
}
}
}
return lazyTypeService;
}
public void doSomeThing(){
String msg = Thread.currentThread().getStackTrace()[1].getMethodName()+"调用了";
System.out.println(msg);
}
}
内部类写法:
package com.lomi.designModel.singleton;
/**
* 静态内部类单例写法
*
* 内部类的2个特点,
* 第一是用到才加载,
* 第二是保证加载的线程安全
*
* 和饿汉的写法区别在于,外部类可以使用只要不用到单例的方法,就不会初始化内部内,外部类静态成员变量只要外部被使用就会初始化
*
* @Author ZHANGYUKUN
* @Date 2022/10/18
*/
public class InnerClassSingleton {
public static void main(String[] args) {
System.out.println("程序执行。。。。。。。。。。");
InnerClassService innerClassService = InnerClassService.getInstance();
innerClassService.doSomeThing();
}
}
class InnerClassService{
InnerClassService(){
System.out.println("InnerClassService初始化............");
}
//使用内部类持有外部的单例对象的引用,实现懒加载
private static class InnerClassServiceInstance{
private static final InnerClassService innerClassService = new InnerClassService();
}
public static InnerClassService getInstance(){
return InnerClassServiceInstance.innerClassService;
}
public void doSomeThing(){
String msg = Thread.currentThread().getStackTrace()[1].getMethodName()+"调用了";
System.out.println(msg);
}
}
枚举写法:
package com.lomi.designModel.singleton;
/**
*
* 基于枚举的单例,枚举本来就是单例的,天然就是一个单例,如果不用到也不会加载,只是这样语义有点混
*
* @Author ZHANGYUKUN
* @Date 2022/10/18
*/
public class EnumSingleton {
public static void main(String[] args) {
System.out.println("程序执行。。。。。。。。。。");
EnumService enumService = EnumService.INSTANCE;
enumService.doSomeThing();
}
}
enum EnumService{
INSTANCE;
public void doSomeThing(){
String msg = Thread.currentThread().getStackTrace()[1].getMethodName()+"调用了";
System.out.println(msg);
}
}
单例我们需考虑三个因素
1 单实例对象(枚举,静态常量天然就是单实例)
2 线程安全(类加载过程天然就是线程安全,也可通过sync 等锁来控制)
3 尽量懒加载(类枚举天然就是用到才加载,或者通过代码控制)
工厂模式:
简单工厂:
package com.lomi.designModel.factory;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.lomi.utils.CodeUtil;
/**
* 简单工厂(简单工厂一般只有一个工厂类,并既然是只有一个,那么就应该是静态的 )
*
* @Author ZHANGYUKUN
* @Date 2022/10/18
*/
public class SimpleUserFactory {
public static void main(String[] args) {
User user = SimpleUserFactory.newInstance();
System.out.println(JSONObject.toJSONString( user ));
}
//生成一个唯一ID,有随机默认名字的用户
public static User newInstance(){
User user = new User();
user.setName( CodeUtil.randomCode(3) );
user.setId( IdUtil.getSnowflakeNextId() );
return user;
}
}
class User{
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
抽象工厂(多工厂):我们可以,单工厂生产的是一个维度不同产品,多工厂是两个维度的变化的产品。
package com.lomi.designModel.factory;
import com.alibaba.fastjson.JSONObject;
import com.lomi.utils.CodeUtil;
import cn.hutool.core.util.IdUtil;
/**
* 多工厂(有多个工厂类,可以切换工厂实现类方法),工厂模式+模板方法
*
* 使用情景 有部分生产逻辑类似,但是又有一部分生产逻辑不同,下面的例子在Name字段是2个工厂有自己的特色
*
* @Author ZHANGYUKUN
* @Date 2022/10/18
*/
public class MultipartUserFactory {
private AbstractUserFactory abstractUserFactory;
public AbstractUserFactory getAbstractUserFactory() {
return abstractUserFactory;
}
public void setAbstractUserFactory(AbstractUserFactory abstractUserFactory) {
this.abstractUserFactory = abstractUserFactory;
}
public static void main(String[] args) {
MultipartUserFactory multipartUserFactory = new MultipartUserFactory();
multipartUserFactory.setAbstractUserFactory( new UserFactory1() );
System.out.println( multipartUserFactory.getAbstractUserFactory().newInstance().getName() );
}
}
abstract class AbstractUserFactory{
//抽象工厂的模板方法
abstract User customFeature();
//公共部分,特色部分有自定义特色的模板方法产生
public User newInstance() {
User user = customFeature();
user.setId( IdUtil.getSnowflakeNextId() );
return user;
}
}
class UserFactory1 extends AbstractUserFactory{
@Override
public User customFeature() {
User user = new User();
user.setName( "UserFactory1:" + CodeUtil.randomCode(3) );
return user;
}
}
class UserFactory2 extends AbstractUserFactory{
@Override
public User customFeature() {
User user = new User();
user.setName( "UserFactory2:" + CodeUtil.randomCode(3) );
return user;
}
}
原型模式:
Java Object 对象的clone就是用法原型模式,使用的浅拷贝,
如果需要深拷贝可以考虑重写clone方法,然后通过 Java对象序列化接口输出到ObjectOutputStream然后再反序列化回来,或者是通过json工具序列化成JSON在反序列回来,也可以在指定需要深拷贝的字段上调用clone 方法。
原型模式类图:

package com.lomi.designModel.prototype;
/**
* 原型复制的元素
*
* @Author ZHANGYUKUN
* @Date 2022/10/20
*/
public class ProtoTypeItem implements Cloneable{
private String name;
private Long age;
private Integer state;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAge() {
return age;
}
public void setAge(Long age) {
this.age = age;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
@Override
public String toString() {
return "ProtoTypeItem{" +
"name='" + name + '\'' +
", age=" + age +
", state=" + state +
'}';
}
@Override
protected ProtoTypeItem clone() throws CloneNotSupportedException {
ProtoTypeItem protoTypeItem = (ProtoTypeItem)super.clone();
return protoTypeItem;
}
public static void main(String[] args) throws CloneNotSupportedException {
ProtoTypeItem protoTypeItem = new ProtoTypeItem();
protoTypeItem.setAge(1L);
protoTypeItem.setName(new String("张三"));
protoTypeItem.setState( 2 );
ProtoTypeItem protoTypeItem5 = new ProtoTypeItem();
protoTypeItem5.setAge(1L);
protoTypeItem5.setName(new String("张三"));
protoTypeItem5.setState( 2 );
ProtoTypeItem protoTypeItem2 = protoTypeItem.clone();;
ProtoTypeItem protoTypeItem3 = protoTypeItem.clone();;
ProtoTypeItem protoTypeItem4 = protoTypeItem.clone();;
System.out.println(protoTypeItem);
System.out.println(protoTypeItem2);
System.out.println(protoTypeItem3);
System.out.println(protoTypeItem4);
System.out.println(protoTypeItem.hashCode());
System.out.println(protoTypeItem2.hashCode());
System.out.println(protoTypeItem3.hashCode());
System.out.println(protoTypeItem4.hashCode());
System.out.println(protoTypeItem.getName() == protoTypeItem2.getName() );
System.out.println(protoTypeItem.getAge() == protoTypeItem2.getAge() );
System.out.println(protoTypeItem.getState() == protoTypeItem2.getState() );
System.out.println(protoTypeItem.getName() == protoTypeItem5.getName() );
System.out.println(protoTypeItem.getAge() == protoTypeItem5.getAge() );
System.out.println(protoTypeItem.getState() == protoTypeItem5.getState() );
}
}
建造器模式:
用处在于处理配置属性的一些检查,依赖,顺序等问题,直接new 然后设置容易遗漏,然后遗漏的问题只会在后面的使用中被发现,不同实现的构造器可以按照不同的方式构造对象,把构造过程和产品解耦了
package com.lomi.designModel.build;
import io.swagger.models.auth.In;
import java.util.HashMap;
import java.util.Map;
/**
* 具体的一个构造器
*
* @Author ZHANGYUKUN
* @Date 2022/10/20
*/
public class SimpleUserBuilder extends IUserBuilder {
private Map<String,Object> configs = new HashMap<>();
@Override
public IUserBuilder setName(String name) {
configs.put("name",name);
return this;
}
@Override
public IUserBuilder setAge(Long age) {
configs.put("age",age);
return this;
}
@Override
public IUserBuilder setState(Integer state) {
configs.put("state",state);
return this;
}
//我们可以在建造的过程中检查配置是否完整
@Override
public User build(){
User user = new User();
user.setAge( (Long) configs.get("age") );
user.setName( (String) configs.get("name") );
user.setState( (Integer)configs.get("state") );
if( configs.get("name") == null && configs.get("age") == null ) {
throw new RuntimeException("name和age 不能同时为空");
}
return user;
}
public static void main(String[] args) {
User user = new SimpleUserBuilder().setAge(1L).setName("zs").setState(1).build();
System.out.println( user );
}
}
abstract class IUserBuilder{
public abstract IUserBuilder setName(String name);
public abstract IUserBuilder setAge(Long age);
public abstract IUserBuilder setState(Integer state);
public User build(){
return new User();
};
}
class User{
private String name;
private Long age;
private Integer state;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAge() {
return age;
}
public void setAge(Long age) {
this.age = age;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", state=" + state +
'}';
}
}
结构类型:
适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
适配器模式:
就是装换接口方法名字和理论实现类方法名字不一样的
类的适配器:可以继承类的时候使用
package com.lomi.designModel.adapter;
/**
* 类的适配器
*
* 1 规范是使用 AdminUserService 接口的 save方法
* 2 但是我们别的类似系统有里面有个UserService#add方法是同样逻辑的实现只是方法名字不一样
* 3 我们通过 UserServiceAdapter 来实现装换
*
* @Author ZHANGYUKUN
* @Date 2022/10/24
*/
public class ClassAdapter {
public static void main(String[] args) {
UserServiceAdapter userServiceAdapter = new UserServiceAdapter();
userServiceAdapter.save();
}
}
class UserServiceAdapter extends UserService implements AdminUserService {
@Override
public void save() {
this.add();
}
}
/**
* 实现
*/
class UserService{
public void add(){
System.out.println("add 一个用户");
}
}
/**
* 接口
*/
interface AdminUserService{
void save();
}
对象适配器:不能继承对象,并且已经有对象实例的情况使用
package com.lomi.designModel.adapter;
/**
* 对象的适配器
*
* 1 已有对象 UserService2 userService2
* 2 需要适配成 AdminUserService2@add
* 3 使用组合或者聚合对象内部调用
*
* @Author ZHANGYUKUN
* @Date 2022/10/24
*/
public class ObjectAdapter {
public static void main(String[] args) {
UserService2 userService2 = new UserService2();
UserServiceAdapter2 userServiceAdapter2 = new UserServiceAdapter2(userService2);
userServiceAdapter2.save();
}
}
class UserServiceAdapter2 implements AdminUserService2 {
private UserService2 userService2;
public UserServiceAdapter2(UserService2 userService2){
this.userService2 = userService2;
}
@Override
public void save() {
userService2.add();
}
}
/**
* 实现
*/
class UserService2{
public void add(){
System.out.println("add 一个用户");
}
}
/**
* 接口
*/
interface AdminUserService2{
void save();
}
接口的适配器:
接口有一堆方法,继承都需要重写,但是很多接口我们用不着,这时候需要接口适配器
package com.lomi.designModel.adapter;
/**
* 接口适配器
*
* 接口有一堆方法,继承都需要重写,但是很多接口我们用不着,这时候需要接口适配器
*
* @Author ZHANGYUKUN
* @Date 2022/10/24
*/
public class InterfaceAdapter {
public static void main(String[] args) {
MyUserService myUserService = new MyUserService();
myUserService.add();
}
}
class MyUserService extends UserService3Adapter{
@Override
public void add() {
System.out.println("我重写了这个方法");
}
}
class UserService3Adapter implements UserService3{
@Override
public void add() {
System.out.println("未定义的方法");
}
@Override
public void delete() {
System.out.println("未定义的方法");
}
@Override
public void update() {
System.out.println("未定义的方法");
}
@Override
public void query() {
System.out.println("未定义的方法");
}
}
interface UserService3{
void add();
void delete();
void update();
void query();
}
桥接模式:
桥接模式,让有多重变化属性维度水平拓展,而不是垂直拓展,解决一个维度添加新类型,关联维度所有类型都需要写新的实现的类爆炸问题
问题jdbc 桥分别有那两种变化条件?数据库实现和数据库操作?或者jdbc不是桥接模,而是策略模式?毕竟数据库操作是几乎不会变得,能变得只有数据库实现。
package com.lomi.designModel.bridge;
/**
* 桥接模式,让有多重变化属性维度水平拓展,而不是垂直拓展
* 比如让颜色和形状能够自由独立拓展,而不是每家一个颜色,对应的图形都要有新的实现
*
* @Author ZHANGYUKUN
* @Date 2022/10/25
*/
public class BridgeDesignType {
public static void main(String[] args) {
ThreePolygon threePolygon = new ThreePolygon(new Green());
threePolygon.draw();
}
}
/**
* 颜色
*/
interface Color{
String getColor();
}
class Red implements Color{
@Override
public String getColor() {
return "红";
}
}
class Green implements Color{
@Override
public String getColor() {
return "绿";
}
}
/**
*多边形
*/
abstract class Polygon{
Color color;
public Polygon( Color color){
this.color = color;
}
abstract String getPolygon();
public void draw(){
System.out.println("画出"+color.getColor()+"色的"+getPolygon());
}
}
class TwoPolygon extends Polygon{
public TwoPolygon(Color color) {
super(color);
}
@Override
String getPolygon() {
return "2边型";
}
}
class ThreePolygon extends Polygon{
public ThreePolygon(Color color) {
super(color);
}
@Override
String getPolygon() {
return "3边型";
}
}
装饰器模式:
对原来对象做了增强,但是元对象依旧有存在的价值,可以独立存在(和代理及其类似,元对象独立存在也是和代理的唯一区别)
package com.lomi.designModel.decorator;
/**
* 装饰器模式(套娃模式)
* 对原来对象做了增强,但是元对象依旧有存在的价值,可以独立存在(和代理及其类似,元对象独立存在也是和代理的唯一区别)
*
* @Author ZHANGYUKUN
* @Date 2022/10/25
*/
public class DecoratorDesignModel {
public static void main(String[] args) {
User user = new User();
MZUserDecorator mzUserDecorator = new MZUserDecorator(new STUserDecorator(user));
mzUserDecorator.show();
}
}
interface IUser{
void show();
}
class User implements IUser{
@Override
public void show() {
System.out.println("一个脑袋2只手的人");
}
}
class MZUserDecorator implements IUser{
private IUser user;
public MZUserDecorator(IUser user){
this.user = user;
}
@Override
public void show() {
user.show();
System.out.println("并且这个人带了帽子");
}
}
class STUserDecorator implements IUser{
private IUser user;
public STUserDecorator(IUser user){
this.user = user;
}
@Override
public void show() {
user.show();
System.out.println("并且这个人带了手套");
}
}
组合模式:
树形结构嵌套模式,Java的 Map就是这种结构
package com.lomi.designModel.composition;
import java.util.ArrayList;
import java.util.List;
/**
* 组合模式一种树形结构模型
*
* @Author ZHANGYUKUN
* @Date 2022/10/25
*/
public class CompositionDesignModel {
public static void main(String[] args) {
Item root = new Item("root");
Item item11 = new Item("item11");
Item item12 = new Item("item12");
Item item13 = new Item("item13");
Item item111 = new Item("item111");
Item item112 = new Item("item112");
Leaf leaf1111 = new Leaf("leaf1111");
root.add(item11);
root.add(item12);
root.add(item13);
item11.add(item111);
item11.add(item112);
item111.add(leaf1111);
root.p();
}
}
abstract class Node{
abstract String getName();
abstract List<Node> getChilds();
public void p(){
if( getChilds() == null ){
System.out.println( getName());
}else{
for( Node node :getChilds()){
node.p();
}
System.out.println( getName());
}
}
}
class Item extends Node{
private List<Node> childs = new ArrayList<>();
private String name;
public Item(String name ){
this.name = name;
}
void add(Node child){
childs.add(child);
}
void remove(Node node){
childs.remove(node);
}
@Override
String getName() {
return name;
}
@Override
List<Node> getChilds() {
return childs;
}
}
class Leaf extends Node{
private String name;
public Leaf(String name ){
this.name = name;
}
@Override
String getName() {
return name;
}
@Override
List<Node> getChilds() {
return null;
}
}
外观模式:
解决 部分逻辑依赖的方法或者接口多而且繁杂,这时候需要一个统筹来简化调用过程的类,核心是定义一个高层接口,来统筹复杂的过程
package com.lomi.designModel.facade;
/**
* 外观模式
*
* 解决 部分逻辑依赖的方法或者接口多而且繁杂,这时候需要一个统筹来简化调用过程的类
*
*
* @Author ZHANGYUKUN
* @Date 2022/10/25
*/
public class FacadeDesignModel {
public static void main(String[] args) {
Computer computer = new Computer();
computer.start();
}
}
class Computer{
private ICPU cpu = new CPU();
private IMainBoard mainBoard = new MainBoard();
private IMemory memory = new Memory();
public void start(){
mainBoard.electrify();
memory.load();
cpu.calculate();
}
}
interface ICPU{
void calculate();
}
class CPU implements ICPU{
public void calculate(){
System.out.println("CPU开始计算");
}
}
interface IMainBoard{
void electrify();
}
class MainBoard implements IMainBoard{
public void electrify(){
System.out.println("主板通电");
}
}
interface IMemory{
void load();
}
class Memory implements IMemory{
public void load(){
System.out.println("内存加载数据");
}
}
蝇量模式:
用于池,缓存,减少反复创建同样对象的消耗
package com.lomi.designModel.proxy;
/**
* 代理模式
*
* 对服务或者对象增强,但是不需要原对象依旧存在,装饰器强调目标对象能独立存在,并且装饰器有多层装饰的隐预
*
* @Author ZHANGYUKUN
* @Date 2022/10/26
*/
public class PorxyPattern {
public static void main(String[] args) {
UserServicePorxy userServicePorxy = new UserServicePorxy(new UserService());
userServicePorxy.add();
}
}
interface IUserService{
void add();
}
class UserService implements IUserService{
public void add(){
System.out.println("添加用户");
};
}
class UserServicePorxy implements IUserService{
private UserService userService;
public UserServicePorxy(UserService userService){
this.userService = userService;
}
public void add(){
System.out.println("先做日志");
userService.add();
};
}
代理模式:
package com.lomi.designModel.proxy;
/**
* 代理模式
*
* 对服务或者对象增强,但是不需要原对象依旧存在,装饰器强调目标对象能独立存在,并且装饰器有多层装饰的隐预
*
* @Author ZHANGYUKUN
* @Date 2022/10/26
*/
public class PorxyPattern {
public static void main(String[] args) {
UserServicePorxy userServicePorxy = new UserServicePorxy(new UserService());
userServicePorxy.add();
}
}
interface IUserService{
void add();
}
class UserService implements IUserService{
public void add(){
System.out.println("添加用户");
};
}
class UserServicePorxy implements IUserService{
private UserService userService;
public UserServicePorxy(UserService userService){
this.userService = userService;
}
public void add(){
System.out.println("先做日志");
userService.add();
};
}
行为类型:
模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。
模板方法
模板方法(抽象类里面的实现方法调用抽象方法,实体方法确定执行过程,抽象方法拓展实现
package com.lomi.designModel.templetMethod;
import org.apache.commons.math3.analysis.function.Abs;
/**
* 模板方法(抽象类里面的实现方法调用抽象方法,实体方法确定执行过程,抽象方法拓展实现)
*
* @Author ZHANGYUKUN
* @Date 2022/10/26
*/
public class TempletMethedPattern {
public static void main(String[] args) {
DiskMessageService diskMessageService = new DiskMessageService();
diskMessageService.send();
}
}
abstract class AbstractMessageService{
abstract String getMsg();
public void send(){
String msg = getMsg();
System.out.println( "我发送了:" + getMsg() );
}
}
class DiskMessageService extends AbstractMessageService{
@Override
String getMsg() {
return "从磁盘里面读出来的消息";
}
}
命令模式:
把调用者和命令分开,调用者不需要知道命令是怎么实施的,(命令接受者是不是必须的呢?我感觉没什么必要)
package com.lomi.designModel.command;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 命令模式,把命令和命令调用者分开,命令不知道会被谁调用(命令接受者是不是必须的呢?我感觉没什么必要)
*
* @Author ZHANGYUKUN
* @Date 2022/10/26
*/
public class CommandPattern {
public static void main(String[] args) throws InterruptedException {
Invoker invoker = new Invoker();
invoker.add( new RocketMQMessageSendCommand() );
invoker.add( new FishCommand() );
invoker.executeOne();
invoker.executeOne();
}
}
/**
* 命令
*/
interface Command{
void excute();
}
/**
* 发送消息命令
*/
class RocketMQMessageSendCommand implements Command {
@Override
public void excute() {
System.out.println("发送消息到mq");
}
}
/**
* 钓鱼命令
*/
class FishCommand implements Command{
@Override
public void excute() {
System.out.println("我吊了一条大鱼");
}
}
/**
* 调用者
*/
class Invoker{
private BlockingQueue<Command> queue = new LinkedBlockingQueue();
void add(Command command) throws InterruptedException {
queue.put(command);
}
void executeOne() throws InterruptedException {
queue.take().excute();
}
}
访问者模式:
让资源和针对资源的行为分开,是行为的变化拓展变得简单,但是资源类型的变化变得十分困难
package com.lomi.designModel.visitor;
import java.util.LinkedList;
import java.util.List;
/**
* 访问者模式(让资源和针对资源的行为分开,是行为的变化拓展变得简单,但是资源类型的变化变得十分困难)
*
* @Author ZHANGYUKUN
* @Date 2022/10/27
*/
public class VisitorPattern {
public static void main(String[] args) {
List<IResource> resList = new LinkedList<>();
resList.add( new Res1() );
resList.add( new Res2() );
resList.add( new Res3() );
resList.add( new Res2() );
IVisitor countVisitor = new CountVisitor();
IVisitor countRes1Visitor = new CountRes1Visitor();
resList.forEach( item->{
item.accept( countVisitor );
} );
resList.forEach( item->{
item.accept( countRes1Visitor );
} );
System.out.println( countVisitor.getCount() );
System.out.println( countRes1Visitor.getCount() );
}
}
/**
* 定义了三种资源
*/
interface IResource{
String getName();
void accept(IVisitor iVisitor);
}
class Res1 implements IResource{
@Override
public String getName() {
return "1";
}
@Override
public void accept(IVisitor iVisitor){
iVisitor.visit(this);
}
}
class Res2 implements IResource{
@Override
public String getName() {
return "2";
}
@Override
public void accept(IVisitor iVisitor){
iVisitor.visit(this);
}
}
class Res3 implements IResource{
@Override
public String getName() {
return "3";
}
@Override
public void accept(IVisitor iVisitor){
iVisitor.visit(this);
}
}
interface IVisitor{
void visit(Res1 res);
void visit(Res2 res);
void visit(Res3 res);
int getCount();
}
/**
* 统计总个数的访问者
*/
class CountVisitor implements IVisitor{
int count = 0;
@Override
public void visit(Res1 res) {
count+=1;
}
@Override
public void visit(Res2 res) {
count+=1;
}
@Override
public void visit(Res3 res) {
count+=1;
}
@Override
public int getCount() {
return count;
}
}
/**
* 统计总个数的访问者
*/
class CountRes1Visitor implements IVisitor{
int count = 0;
@Override
public void visit(Res1 res) {
count+=1;
}
@Override
public void visit(Res2 res) {
}
@Override
public void visit(Res3 res) {
}
@Override
public int getCount() {
return count;
}
}
迭代器模式:
迭代器模式,为集合提供统一的遍历方式(Java的迭代器提供了删除和快速失败等功能更加完善)
package com.lomi.designModel.iterator;
/**
* 迭代器模式,为集合提供统一的遍历方式
*
* @Author ZHANGYUKUN
* @Date 2022/10/27
*/
public class IteratorPattern {
public static void main(String[] args) {
MyCollection myCollection = new MyCollection();
Iterat iterator = myCollection.iterator();
while( iterator.hasNext() ){
Object next = iterator.next();
System.out.println(next);
}
}
}
interface Iterat<T>{
T next();
boolean hasNext();
}
interface IteratAble<T>{
Iterat iterator();
}
class MyCollection implements IteratAble{
String[] datas = new String[1024];
{
datas[0] = "1";
datas[1] = "2";
datas[2] = "3";
datas[3] = "4";
datas[4] = "5";
datas[5] = "6";
}
public String[] getDatas(){
return datas;
}
@Override
public Iterat iterator(){
return new MyIterat(this);
};
class MyIterat implements Iterat<String>{
private MyCollection myCollection;
private int index;
public MyIterat( MyCollection myCollection){
this.myCollection = myCollection;
this.index = 0;
}
@Override
public String next() {
String data = myCollection.getDatas()[index];
index++;
return data;
}
@Override
public boolean hasNext() {
return (myCollection.getDatas()[index] != null);
}
}
}
观察者模式:
让感兴趣的事件监听者,可以容易的感知事件的变化
package com.lomi.designModel.observer;
import java.util.ArrayList;
import java.util.List;
/**
* 观察者模式(感知事件的变动)
*
* @Author ZHANGYUKUN
* @Date 2022/10/27
*/
public class ObserverPattern {
public static void main(String[] args) {
Event event = new Event();
Observer observer1 = new Observer1();
Observer observer2 = new Observer2();
event.regiter(observer1);
event.regiter(observer2);
event.setState(0);
event.setState(1);
event.setState(3);
}
}
interface Observer{
void eventSateChange(Event event);
}
class Observer1 implements Observer{
@Override
public void eventSateChange(Event event) {
System.out.println("观察者1看到状态变化成了:" + event.getState());
}
}
class Observer2 implements Observer{
@Override
public void eventSateChange(Event event) {
System.out.println("观察者2看到状态变化成了:" + event.getState());
}
}
class Event{
private Integer state;
private List<Observer> observers = new ArrayList<>();
public void setState(Integer state) {
this.state = state;
notifAll();
}
public Integer getState() {
return state;
}
public List<Observer> getObservers() {
return observers;
}
public void setObservers(List<Observer> observers) {
this.observers = observers;
}
public void regiter(Observer observer){
observers.add(observer);
}
public void notifAll(){
observers.forEach( item->item.eventSateChange(this) );
}
}
策略模式:
通过改变策略对象,改变真实执行的逻辑
package com.lomi.designModel.strategy;
/**
* 策略模式
* 是一和模板方法一样简单的设计模式,一句话换实现
*
* @Author ZHANGYUKUN
* @Date 2022/10/27
*/
public class StategyPattern {
public static void main(String[] args) {
Order order = new Order();
Counter counter = new Person();
Counter counter2 = new Computer();
order.setCounter( counter );
order.getResult();
order.setCounter( counter2 );
order.getResult();
}
}
interface Counter{
void calculate();
}
class Person implements Counter{
@Override
public void calculate() {
System.out.println("数手指");
}
}
class Computer implements Counter{
@Override
public void calculate() {
System.out.println("用二进制算");
}
}
class Order{
private Counter counter;
public Counter getCounter() {
return counter;
}
public void setCounter(Counter counter) {
this.counter = counter;
}
public void getResult(){
counter.calculate();
}
}
责任链模式:
用户数据需要被多次处理的情况
package com.lomi.designModel.chain;
/**
* 责任链模式
*
* @Author ZHANGYUKUN
* @Date 2022/10/28
*/
public class ChainPatten {
public static void main(String[] args) {
ChainNode chainNode1 = new ChainNode1();
ChainNode chainNode2 = new ChainNode2();
ChainNode chainNode3 = new ChainNode3();
chainNode1.addTaill(chainNode2).addTaill(chainNode3);
chainNode1.in("datadata" );
}
}
abstract class ChainNode{
private ChainNode next;
private ChainNode pre;
public ChainNode addTaill(ChainNode newNode) {
newNode.pre = this;
this.next = newNode;
return newNode;
}
public ChainNode getNext() {
return next;
}
public void setNext(ChainNode next) {
this.next = next;
}
public ChainNode getPre() {
return pre;
}
public void setPre(ChainNode pre) {
this.pre = pre;
}
abstract void in(Object data);
abstract void out(Object data);
void doNextIn(Object data){
if( getNext() == null ){
out(data);
}else{
getNext().in(data);
}
};
void doPreOut(Object data){
if( getPre() == null ){
return;
}
getPre().out(data);
};
}
class ChainNode1 extends ChainNode{
@Override
void in(Object data) {
System.out.println("ChainNode1:in");
doNextIn(data);
}
@Override
void out(Object data) {
System.out.println("ChainNode1:out");
doPreOut(data);
}
}
class ChainNode2 extends ChainNode{
@Override
void in(Object data) {
System.out.println("ChainNode2:in");
doNextIn(data);
}
@Override
void out(Object data) {
System.out.println("ChainNode2:out");
doPreOut(data);
}
}
class ChainNode3 extends ChainNode{
@Override
void in(Object data) {
System.out.println("ChainNode3:in");
doNextIn(data);
}
@Override
void out(Object data) {
System.out.println("ChainNode3:out");
doPreOut(data);
}
}
备忘录模式:
用于建立保存点,被保存的数据允许有多个备份,并且不应该保存在自身
package com.lomi.designModel.memo;
import java.util.HashMap;
/**
* 备忘录模式
*
* 被保存的数据允许有多个备份,并且不应该保存在自身
*
*
*
* @Author ZHANGYUKUN
* @Date 2022/10/28
*/
public class MemoPattern {
public static void main(String[] args) {
User user = new User();
user.setState( 100 );
MemoCaretaker memoCaretaker = new MemoCaretaker();
memoCaretaker.setMemo( "savePoint1", user.toMemo() );
user.setState(200);
memoCaretaker.setMemo( "savePoint2",user.toMemo() );
user.setState(300);
System.out.println( user );
user.fromMemo( memoCaretaker.getMemo("savePoint1") );
System.out.println( user );
user.fromMemo( memoCaretaker.getMemo("savePoint2") );
System.out.println( user );
}
}
class User {
private Integer state;
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
/**
* 保存点可以有多个,并且不应保存在自己哪里
* @return
*/
public Memo<Integer> toMemo(){
return new Memo<>(this.state);
}
public void fromMemo(Memo<Integer> memo){
this.state = memo.getState();
}
@Override
public String toString() {
return "User{" +
"state=" + state +
'}';
}
}
/**
* 用来保存状态
* @param <T>
*/
class Memo<T>{
private T state;
public Memo( T state ){
this.state = state;
}
public T getState() {
return state;
}
public void setState(T state) {
this.state = state;
}
}
/**
* 用来统一的管理保存点
*/
class MemoCaretaker{
private HashMap<String,Memo> memos = new HashMap<>();
public Memo getMemo(String savePointName) {
return memos.get(savePointName);
}
public void setMemo(String savePointName,Memo memo) {
memos.put(savePointName,memo);
}
}
状态模式:
和策略模式类似,强调状态改变以后做的事情不一样,并且状态伴随流程变化而变化,状态内部改变,策略模式是外部介入改变策略
package com.lomi.designModel.state;
import org.w3c.dom.ls.LSOutput;
/**
* 状态模式(和策略模式类似)
*
* 强调状态改变以后做的事情不一样,并且状态伴随流程变化而变化,状态内部改变,策略模式是外部介入改变策略
*
* @Author ZHANGYUKUN
* @Date 2022/10/29
*/
public class StatePattern {
public static void main(String[] args) {
Context context = new Context();
context.doSomeThing();
context.doSomeThing();
context.doSomeThing();
context.doSomeThing();
}
}
class Context{
public static State state1 = new State1();
public static State state2 = new State2();
public static State state3 = new State3();
private State state;
public Context(){
this.state = state1;
}
public State getState() {
return state;
}
/**
* 如果是策略模式一边通过对外接口改变策略,状态模式是内部流程改变状态
* @param state
*/
public void setState(State state) {
this.state = state;
}
public void doSomeThing(){
state.doSomeThing(this);
}
}
interface State{
void doSomeThing(Context context);
}
class State1 implements State{
@Override
public void doSomeThing(Context context) {
System.out.println("做状态改变1的事情");
context.setState( Context.state2 );
}
}
class State2 implements State{
@Override
public void doSomeThing(Context context) {
System.out.println("做状态改变2的事情");
context.setState( Context.state3 );
}
}
class State3 implements State{
@Override
public void doSomeThing(Context context) {
System.out.println("做状态改变3的事情");
}
}
中介者模式:
中介者的作用是解耦类对象之间的关系,一切耦合都由中介来承担,尤其是多方关系的时候
package com.lomi.designModel.mediator;
import java.util.HashMap;
import java.util.Map;
/**
* 中介者模式(中介者的作用是解耦类对象之间的关系,一切耦合都由中介来承担,尤其是多方关系的时候)
*
* @Author ZHANGYUKUN
* @Date 2022/10/30
*/
public class MediatorPattern {
public static void main(String[] args) {
Mediator mediator = new HouseMediator();
User customer = new Customer("Customer",mediator);
User owner = new Owner("Owner",mediator);
owner.sendMessage("query");
customer.sendMessage("query");
customer.sendMessage("ok");
}
}
interface Mediator{
void register(String userName,User user);
void receiveMessage(String userName,String message);
}
class HouseMediator implements Mediator{
private Map<String,User> users = new HashMap<>();
@Override
public void register(String userName, User user) {
users.put(userName,user);
}
@Override
public void receiveMessage(String userName, String message) {
if( "Customer".equals(userName) ){
if( "query".equals(message) ){
System.out.println("客人询问租房价格");
//可以在Owner中定义询价接口,强制转换然后调用
}else if( "ok".equals(message)){
System.out.println("客人确定要这个房子");
}
}else if("Owner".equals(userName) ){
if( "query".equals(message) ){
System.out.println("房主登记房屋");
}
}
}
}
interface User{
void sendMessage(String message);
Mediator getMediator();
}
class Owner implements User{
private String userName;
private Mediator mediator;
public Owner(String userName,Mediator mediator){
this.mediator = mediator;
this.userName = userName;
}
@Override
public void sendMessage( String message) {
mediator.receiveMessage( userName,message );
}
@Override
public Mediator getMediator() {
return mediator;
}
}
class Customer implements User{
private String userName;
private Mediator mediator;
public Customer(String userName,Mediator mediator){
this.mediator = mediator;
this.userName = userName;
}
@Override
public void sendMessage( String message) {
mediator.receiveMessage( userName,message );
}
@Override
public Mediator getMediator() {
return mediator;
}
}
解释器模式:
为解释表达式之类的业务提供的设计模式,使解释表达式变得容易拓展
能耍的时候就一定要耍,不能耍的时候一定要学。
--天道酬勤,贵在坚持posted on 2022-10-18 20:06 zhangyukun 阅读(94) 评论(0) 收藏 举报
浙公网安备 33010602011771号