设计模式之享元模式

写在前面

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

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)

相关推荐
小白不太白9504 小时前
设计模式之 模板方法模式
java·设计模式·模板方法模式
色空大师4 小时前
23种设计模式
java·开发语言·设计模式
闲人一枚(学习中)4 小时前
设计模式-创建型-建造者模式
java·设计模式·建造者模式
博风5 小时前
设计模式:6、装饰模式(包装器)
设计模式
A_cot5 小时前
理解设计模式与 UML 类图:构建稳健软件架构的基石
microsoft·设计模式·简单工厂模式·工厂方法模式·uml
君败红颜5 小时前
设计模式之创建模式篇
设计模式
闲人一枚(学习中)8 小时前
设计模式-创建型-抽象工厂模式
设计模式·抽象工厂模式
小白不太白95010 小时前
设计模式之 观察者模式
观察者模式·设计模式
小白不太白95011 小时前
设计模式之 责任链模式
python·设计模式·责任链模式
吾与谁归in12 小时前
【C#设计模式(13)——代理模式(Proxy Pattern)】
设计模式·c#·代理模式