GoF设计模式 - 享元模式

Posted 让程序飞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GoF设计模式 - 享元模式相关的知识,希望对你有一定的参考价值。

前言

享元模式(Flyweight Pattern)运用共享技术有效地支持大量细粒度的对象,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

模式所涉及的角色

  • Flyweight: 享元接口,通过这个接口传入外部状态并作用于外部状态;
  • ConcreteFlyweight: 具体的享元实现对象,必须是可共享的,需要封装享元对象的内部状态;
  • UnsharedConcreteFlyweight: 非共享的享元实现对象,并不是所有的享元对象都可以共享,非共享的享元对象通常是享元对象的组合对象;
  • FlyweightFactory: 享元工厂,主要用来创建并管理共享的享元对象,并对外提供访问共享享元的接口

模式实现 

 以五子棋/围棋做示例

  • 棋子(ChessPieces)类是抽象享元角色,它包含了一个落子的 DownPieces(Graphics graphics,Point point,Color color) 方法;
  • 具体棋子(WeiQiPieces)类是具体享元角色,它实现了落子方法;
  • ChessGameFactory 是享元工厂角色,它通过 hashMap 来管理棋子,并且提供了获取白子或者黑子的 getChessPieces(Color color) 方法;
  • 客户类(Chessboard)利用 Graphics 组件在框架窗体中绘制一个棋盘,并实现 mouseClicked(MouseEvent e) 事件处理方法,该方法根据用户的选择从享元工厂中获取白子或者黑子并落在棋盘上

 代码实现

 棋子与具体棋子

public interface ChessPieces 
    /**
     * 下子
     *
     * @param graphics 绘制
     * @param point    坐标
     */
    void downPieces(Graphics graphics, Point point, Color color);
public class WeiQiPieces implements ChessPieces 

    @Override
    public void downPieces(Graphics graphics, Point point, Color color) 
        graphics.setColor(color);
        graphics.fillOval(point.x, point.y, 30, 30);
    

棋子工厂

public class ChessGameFactory 
    private final Map<Color,ChessPieces> chessPiecesMap = new HashMap<>();

    public ChessPieces getChessPieces(Color color) 
        ChessPieces chessPieces = chessPiecesMap.get(color);
        if(chessPieces == null)
            chessPiecesMap.put(color, new WeiQiPieces());
        
        return chessPiecesMap.get(color);
    

棋盘及启动类

public class ChessBoard extends MouseAdapter 
    private final ChessGameFactory chessGameFactory = new ChessGameFactory();
    private final Graphics graphics;
    private final JRadioButton whiteChess;
    private final JRadioButton blackChess;
    private final int x = 50;
    private final int y = 50;
    /**
     * 小方格宽度和高度
     */
    private final int w = 40;
    /**
     * 棋盘宽度和高度
     */
    private final int rw = 400;

    public ChessBoard()

        JPanel southJp = new JPanel();
        whiteChess = new JRadioButton("白子");
        blackChess = new JRadioButton("黑子", true);
        ButtonGroup group = new ButtonGroup();
        group.add(whiteChess);
        group.add(blackChess);
        southJp.add(whiteChess);
        southJp.add(blackChess);
        JFrame jFrame = new JFrame("享元模式在围棋游戏中的简单应用");
        Container cont = jFrame.getContentPane();
        cont.add(southJp);
        jFrame.setSize(500, 500);
        jFrame.setVisible(true);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel centerJp = new JPanel();
        centerJp.setLayout(null);
        centerJp.setSize(800, 800);
        centerJp.addMouseListener(this);
        jFrame.add("Center", centerJp);

        try 
            Thread.sleep(500);
         catch (InterruptedException e) 
            e.printStackTrace();
        
        graphics = centerJp.getGraphics();
        graphics.setColor(Color.BLUE);
        graphics.drawRect(x, y, rw, rw);
        for (int i = 1; i < 10; i++) 
            //绘制第i条竖直线
            graphics.drawLine(x + (i * w), y, x + (i * w), y + rw);
            //绘制第i条水平线
            graphics.drawLine(x, y + (i * w), x + rw, y + (i * w));
        
    

    @Override
    public void mouseClicked(MouseEvent e) 
        Point pt = new Point(e.getX() - 15, e.getY() - 15);
        if (whiteChess.isSelected()) 
            ChessPieces c1 = chessGameFactory.getChessPieces(Color.white);
            c1.downPieces(graphics, pt, Color.white);
         else if (blackChess.isSelected()) 
            ChessPieces c2 = chessGameFactory.getChessPieces(Color.black);
            c2.downPieces(graphics, pt, Color.black);
        
    

    public static void main(String[] args) 
        new ChessBoard();
    

运行效果

 源码

https://download.csdn.net/download/javanbme/80098289

以上是关于GoF设计模式 - 享元模式的主要内容,如果未能解决你的问题,请参考以下文章

java设计模式 GOF23 11 享元模式

GoF设计模式 - 享元模式

GoF设计模式 - 享元模式

GoF 23 种设计模式之享元模式和组合模式

GOF之享元模式

11-享元(Flyweight)模式Ruby实现