项目多也别傻做----享元模式

享元模式 :

运用共享技术有效的支持大量细粒度的对象。
动机:在软件系统采用纯粹对象方案(一切皆对象)的问题在于大量细粒度的对象会很快充斥再系统中,从而带来很高的运行时代价---------主要指内存需求方面的代价。

问题的引入----创建网站简单代码

网站类

public class WebSite {

	private String name = "";

	public WebSite(String name) {
		this.name = name;
	}

	public void Use() {
		System.out.println("网站分类:" + name);
	}
}

客户端代码

public class Main {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根

		WebSite fx=new WebSite("产品展示");fx.Use();
		WebSite fy=new WebSite("产品展示");fy.Use();
		WebSite fz=new WebSite("产品展示");fz.Use();
		WebSite fl=new WebSite("博客");fl.Use();
		WebSite fm=new WebSite("博客");fm.Use();
		WebSite fn=new WebSite("博客");fn.Use();
	}

}

简单代码的问题

其实它们本质上都是一样的代码,如果网站增多,实例也随之增多,对服务器造成资源浪费。
解决方法:1.网站公用一套代码。–但不同的网站数据不同,否定。
2.利用用户ID不同来区分不同的用户,各个小网站的具体数据和模板可以不同,但核心代码和数据库却是共享的。

内部状态和外部状态

享元对象能做到共享的关键是区分内部状态的外部状态。
内部状态是存储在享元对象内部并且不会随环境改变而改变。因此内部状态可以共享。
外部状态是随环境改变而改变的、不可共享的状态。享元对象的外部状态必须由客户端保存,并在享元对象被创建后,再需要使用的时候再传入到享元对象内部。
外部状态和内部状态是相互独立的。

享元模式结构图

在这里插入图片描述在这里插入图片描述在这里插入图片描述

享元模式具体代码

Flyweight工厂

public abstract class Flyweight {
//是所有具体享元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态
	public String intrinsic;//内部状态
	protected final String extrinsic;//外部状态
	//要求享元角色必须接受外部状态
	public Flyweight(String extrinsic) {
		this.extrinsic=extrinsic;
	}
	public abstract void operate(int ectrinsic) ;//定义业务操作
	public String getIntrinsic() {
		return intrinsic;
	}
	public void setIntrinsic(String intrinsic) {
		this.intrinsic=intrinsic;
	}
}

共享的和不共享的

public class ConcreteFlyweight extends Flyweight{

	public ConcreteFlyweight(String extrinsic) {
		super(extrinsic);
		// TODO 自动生成的构造函数存根
	}

	public void operate(int extrinsic) {
		System.out.println("具体Flyweight:"+extrinsic);
	}
}

public class UnsharedConcentrateFlyweight extends Flyweight{

	public UnsharedConcentrateFlyweight(String extrinsic) {
		super(extrinsic);
		// TODO 自动生成的构造函数存根
	}

	public void operate(int extrinsic) {
		System.out.println("不共享的具体Flyweight:"+extrinsic);
	}
}

享元工厂
在这里插入图片描述

import java.util.HashMap;

public class FlyweightFactory {

	//定义一个池容器
	private static HashMap<String,Flyweight> pool=new HashMap<String ,Flyweight>();
	
	public static Flyweight getFlyweight(String extrinsic) {
		Flyweight flyweight=null;
		if(pool.containsKey(extrinsic)) {//池中有该对象
			flyweight=pool.get(extrinsic);
			System.out.println("已有"+extrinsic+"直接从池中取---->");
		}else {//根据外部状态创建享元对象
			flyweight=new ConcreteFlyweight(extrinsic);//放入池中
			System.out.println("创建"+extrinsic+"并从池中取出--->");
		}
		return flyweight;
	}
}

客户端代码

public class Main {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
			
