Java享元模式(动态享元)

本文介绍了一种使用享元模式的实现方法,通过反射技术来动态地共享不同类型的数据,提高灵活性。以棋子为示例,展示了如何将坐标、颜色设置为外部状态,而大小则作为内部状态,并通过工厂类进行对象的管理。

关于享元模式的文章网上很多,但大多数案例都只能够共享一种数据类型,也就是在工厂中去实例化了具体的数据类型。

个人认为这在实际开发中不够灵活通用,故根据个人理解借助反射实现了动态的类型共享。当然本人的例子也会存在很多问题,所以该案例只供读者参考,不喜勿喷,谢谢!

介绍:案例以棋子作为测试对象,将棋子的坐标、颜色充当外部状态,大小充当内部状态。

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.运行截图


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值