享元模式-----在五子棋游戏中的应用

分析:
五子棋同围棋一样,包含多个“黑”或“白”颜色的棋子,所以用享 元模式比较好。
模式的应用场景
享元模式是通过减少内存中对象的数量来节省内存空间的,所以以 下几种情形适合采用享元模式
系统中存在大量相同或相似的对象,这些对象耗费大量的内存资源。
大部分的对象可以按照内部状态进行分组,且可将不同部分外部化, 这样每一个组只需保存一个内部状 态。
由于享元模式需要额外维护一个保存享元的数据结构,所以应当在有 足够多的享元实例时才值得使用 享元模式。
拓展思路
◼ 享元模式中,其结构图通常包含可以共享的部分和不可以共享的部分。 在实际使用过程中,有时候会稍加改变,即存在两种特殊的享元模式: 单纯享元模式和复合享元模式。
◼ 单纯享元模式:这种享元模式中的所有的具体享元类都是可以共享的,不存 在非共享的具体享元类
◼ 单纯享元模式:这种享元模式中的有些享元对象是由一些单纯享元对象组合 而成的,它们就是复合享元对象。虽然复合享元对象本身不能共享,但它们可 以分解成单纯享元对象再被共享
拓展思路
◼ 单纯享元模式:这种享元模式中的所有的具体享元类都是可以共享的,不存 在非共享的具体享元类
在这里插入图片描述
结构图说明:
本实例中的棋子(ChessPieces)类是抽象享元角色,它包含了一个落子的DownPieces(Graphics g,Point pt) 方 法;白子(WhitePieces)和黑子(BlackPieces)类是具体享元角色,它实现了落子方法;Point 是非享元角色, 它指定了落子的位置;WeiqiFactory 是享元工厂角色,它通过 ArrayList 来管理棋子,并且提供了获取白子或者黑 子的 getChessPieces(String type) 方法;客户类(Chessboard)利用 Graphics 组件在框架窗体中绘制一个棋盘, 并实现 mouseClicked(MouseEvent e) 事件处理方法,该方法根据用户的选择从享元工厂中获取白子或者黑子并 落在棋盘上。
代码
棋子:


import java.awt.Graphics;
import java.awt.Point;

/**
 * 抽象享元角色 棋子
 * @author 17717
 *
 */
public interface ChessPieces {
    
    
	void downPieces(Graphics graphics,Point point);
}

具体的享元角色 白棋:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
/**
 * 具体的享元角色 白棋
 * @author 17717
 *
 */
public class BlackPieces implements ChessPieces{
    
    

	@Override
	public void downPieces(Graphics graphics, Point point) {
    
    
		graphics.setColor(Color.white);//设置颜色
		graphics.fillOval(point.x, point.y, 30, 30);
	}

}

具体的享元角色 黑棋

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
/**
 * 具体的享元角色 黑棋
 * @author 17717
 *
 */
public class WhitePieces implements ChessPieces{
    
    

	@Override
	public void downPieces(Graphics graphics, Point point) {
    
    
		graphics.setColor(Color.black);//设置颜色
		graphics.fillOval(point.x, point.y, 30, 30);
	}

}

享元工厂角色

import java.util.HashMap;
import java.util.Map;

/**
 * 享元工厂角色
 * @author 17717
 *
 */
public class WuziqiFactory {
    
    
	private Map<String,ChessPieces> map=new HashMap<String,ChessPieces>();

public WuziqiFactory() {
    
    
		ChessPieces white=new WhitePieces();
		ChessPieces black=new BlackPieces();
		map.put("white",white);
		map.put("black",black);
	}

	public ChessPieces getChessPieces(String type) {
    
    
		return map.get(type);
	}
}

棋盘


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

public class ChessBoard extends MouseAdapter{
    
    
	private WuziqiFactory factory;
	private JFrame frame;
	private Graphics graphics;
	private JRadioButton wz,bz;
	
	private final int x=50;
	private final int y=50;
	private final int w=40;//小方格的宽度和高度
	private final int rw=600;//棋盘的宽度和高度
	
	public ChessBoard() {
    
    
		this.factory = new WuziqiFactory();
		this.frame =new JFrame("享元模式在五子棋中的应用");
		this.frame.setBounds(100,100,500,500);//设置窗体界限
		this.frame.setResizable(false);
		this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);;
		this.frame.setVisible(true);
		this.frame.setLocationRelativeTo(null);
		//创建按钮组件
		JPanel southJp=new JPanel();
		this.frame.add(BorderLayout.SOUTH,southJp);
		this.wz=new JRadioButton("白子",true);//为真时选中
		this.bz=new JRadioButton("黑子");
		ButtonGroup group=new ButtonGroup();
		group.add(this.wz);
		group.add(this.bz);
		
		southJp.add(this.wz);
		southJp.add(this.bz);
		//创建棋盘组件
		JPanel centerJp=new JPanel();
		centerJp.setLayout(null);
		centerJp.setSize(500,500);
		centerJp.addMouseListener(this);//增加点击事件
		
		this.frame.add(BorderLayout.CENTER,centerJp);
		try {
    
    
		Thread.sleep(5000);
		}catch (Exception e) {
    
    
			System.out.println("");
		}
		
		this.graphics=centerJp.getGraphics();
		this.graphics.setColor(Color.BLUE);
		
		this.graphics.drawRect(x, y, rw, rw);
		for(int i=0;i<10;i++) {
    
    
			//绘制竖线
			graphics.drawLine(x+(i*w), y, x+(i*w), y+rw);
			//横线
			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);
	

		String type="black";
		if(this.wz.isSelected()) {
    
    
			type="white";
		}
		ChessPieces pieces=factory.getChessPieces(type);
		pieces.downPieces(this.graphics, pt);
}
}

测试类


public class App {
    
    
public static void main(String[] args) {
    
    
	new ChessBoard();
}
}

在这里插入图片描述
总结
⚫ Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低 细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象状 态的处理。
⚫ 对象的数量太大从而导致对象内存开销加大——什么样的数量才算大 ?这需要我们仔细的根据具体应用情况进行评估,而不能凭空臆断。

猜你喜欢

转载自blog.csdn.net/BKKBjams/article/details/106531625
今日推荐