Java设计模式—享元(FlyWeight)模式

享元模式(Flyweight),运用共享技术有效地支持大量细粒度的对象

java 复制代码
public abstract class Piece {
    protected PieceColor m_color;
    protected PiecePos m_pos;

    public Piece(PieceColor color ,PiecePos pos){
        m_color = color;
        m_pos = pos;
    }

    public abstract void draw() ;
}
java 复制代码
public class WhitePiece extends Piece{
    public WhitePiece(PieceColor color ,PiecePos pos){
        super(color , pos);
    }

    @Override
    public void draw() {
        System.out.println("draw a whitePiece ! ");
    }
}
java 复制代码
public class BlackPiece extends Piece {
    public BlackPiece(PieceColor color , PiecePos pos){
        super(color,pos);
    }

    @Override
    public void draw() {
        System.out.println("draw a blackPiece !");
    }
}
java 复制代码
public enum PieceColor {
    BLACK,
    WHITE
}
java 复制代码
public class PieceBoard {
    private static final ArrayList<Piece> m_arrayPiece = new ArrayList<>();

    private String m_blackName;
    private String m_whiteName;

    public PieceBoard(String black , String white){
        m_blackName = black;
        m_whiteName = white;
    }

    public void SetPiece(PieceColor color ,PiecePos pos){
        Piece piece = null;
        if(color == PieceColor.BLACK){
            piece = new BlackPiece(color, pos);
            System.out.println(m_blackName + "在位置(" +
                    pos.getX() + ","+pos.getY() + ")");
            piece.draw();
        }else {
            piece = new WhitePiece(color, pos);
            System.out.println(m_whiteName + "在位置(" +
                    pos.getX() + "," +pos.getY() +")");
            piece.draw();
        }
        m_arrayPiece.add(piece);
    }


    public static void main(String[] args) {
        PieceBoard board = new PieceBoard("Black Player", "White Player");
        PiecePos pos = new PiecePos(3, 4);
        board.SetPiece(PieceColor.BLACK, pos);
    }
}


享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类实例来表示数据。如果能发现这些实例除了几个参数外基本上都是相同的,有时就能够大幅度地减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将它们传递进来,
就可以通过共享大幅度地减少单个实例的数目。 也就是说,享元模式 Flyweight 执行时所需的状态有内部的也可能有外部的,内部状态存储于 ConcreteFlyweight 对象之中,而外部对象则应该考虑由客户端对象存储或计算,当调用 Flyweight 对象的操作时,将该状态传递给它。"

在Java中,字符串 String 就是运用了Flyweight模式。'==' 可以用来确定titleA与titleB是否是相同的实例,返回值为 boolean 值。当用 new String()方法时,两个对象 titleA 和 titleB 的引用地址是不相同的,但当 titleC 和 titleD 都使用赋值的方式时,两个字符串的引用地址竟然是相同的。
试想一下,如果每次创建字符串对象时,都需要创建一个新的字符串对象的话,内存的开销会很大。所以如果第一次创建了字符串对象titleC,下次再创建相同的字符串titleD时只是把它的引用指向相同的字符串 String ,这样就实现了'String '在内存中的共享。" 虽说享元模式更多的时候是一种底层的设计模式,但现实中也是有应用的。比如说休闲游戏开发中,像围棋、五子棋、跳棋等,它们都有大量的棋子对象,围棋和五子棋只有黑白两色、跳棋颜色略多一些,但也是不太变化的,所以颜色应该是棋子的内部状态,而各个棋子之间的差别主要就是位置的不 同,所以方位坐标应该是棋子的外部状态,像围棋,一盘棋理论上有361个空位可以放棋子,那如果用常规的面向对象方式编程,每盘棋都可能有两三百个棋子对象产生,一台服务器就很难支持更多的玩家玩围棋游戏了,毕竟内存空间还是有限的。如果用了享元模式来处理棋子,那么棋子对象可以减少到只有两个实例,

相关推荐
是梦终空2 分钟前
JAVA毕业设计176—基于Java+Springboot+vue3的交通旅游订票管理系统(源代码+数据库)
java·spring boot·vue·毕业设计·课程设计·源代码·交通订票
落落落sss11 分钟前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
码爸15 分钟前
flink doris批量sink
java·前端·flink
Monodye1 小时前
【Java】网络编程:TCP_IP协议详解(IP协议数据报文及如何解决IPv4不够的状况)
java·网络·数据结构·算法·系统架构
一丝晨光1 小时前
逻辑运算符
java·c++·python·kotlin·c#·c·逻辑运算符
无名指的等待7121 小时前
SpringBoot中使用ElasticSearch
java·spring boot·后端
Tatakai252 小时前
Mybatis Plus分页查询返回total为0问题
java·spring·bug·mybatis
武子康2 小时前
大数据-133 - ClickHouse 基础概述 全面了解
java·大数据·分布式·clickhouse·flink·spark
.生产的驴2 小时前
SpringBoot 消息队列RabbitMQ 消费者确认机制 失败重试机制
java·spring boot·分布式·后端·rabbitmq·java-rabbitmq
Code哈哈笑2 小时前
【C++ 学习】多态的基础和原理(10)
java·c++·学习