【java设计模式】享元模式

参考自:https://blog.csdn.net/justloveyou_/article/details/55045638


存在的意义:面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。享元模式正是为解决这一类问题而诞生的。


 内部状态(Intrinsic State):在享元模式中可以共享的相同内容

外部状态(Extrinsic State):需要外部环境来设置的不能共享的内容

在实际使用中,能够共享的内部状态是有限的,因此享元对象一般都设计为较小的对象,它所包含的内部状态较少,这种对象也称为细粒度对象。 

由于 享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种 对象结构型模式

模式结构:



单纯享元模式:在单纯享元模式中,所有的享元对象都是可以共享的,即所有抽象享元类的子类都可共享,不存在非共享具体享元类。


步骤一:建立一个抽象享元接口

//抽象享元角色类
public interface FlyWeight {
	//一个示意性方法,参数externalState是外蕴状态
    void action(String externalState);
}


步骤二:建立具体享元角色类

//具体享元角色类
public class ConcreteFlyWeight implements FlyWeight {

	//内蕴状态
	private String name;
	
	//构造函数,内蕴状态作为参数传入
	public ConcreteFlyWeight(String name) {
		this.name=name;
	}
	// 外蕴状态 externalState作为参数传入方法中,改变方法的行为,但是并不改变对象的内蕴状态name。
	public void action(String externalState) {
		 System.out.println(" 内蕴状态= " + this.name);
	      System.out.println("外蕴状态 = " + externalState);
		
	}

}

步骤三:建立一个享元工厂

//享元工厂角色类
public class FlyWeightFactory {
   private static final Logger log=LoggerFactory.getLogger(FlyWeightFactory.class);
   
   private static ConcurrentHashMap<String,FlyWeight> allFlyWeight=new ConcurrentHashMap<String,FlyWeight>();
    
   public static FlyWeight getFlyWeight(String name) {
	   if(allFlyWeight.get(name)==null) {
		   synchronized(allFlyWeight) {
			   if(allFlyWeight.get(name)==null) {
				   System.out.println("实例名不存在,执行创建");
				   FlyWeight flyweight=new ConcreteFlyWeight(name);
				   System.out.println("创建完成");
				   allFlyWeight.put(name, flyweight);
			   }
		   }
	   }
	   return allFlyWeight.get(name);
	   
   }
}

步骤四:测试

public class Test {
	
	public static void main(String[] args) {
		 FlyWeightFactory factory=new FlyWeightFactory();
		 //申请三个享元对象A,B,B(但是实际创建只有两个)
	        FlyWeight fly=factory.getFlyWeight("A");
	        fly.action("创建一个对象A");
	       fly=factory.getFlyWeight("B");
	        fly.action("创建一个对象B");
	        fly=factory.getFlyWeight("B");
	        fly.action("创建一个对象B");
	}
       
}


复合享元模式:将一些单纯享元使用组合模式加以组合,可以形成复合享元对象,这样的复合享元对象本身不能共享,但是它们可以分解成单纯享元对象,而后者则可以共享。


步骤一:建立抽象享元接口

//抽象享元角色类
public interface FlyWeight {
	//一个示意性方法,参数externalState是外蕴状态
    void action(String externalState);
}

步骤二:建立单纯具体享元角色类

//具体享元角色类
public class ConcreteFlyWeight implements FlyWeight {

	//内蕴状态
	private String name;
	
	//构造函数,内蕴状态作为参数传入
	public ConcreteFlyWeight(String name) {
		this.name=name;
	}
	// 外蕴状态 externalState作为参数传入方法中,改变方法的行为,但是并不改变对象的内蕴状态name。
	public void action(String externalState) {
		 System.out.println(" 内蕴状态= " + this.name);
	      System.out.println("外蕴状态 = " + externalState);
		
	}

}

步骤二:建立复合具体享元角色类

public class ConcreteCompositeFlyweight implements FlyWeight {

	private Map<String,FlyWeight> map=new HashMap<String,FlyWeight>();
	//增加一个新的单纯享元对象到聚集中
	public void add(String name,FlyWeight fly) {
		map.put(name, fly);
	}
	
	@Override
	public void action(String externalState) {
		 FlyWeight fly = null;
		 for(Object o:map.keySet()) {
			 fly=map.get(o);
			 fly.action("执行-----(外蕴状态)");
		 }
	}
   
}

步骤三:建立享元工厂

//享元工厂角色类
public class FlyWeightFactory {
   
   private static ConcurrentHashMap<String,FlyWeight> allFlyWeight=new ConcurrentHashMap<String,FlyWeight>();
    
   
   //复合享元工厂方法(接收的是一个List集合参数的内蕴状态(键),遍历来get到对应的享元对象)
   
   public FlyWeight getCompositeFlyWeight(List<String> compositestate) {
	   ConcreteCompositeFlyweight compository=new ConcreteCompositeFlyweight();
	   for(String state:compositestate) {
		   compository.add(state, this.getFlyWeight(state));
	   }
	return compository;
	   
   }
   
   
   
   //单纯享元工厂方法
   public static FlyWeight getFlyWeight(String name) {
	   if(allFlyWeight.get(name)==null) {
		   synchronized(allFlyWeight) {
			   if(allFlyWeight.get(name)==null) {
				   System.out.println("实例名不存在,执行创建");
				   FlyWeight flyweight=new ConcreteFlyWeight(name);
				   System.out.println("创建完成");
				   allFlyWeight.put(name, flyweight);
			   }
		   }
	   }
	   return allFlyWeight.get(name);
	   
   }
}

步骤四:测试

public class Test {
	
	public static void main(String[] args) {
		
		List<String> compositestate=new ArrayList<String>();
		compositestate.add("A");
		compositestate.add("B");
		compositestate.add("C");
		compositestate.add("C");
		FlyWeightFactory flyFactory=new FlyWeightFactory();
		FlyWeight compositeFly1= flyFactory.getCompositeFlyWeight(compositestate);
		FlyWeight compositeFly2= flyFactory.getCompositeFlyWeight(compositestate);
		compositeFly1.action("复合享元模式-----");
		System.out.println("----------");
		System.out.println("复合享元对象是否共享对象:"+(compositeFly1==compositeFly2));
		
		String state="hello";
		FlyWeight fly1=flyFactory.getFlyWeight(state);
		FlyWeight fly2=flyFactory.getFlyWeight(state);
		System.out.println("单纯享元对象是否共享对象:"+(fly1==fly2));
		
	}
       
}



猜你喜欢

转载自blog.csdn.net/sinat_35821285/article/details/80108288