享元模式

享元模式

一、概述

  1. 内存属于稀缺资源,不要随便浪费。如果有很多个完全相同或相似的 对象,我们可以通过享元模式,节省内存。
  2. 享元模式以共享的方式高效地支持大量细粒度对象的重用。
  3. 享元对象能做到共享的关键是区分了内部状态和外部状态。
    • 内部状态:可以共享,不会随环境变化而改变
    • 外部状态:不可以共享,会随环境变化而改变
  4. 应用场景
    围棋软件设计,每个围棋棋子都是一个对象, 有颜色、形状、大小等属性是可以共享的,称之为内部状态。比如位置属性不可以共享,可以称之为外部状态
  5. 享元模式构成
    • FlyweightFactory享元工厂类:创建并管理享元对象,享元池一般设计成键值对
    • FlyWeight抽象享元类 :通常是一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置外部状态。
    • ConcreteFlyWeight具体享元类 :为内部状态提供成员变量进行存储
    • UnsharedConcreteFlyWeight非共享享元类 :不能被共享的子类可以设计为非共享享元类

二、代码围棋

  1. 享元接口

    public interface ChessFlyWeight {
    	void setColor(String c);
    	String getColor();
    	void display(Coordinate c);
    }
    
  2. 具体享元类

    class ConcreteChess implements ChessFlyWeight {
    
    	private String color;
    	
    	public ConcreteChess(String color) {
    		super();
    		this.color = color;
    	}
    
    	@Override
    	public void display(Coordinate c) {
    		System.out.println("棋子颜色:"+color);
    		System.out.println("棋子位置:"+c.getX()+"----"+c.getY());
    	}
    
    	@Override
    	public String getColor() {
    		return color;
    	}
    
    	@Override
    	public void setColor(String c) {
    		this.color = c;
    	}
    }
    
  3. 非共享元类

    public class Coordinate {
    	private int x,y;
    
    	public Coordinate(int x, int y) {
    		super();
    		this.x = x;
    		this.y = y;
    	}
    
    	public int getX() {
    		return x;
    	}
    
    	public void setX(int x) {
    		this.x = x;
    	}
    
    	public int getY() {
    		return y;
    	}
    
    	public void setY(int y) {
    		this.y = y;
    	}
    	
    }
    
  4. 享元工厂

    public class ChessFlyWeightFactory {
    	//享元池
    	private static Map<String,ChessFlyWeight> map = new HashMap<String, ChessFlyWeight>();
    	
    	public static ChessFlyWeight  getChess(String color){
    		
    		if(map.get(color)!=null){
    			return map.get(color);
    		}else{
    			ChessFlyWeight cfw = new ConcreteChess(color);
    			map.put(color, cfw);
    			return cfw;
    		}
    		
    	}
    }
    
    
  5. 测试类

    public class Client {
    	public static void main(String[] args) {
    		ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("黑色");
    		ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("黑色");
    		System.out.println(chess1);
    		System.out.println(chess2);
    		
    		System.out.println("增加外部状态的处理===========");
    		chess1.display(new Coordinate(10, 10));
    		chess2.display(new Coordinate(20, 20));
    		
    		
    	}
    }
    
    

享元模式