		int extrinsic=22;
		FlyweightFactory f=new FlyweightFactory();
		Flyweight flyweightX=f.getFlyweight("X");
		flyweightX.operate(--extrinsic);
		Flyweight flyweightY=f.getFlyweight("Y");
		flyweightX.operate(--extrinsic);
		Flyweight flyweightZ=f.getFlyweight("Z");
		flyweightX.operate(--extrinsic);
		Flyweight flyweightReX=f.getFlyweight("X");
		flyweightX.operate(--extrinsic);
		Flyweight unsharedFlyweight=new UnsharedConcentrateFlyweight("X");
		unsharedFlyweight.operate(--extrinsic);
	}

}

结果在这里插入图片描述

网站共享代码(无外部状态的享元模式)

public abstract class WebSite1 {

	public abstract void Use();
}

public class ConcreteWebSite extends WebSite1{

	private String name="";
	public ConcreteWebSite(String name) {
		this.name = name;
	}
	@Override
	public void Use() {
		// TODO 自动生成的方法存根
		System.out.println("网站分类:"+name);
	}

}
import java.util.HashMap;

public class WebSiteFactory {

	//定义一个池容器

	private static HashMap<String,WebSite1> flyweights=new HashMap<String ,WebSite1>();
	//获得网站分类
	public WebSite1 GetWebSiteCategory(String key) {
		if(!flyweights.containsKey(key)) {
			WebSite1 flyweight=new ConcreteWebSite(key);
			flyweights.put(key, flyweight);
		}
		return flyweights.get(key);
	}
	
	public int GetWebSiteCount() {
		return flyweights.size();
	}
}

public class Main {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根

		WebSiteFactory f=new WebSiteFactory();
		
		WebSite1 fx=f.GetWebSiteCategory("产品展示");fx.Use();
		WebSite1 fy=f.GetWebSiteCategory("产品展示");fy.Use();
		WebSite1 fz=f.GetWebSiteCategory("产品展示");fz.Use();
		WebSite1 fl=f.GetWebSiteCategory("博客");fl.Use();
		WebSite1 fm=f.GetWebSiteCategory("博客");fm.Use();
		WebSite1 fn=f.GetWebSiteCategory("博客");fn.Use();
		System.out.println("网站分类总数为"+f.GetWebSiteCount());
	}

}

在这里插入图片描述
实际上这样写没有体现对象间的不同。
在网站的例子中,客户账号就是外部状态,应该由专门的对象来处理。

带外部状态的网站共享代码

public class User {

	private String name;

	public User(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}

public abstract class WebSite2 {

	public abstract void Use(User user);
}

//具体网站类
public class ConcreteWebSite1 extends WebSite2{

	private String name="";
	public ConcreteWebSite1(String name) {
		this.name = name;
	}
	@Override
	public void Use(User user) {
		// TODO 自动生成的方法存根
		System.out.println("网站分类:"+name+"用户:"+user.getName());
	}

}

import java.util.HashMap;

public class WebSiteFactory1 {

	//定义一个池容器

	private static HashMap<String,WebSite2> flyweights=new HashMap<String ,WebSite2>();
	//获得网站分类
	public WebSite2 GetWebSiteCategory(String key) {
		if(!flyweights.containsKey(key)) {
			WebSite2 flyweight=new ConcreteWebSite1(key);
			flyweights.put(key, flyweight);
		}
		return flyweights.get(key);
	}
	
	public int GetWebSiteCount() {
		return flyweights.size();
	}
}
public class Main {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根

		WebSiteFactory1 f=new WebSiteFactory1();
		WebSite2 fx=f.GetWebSiteCategory("产品展示");fx.Use(new User("小菜"));
		WebSite2 fy=f.GetWebSiteCategory("产品展示");fy.Use(new User("大鸟"));
		WebSite2 fz=f.GetWebSiteCategory("博客");fz.Use(new User("娇娇"));
		System.out.println("网站分类总数为"+f.GetWebSiteCount());
	}

}

在这里插入图片描述

享元模式的优缺点

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值