关于享元模式的文章网上很多,但大多数案例都只能够共享一种数据类型,也就是在工厂中去实例化了具体的数据类型。
个人认为这在实际开发中不够灵活通用,故根据个人理解借助反射实现了动态的类型共享。当然本人的例子也会存在很多问题,所以该案例只供读者参考,不喜勿喷,谢谢!
介绍:案例以棋子作为测试对象,将棋子的坐标、颜色充当外部状态,大小充当内部状态。
1.棋子坐标类
package com.advance.pattern.flyweight;
/**
* 坐标类,外部状态
* @author raoyu
*
*/
public class Coordinate {
private float x;
private float y;
public Coordinate() {
// TODO Auto-generated constructor stub
}
public Coordinate(float x, float y) {
super();
this.x = x;
this.y = y;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
}
2.棋子颜色类
package com.advance.pattern.flyweight;
/**
* 颜色类
* @author raoyu
*
*/
public class Color {
private String name;
public Color() {
// TODO Auto-generated constructor stub
}
public Color(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.棋子类
package com.advance.pattern.flyweight;
/**
* 棋子内部状态
* @author raoyu
*
*/
public class ChessFlyweight {
private int size;
private Coordinate coordinate;
private Color color;
public ChessFlyweight() {
// TODO Auto-generated constructor stub
}
public ChessFlyweight(int size) {
super();
this.size = size;
}
public ChessFlyweight(int size, Coordinate coordinate, Color color) {
super();
this.size = size;
this.coordinate = coordinate;
this.color = color;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public Coordinate getCoordinate() {
return coordinate;
}
public void setCoordinate(Coordinate coordinate) {
this.coordinate = coordinate;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
4.工厂类
package com.advance.pattern.flyweight;
import java.util.HashMap;
import java.util.Map;
/**
* 在此工厂中放置所有共享类的对象
*
* @author raoyu
*
*/
public class FlyWeightFactory {
// 单例模式
private static FlyWeightFactory factory = new FlyWeightFactory();
private FlyWeightFactory() {
}
public static FlyWeightFactory getInstance() {
return factory;
}
private Map<String, Object> data = new HashMap<>();
/**
* 类似于Spring的自动注入,通过编译时期减少错误
*
* @param claszz
* @return
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public Object getObject(Class<?> claszz)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
String className = claszz.getName();
if (data.get(className) == null) {
// 反射构造对象
Object object = Class.forName(className).newInstance();
addFlyweightObj(object);
return object;
}
return data.get(className);
}
public void addFlyweightObj(Object object) {
data.put(object.getClass().getName(), object);
}
}
5.测试类
package com.advance.pattern.flyweight;
public class Client {
//使七个对象减少到三个对象
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//享元工厂(单例模式)
FlyWeightFactory factory = FlyWeightFactory.getInstance();
//创建黑色棋子
ChessFlyweight blackChess = (ChessFlyweight) factory.getObject(ChessFlyweight.class);
//白色棋子享元
ChessFlyweight whiteChess = (ChessFlyweight) factory.getObject(ChessFlyweight.class);
//创建黑色
Color color = (Color) factory.getObject(Color.class);
//创建坐标对象
Coordinate coordinate = (Coordinate) factory.getObject(Coordinate.class);
coordinate.setX(10);
coordinate.setY(10);
color.setName("黑色");
blackChess.setColor(color);
blackChess.setCoordinate(coordinate);
color.setName("白色");
coordinate.setX(20);
coordinate.setY(20);
whiteChess.setColor(color);
whiteChess.setCoordinate(coordinate);
System.out.println(blackChess +"\n"+whiteChess);
System.out.println(blackChess.getCoordinate() +"\n"+whiteChess.getCoordinate());
}
}
6.运行截图