设计模式 -- 享元模式

版权声明:本文为博主原创文章,欢迎转载! https://blog.csdn.net/qq_36336332/article/details/79469883
1、使用场景:内存属于稀缺资源,不能随意浪费,如果有多个完全相同或相似的对象,我们可以通过享元模式来节省内存。

   1)、线程池、数据库连接池

   2)、String类的设计,""-字符串池。

2、核心:以共享的方式高效地支持大量细粒度对象的重用。

3、关键细节 --> 区分内部状态和外部状态:

   1)、内部状态:可以共享,不会随环境变化而变化。

   2)、外部状态:不可以共享,会随环境变化而变化(可以作为参数传进来)。

4、实现细节:

   1)、享元工厂:创建并管理享元对象,享元池一般设计成键值对。

   2)、享元抽象类:通常由一个接口或抽象类,声明公共方法,这些方法可以向外界提供对象的内部状态,设置外部状态。

   3)、享元具体类:为内部状态提供成员变量进行存储。

   4)、非共享享元类:为外部状态提供设计的类。

5、优点:

   1)、极大减少内存中对象的数量。

   2)、相同或相似对象中只存一份,极大节省资源,提高系统性能。

   3)、外部状态相对独立,不影响内部状态。

6、缺点:

   1)、模式比较复杂,是程序逻辑复杂化。

   2)、节省内存,将外部状态分离,而读取外部状态使程序运行时间变长,用时间换取空间。
代码如下:
package com.linjitai.flyweight;
/**
 * 享元抽象类
 * @author tiger
 * @author 2018年3月7日
 */
public interface CHess {
	void setColor(String color);
	String getColor();
	void display(Coordinate coordinate);
}

package com.linjitai.flyweight;
/**
 * 享元具体类
 * @author tiger
 * @author 2018年3月7日
 */
public class CHessImpl implements CHess {
	private String color;
	@Override
	public void setColor(String color) {
		this.color = color;
	}

	@Override
	public String getColor() {
		return color;
	}
	
	@Override
	public void display(Coordinate coordinate) {
		System.out.println("棋子颜色:" + color + ";位置:(" + coordinate.getX() + ":" + coordinate.getY() + ")");
	}
}

package com.linjitai.flyweight;
/**
 * 非共享享元类
 * @author tiger
 * @author 2018年3月7日
 */
public class Coordinate {
	private int x,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;
	}
	public Coordinate(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	public Coordinate() {
		super();
	}
	@Override
	public String toString() {
		return "Coordinate [x=" + x + ", y=" + y + "]";
	}
}
package com.linjitai.flyweight;

import java.util.HashMap;
import java.util.Map;
/**
 * 享元工厂
 * @author tiger
 * @author 2018年3月7日
 */
public class ChessFactory {
	//享元池
	private static Map<String, CHess> map = new HashMap<>();
	
	public static CHess getChess(String color) {
		if (map.get(color) != null) {
			return map.get(color);
		}else {
			CHess chess = new CHessImpl();
			chess.setColor(color);
			map.put(color, chess);
			return chess;
		}
	}
}

package com.linjitai.flyweight;
/**
 * 测试
 * @author tiger
 * @author 2018年3月7日
 */
public class Main {
	public static void main(String[] args) {
		CHess chess = ChessFactory.getChess("白色");
		CHess chess2 = ChessFactory.getChess("白色");
		//打印结果显示chess和chess2为同一个对象,验证了此为内部共享对象
		System.out.println(chess);
		System.out.println(chess2);
		//添加外部状态,棋子位置不同
		chess.display(new Coordinate(12, 34));
		chess2.display(new Coordinate(22, 24));
	}
}
输出结果如下:
com.linjitai.flyweight.CHessImpl@41975e01
com.linjitai.flyweight.CHessImpl@41975e01
棋子颜色:白色;位置:(12:34)
棋子颜色:白色;位置:(22:24)


猜你喜欢

转载自blog.csdn.net/qq_36336332/article/details/79469883
今日推荐