设计模式之享元模式

写在前面

本文看下一种结构型设计模式,享元模式。

1:介绍

1.1:什么时候使用享元模式

当程序需要大量的重复对象,并且这些大量的重复对象只有部分属性不相同,其他都是相同的时候,就可以考虑使用享元设计模式设计模式来实现。典型的如围棋游戏中的棋子,除了颜色和位置不同外,其他都相同。射击游戏中的子弹,除了大小,型号,杀伤力等不同外,其他都相同。

1.2:UML类图

享元设计模式,包含如下元素:

1:Flyweight
    定义享元对象的公共操作
2:ConcreteFlyweight
    具体的享元对象
3:FlyweightFactory
    享元对象工厂,负责生产享元对象,方便客户端获取享元对象的同时,也可以缓存享元对象,防止因为创建过多的对象而导致内存溢出等问题(想一下射击游戏,用户如果是用机关枪一直突突突,得创建多少对象啊)

UML图如下:

另外,享元设计模式分为内部状态和外部状态,如围棋游戏,棋子的黑色和白色,就是内部状态,在对象的内部定义和维护,是可以共享的,但是落子的位置则是各不相同的,就是外部状态,需要外部传入。如果是工作中认为场景适合使用享元设计模式则一定要考虑清楚内部状态和外部状态的问题。

2:实例

源码

2.1:场景

围棋游戏,创建游戏中的黑子和白子。

2.2:程序

  • 享元接口
java 复制代码
public interface Chess {
    // 绘制棋子(落子,走一步棋)
    // 位置,外部状态,由外部传入
    void draw(int x,int y);
}
  • 内部状态枚举
java 复制代码
public enum Color {
    BLACK("黑色"), WHITE("白色");
    private String name;

    // 默认就是private的,并且不能反射,暴力也不行
    Color(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public String getAlias() {
        return this.name;
    }
}
  • 具体享元类
    黑子和白子类:
java 复制代码
//黑棋
public class BlackChess implements Chess {
    // 内部状态,共享
    private final Color color = Color.BLACK;

    private final String sharp = "圆形";

    public Color getColor() {
        return color;
    }

    // 外部状态
    @Override
    public void draw(int x, int y) {
        System.out.println(String.format("%s%s棋子置于(%d,%d)处", sharp, color.getAlias(), x, y));
    }
}

//白棋
public class WhiteChess implements Chess {
    //内部状态,共享
    private final Color color = Color.WHITE;

    private final String sharp = "圆形";

    public Color getColor() {
        return color;
    }

    @Override
    public void draw(int x, int y) {
        System.out.println(String.format("%s%s棋子置于(%d,%d)处", sharp, color.getAlias(), x, y));
    }
}
  • 享元工厂类
java 复制代码
public class ChessFactory {
    private static final Map<Color, Chess> chessMap = new HashMap<>();

    public static Chess getChess(Color color) {
        Chess chess = chessMap.get(color);
        if (chess == null) {
            chess = color == Color.WHITE ? new WhiteChess() : new BlackChess();
            chessMap.put(color, chess);
        }
        return chess;
    }
}
  • 测试
java 复制代码
public class FlyweightClient {

    @Test
    public void playChess() {
        //下黑子
        Chess backChess1 = ChessFactory.getChess(Color.BLACK);
        backChess1.draw(2, 5);

        //下白子
        Chess whiteChess = ChessFactory.getChess(Color.WHITE);
        whiteChess.draw(3, 5);

        //下黑子
        Chess backChess2 = ChessFactory.getChess(Color.BLACK);
        backChess2.draw(2, 6);

        System.out.println(String.format("backChess1:%d | backChess2:%d | whiteChess:%d",
                backChess1.hashCode(), backChess2.hashCode(), whiteChess.hashCode()));
    }
}

运行:

圆形黑色棋子置于(2,5)处
圆形白色棋子置于(3,5)处
圆形黑色棋子置于(2,6)处
backChess1:1327763628 | backChess2:1327763628 | whiteChess:1915503092

Process finished with exit code 0

写在后面

参考文章列表

秒懂设计模式之享元模式(Flyweight Pattern)

相关推荐
wrx繁星点点1 小时前
状态模式(State Pattern)详解
java·开发语言·ui·设计模式·状态模式
金池尽干3 小时前
设计模式之——观察者模式
观察者模式·设计模式
也无晴也无风雨3 小时前
代码中的设计模式-策略模式
设计模式·bash·策略模式
捕鲸叉12 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
Mr. zhihao13 小时前
享元模式在 JDK 中的应用解析
java·享元模式
wrx繁星点点13 小时前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
凉辰13 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
菜菜-plus13 小时前
java设计模式之策略模式
java·设计模式·策略模式
暗黑起源喵13 小时前
设计模式-迭代器
设计模式
lexusv8ls600h15 小时前
微服务设计模式 - 网关路由模式(Gateway Routing Pattern)
spring boot·微服务·设计模式