zoukankan      html  css  js  c++  java
  • FlyweightPattern(23种设计模式之一)


    设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大原则(6):开闭原则

    参考书籍:设计模式-可复用面向对象软件基础(黑皮书)

    享元模式,以共享的方式高效地支持大量的细粒度对象。通过复用内存中已存在的对象,降低系统创建对象实例的性能消耗。

    简单的典型实例:以黑白五子棋对弈为例,获取每个棋子的状态,然而我们不可能为每个棋子都建立一个对象,这样内存开销太大,这样关键就在于抽象出每个棋子的内部状态和外部状态,将其的状态分离。

    FlyweightPattern,UML抽象图百度找,代码实现如下

    使用享元模式设计以黑白五子棋对弈

    抽象细粒度对象类

    package FlyweightPattern;
    public abstract class Chessman {
    	private String color;
    	private int x;
    	private int y;
    	public Chessman(String color){
    		this.color = color;
    	}
    	public void setPosition(int x,int y){
    		this.x = x;
    		this.y = y;
    	}
    	public String getColor(){
    		return color;
    	}
    	public int getX(){
    		return x;
    	}
    	public int getY(){
    		return y;
    	}
    }
    

    细粒度具体对象类

    package FlyweightPattern;
    public class BlackChessman extends Chessman {
    	public BlackChessman() {
    		super("黑棋子");
    		System.out.println("创建黑棋子");
    	}
    }
    
    package FlyweightPattern;
    public class WhiteChessman extends Chessman {
    	public WhiteChessman() {
    		super("白棋子");
    		System.out.println("创建白棋子");
    	}
    }
    

    粒度工厂类

    package FlyweightPattern;
    import java.util.Hashtable;
    public class ChessmanFactory {
    	private static ChessmanFactory chessmanFactory = new ChessmanFactory();
    	//缓存存放共享对象
    	Hashtable<Character,Chessman> cache = new Hashtable<Character,Chessman>();
    	public static ChessmanFactory getInstance(){
    		return chessmanFactory;
    	}
    	//获取棋子
    	public Chessman getChessman(char c){
    		Chessman chessman = this.cache.get(c);
    		if(chessman==null){
    			if(c=='W'){
    				chessman = new WhiteChessman();
    			}else if(c=='B'){
    				chessman = new BlackChessman();
    			}
    			cache.put(c, chessman);
    		}
    		return chessman;
    	}
    }
    

    测试类

    package FlyweightPattern;
    public class Test {
    	public static void main(String[] args) {
    		ChessmanFactory factory=ChessmanFactory.getInstance();
    		Chessman chessman1=factory.getChessman('W');
    		chessman1.setPosition(1, 1);
    		System.out.println(chessman1.getColor()+" ("+chessman1.getX()+","+chessman1.getY()+")");
    		Chessman chessman2=factory.getChessman('W');
    		chessman2.setPosition(2, 2);
    		System.out.println(chessman2.getColor()+" ("+chessman2.getX()+","+chessman2.getY()+")");
    		Chessman chessman3=factory.getChessman('B');
    		chessman3.setPosition(3, 3);
    		System.out.println(chessman3.getColor()+" ("+chessman3.getX()+","+chessman3.getY()+")");
    		Chessman chessman4=factory.getChessman('B');
    		chessman4.setPosition(4, 4);
    		System.out.println(chessman4.getColor()+" ("+chessman4.getX()+","+chessman4.getY()+")");
    	}
    }
    

    享元模式的两种状态:内蕴状态和外蕴状态
    1.内蕴状态(内部状态):
    享元模式的内蕴状态是不会随环境的改变而改变的,是存储在享元对象内部的状态信息,因此内蕴状态是可以共享的,对于任何一个享元对象来讲,它的值是完全相同的。就像上面例子中的“黑子”和“白子”,它代表的状态就是内蕴状态。
    2.外蕴状态(外部状态)
    外蕴状态会随环境的变化而改变的,因此是不可共享的状态,对于不同的享元对象来讲,它的值可能是不同的。享元对象的外蕴状态必须由客户端保存,在享元对象被创建之后,需要使用的时候再传入到享元对象的内部。就像五子棋的位置信息,代表的状态就是享元对象的外蕴状态。


    享元模式关键就在内部状态与外部状态的分离,在这里,场景就是棋盘,棋子的坐标就是外部状态(不可共享),棋子的颜色就是独立于场景的内部状态(可被共享),用户对象负责在有必要的时候将外部状态传递给享元


  • 相关阅读:
    uva 408 Uniform Generator
    Java实现 蓝桥杯VIP 算法提高 栅格打印问题
    Java实现 蓝桥杯VIP 算法提高 栅格打印问题
    Java实现 蓝桥杯VIP 算法提高 栅格打印问题
    Java实现 蓝桥杯VIP 算法提高 打水问题
    Java实现 蓝桥杯VIP 算法提高 打水问题
    Java实现 蓝桥杯VIP 算法提高 打水问题
    Java实现 蓝桥杯VIP 算法提高 打水问题
    Java实现 蓝桥杯VIP 算法提高 不同单词个数统计
    Java实现 蓝桥杯VIP 算法提高 不同单词个数统计
  • 原文地址:https://www.cnblogs.com/1996jiwei/p/6700319.html
Copyright © 2011-2022 走看看