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.外蕴状态(外部状态)
    外蕴状态会随环境的变化而改变的,因此是不可共享的状态,对于不同的享元对象来讲,它的值可能是不同的。享元对象的外蕴状态必须由客户端保存,在享元对象被创建之后,需要使用的时候再传入到享元对象的内部。就像五子棋的位置信息,代表的状态就是享元对象的外蕴状态。


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


  • 相关阅读:
    彻底弄懂flex布局
    剖析Vue原理&实现双向绑定MVVM
    【Mysql进阶-3】大量实例悟透EXPLAIN与慢查询
    mysql 排序
    从ReentrantLock的实现看AQS的原理及应用
    Java面试之Synchronized解析
    基于vue-cli搭建vue项目开发环境
    在win环境下使用yarn安装 vue-cli
    优化器追踪示例
    MySQL常见的七种锁详细介绍
  • 原文地址:https://www.cnblogs.com/1996jiwei/p/6700319.html
Copyright © 2011-2022 走看看