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个空位可以放棋子,那如果用常规的面向对象方式编程,每盘棋都可能有两三百个棋子对象产生,一台服务器就很难支持更多的玩家玩围棋游戏了,毕竟内存空间还是有限的。如果用了享元模式来处理棋子,那么棋子对象可以减少到只有两个实例,

相关推荐
白鲸开源13 分钟前
Ubuntu 22 下 DolphinScheduler 3.x 伪集群部署实录
java·ubuntu·开源
ytadpole20 分钟前
Java 25 新特性 更简洁、更高效、更现代
java·后端
纪莫1 小时前
A公司一面:类加载的过程是怎么样的? 双亲委派的优点和缺点? 产生fullGC的情况有哪些? spring的动态代理有哪些?区别是什么? 如何排查CPU使用率过高?
java·java面试⑧股
JavaGuide1 小时前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
用户3721574261351 小时前
Java 轻松批量替换 Word 文档文字内容
java
白鲸开源2 小时前
教你数分钟内创建并运行一个 DolphinScheduler Workflow!
java
晨米酱2 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
Java中文社群2 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试
代码匠心2 小时前
从零开始学Flink:数据源
java·大数据·后端·flink
间彧2 小时前
Spring Boot项目中如何自定义线程池
java