zoukankan      html  css  js  c++  java
  • 设计模式——享元模式

    享元模式: 场景:内存属于稀缺资源,如果有很多个完全相同或相似的对象,我们可以通过享元模式来节省内存。

          核心:享元模式以共享的方式高效地支持大量细粒度对象的重用。 享元对象能做到共享的关键字是区分了内部状态和外部状态。

          内部状态:可以共享,不会随着环境变化而改变。

          外部状态:不可以共享,会随着环境变化而改变。

    享元模式的实现:

          1.FlyweightFactory享元工厂类:创建并管理享元对象,享元池一般设计成键值对

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

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

          4.UnsharedConcreteFlyWeight非共享享元类:不能被共享的子类可以设计成为非共享享元类。

    应用场景:线程池、数据库连接池、String类的设计。

    优点:极大的减少内存中对象的数量。相同或相似的对象内存中只有一份,一个实例可以提供许多虚拟实例,极大的节约资源,提高系统的性能。      

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

    缺点:模式较复杂。使程序的逻辑复杂化,每次读取外部状态使运行时间变长,用时间换取了空间。      

             一旦实现了享元模式,单个逻辑实例将无法拥有独立的行为。

    看一个简单明了的Demo:

    /**
     * 享元类
     * @author wxisme
     *
     */
    public interface FlyWeight {
    	void setSex(String sex);
    	String getSex();
    	void display(Character c);
    
    }
    /**
     * 具体享元类  获取内部状态、设置外部状态
     * @author wxisme
     *
     */
    
    class HumanFlyWeight implements FlyWeight {
    	private String sex;
    
    	
    	public HumanFlyWeight(String sex) {
    		super();
    		this.sex = sex;
    	}
    
    	@Override
    	public void setSex(String sex) {
    		this.sex = sex;
    	}
    
    	@Override
    	public String getSex() {
    		return sex;
    	}
    
    	@Override
    	public void display(Character c) {
    		System.out.println(c.getCharacter() + "的" + sex + "。");
    	}
    	
    }
    
    
    
    /**
     * 外部状态
     * @author wxisme
     *
     */
    public class Character {
    	private String character;
    
    	
    	public Character(String character) {
    		super();
    		this.character = character;
    	}
    
    	public String getCharacter() {
    		return character;
    	}
    
    	public void setCharacter(String character) {
    		this.character = character;
    	}
    	
    	
    
    }
    
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 享元工厂类
     * @author wxisme
     *
     */
    
    public class HumanFlyWeightFactory {
    	static Map<String, FlyWeight> map = new HashMap<>();
    	
    	public static FlyWeight getHuman(String sex) {
    		if(map.get(sex) != null) {
    			return map.get(sex);
    		}
    		else {
    			FlyWeight h = new HumanFlyWeight(sex);
    			map.put(sex, h);
    			return h;
    		}
    		
    	}
    
    }
    
    
    public class Client {
    	public static void main(String[] args) {
    		HumanFlyWeightFactory factory = new HumanFlyWeightFactory();
    		//实质是共享相同的内部状态,封装变化的外部状态,节省资源。
    		FlyWeight flyweight1 = factory.getHuman("女人");
    		FlyWeight flyweight2 = factory.getHuman("女人");
    		//两个只包含相同内部状态的对象其实是一个对象。
    		System.out.println(flyweight1);
    		System.out.println(flyweight2);
    		//设置变化的外部状态。
    		flyweight1.display(new Character("性感"));
    		flyweight2.display(new Character("漂亮"));
    
    		
    	}
    }
    

     运行结果:

    com.wxisme.flyweight.HumanFlyWeight@1fe3ee3
    com.wxisme.flyweight.HumanFlyWeight@1fe3ee3
    性感的女人。
    漂亮的女人。

  • 相关阅读:
    Java人员正确使用 IntelliJ IDEA的方式
    python错误:UnicodeDecodeError: 'utf8' codec can't decode byte 0xe6 in position 0: unexpected end of data
    htm5本地存储方案——websql的封装
    htm5本地存储方案——indexdb的封装
    jquery实现checkbox的单选和全选
    Live2d Test Env
    Live2d Test Env
    Live2d Test Env
    Live2d Test Env
    Live2d Test Env
  • 原文地址:https://www.cnblogs.com/wxisme/p/4549858.html
Copyright © 2011-2022 走看看