爱游戏全站app官网入口-爱游戏官网

[工作中的设计模式]享元模式模式flyweight -爱游戏全站app官网入口

2023-08-15,,

一、模式解析

flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意。享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象。

享元模式:主要为了在创建对象时,对共有对象以缓存的方式进行保存,对外部对象进行单独创建

模式要点:

1、享元模式中的对象分为两部分:共性部分和个性化部分,共性部分就是每个对象都一致的或者多个对象可以共享的部分,个性化部分指差异比较大,每个类均不同的部分

2、共性部分的抽象就是此模式介绍的享元对象

3、享元对象一般通过一个享元工厂进行创建和保存

4、享元工厂根据享元对象的多少,实现一个单例或者多例模式,来创建享元对象

5、享元对象可以预先设定好在享元工厂里,也可以创建一个集合,每次创建对象时,查看享元对象是否存在,不存在则进行添加

二、模式代码

1、创建享元接口

package flyweight.patten;
//享元接口
public interface flyweight { public void opertion();
}

2、创建具体享元类

package flyweight.patten;
public class concreteflyweight implements flyweight {
public string name;
public concreteflyweight(string name){
this.name=name;
}
@override
public void opertion() {
system.out.println("执行享元类");
}
}

3、创建享元工厂

package flyweight.patten;
import java.util.hashmap;
import java.util.map; //享元工厂,为客户端提供享元类
public class flyweightfactory { //使用内部map,保证享元对象只被创建一次
private map map=new hashmap(); public flyweight getflyweight(string name){
flyweight flyweight=map.get(name);
if(map.get(name)==null||map.get(name).equals("")){
flyweight=new concreteflyweight(name);
map.put(name, flyweight);
}
return flyweight;
} }

5、客户端

package flyweight.patten;
public class client {
public static void main(string[] args) {
flyweightfactory factory=new flyweightfactory();
flyweight flyweight1=factory.getflyweight("张三");
flyweight flyweight2=factory.getflyweight("李四");
flyweight flyweight3=factory.getflyweight("张三");
system.out.println(flyweight1==flyweight2);
system.out.println(flyweight1==flyweight3);
}
}

6、执行结果,可以看到,如果姓名相同,每次引用的享元对象都是一样的,符合多例模式

false
true

注:此模式的标准代码为单纯的享元模式,并不完全符合我们上边的模式要点,因为他创建的对象参数全部为享元内容,所以我们在后边的实例中编写一个完全的享元模式代码。

三、应用场景

享元模式的应用比较广泛,类似与数据库的外键关联关系,所以我们以工作中最常见的银行卡举例:

  客户账户属性分为:银行卡种类,银行卡名称,银行卡号,余额,客户姓名等因素。在创建卡对象时候,由于卡种类和名称对于每个银行仅有几种,所以创建一个享元对象进行保存。

四、模式代码

1、创建银行卡类,也就是享元对象

package flyweight.example;
/**
* 卡类型
* @author lenovo
*
*/
public class card {
private string cardtype;
private string cardname;
public string getcardname() {
return cardname;
} public void setcardname(string cardname) {
this.cardname = cardname;
} public string getcardtype() {
return cardtype;
} public void setcardtype(string cardtype) {
this.cardtype = cardtype;
}
public card(string cardtype,string cardname){
this.cardtype=cardtype;
this.cardname=cardname;
} @override
public string tostring() {
return "cardtype [cardtype=" cardtype ", cardname=" cardname "]";
} }

2、创建账户接口

package flyweight.example;
/**
* 账户接口
* @author lenovo
*
*/
public interface countinterface {
/**
* 显示卡内容
*/
public void show() ;
}

3、创建账户类

package flyweight.example;
import java.math.bigdecimal;
/**
* 具体账户属性
* @author lenovo
*
*/
public class concretecount implements countinterface {
private string cardno;
private bigdecimal balance;
private card card;
/**
* 根据参数创建用户对象
* @param cardno
* @param balance
* @param cardtype
*/
public concretecount(string cardno, bigdecimal balance, card card) {
this.cardno = cardno;
this.balance = balance;
this.card = card;
} @override
public string tostring() {
return "concretecount [cardno=" cardno ", balance=" balance ", card=" card "]";
} @override
public void show() {
system.out.println(this.tostring()); } }

5、创建享元工厂,享元工厂返回客户账户实例,在创建客户账户时,首先判断卡属性是否存在,存在就直接从享元对象中获取卡属性,否则创建新的卡

package flyweight.example;
import java.math.bigdecimal;
import java.util.hashmap;
import java.util.map; /**
* 享元工厂,主要用于创建对象
* @author lenovo
*
*/
public class countfactory {
//保存享元对象的map
map cardtypemap=new hashmap(); public concretecount getconcretecount(string cardno, bigdecimal balance,string cardtype,string cardname){ card card=null;
//判断享元对象是否已经存在,如果存在则使用,不存在则额外创建
if(cardtypemap.get(cardtype cardname)!=null){
card=cardtypemap.get(cardtype cardname);
}else {
card=new card(cardtype, cardname);
cardtypemap.put(cardtype cardname, card);
} return new concretecount(cardno, balance, card); }
}

5、客户端

package flyweight.example;
import java.math.bigdecimal;
public class cardtest {
    /**
* 测试享元模式
* @param args
*/
public static void main(string[] args) {
countfactory factory=new countfactory();
concretecount count=factory.getconcretecount("001", new bigdecimal(100), "1", "信用卡");
concretecount count2=factory.getconcretecount("002", new bigdecimal(200), "2", "借记卡");
concretecount count3=factory.getconcretecount("003", new bigdecimal(300), "1", "信用卡");
concretecount count4=factory.getconcretecount("004", new bigdecimal(400), "2", "借记卡"); count.show();
count2.show();
count3.show();
count4.show(); } }

6、结果

concretecount [cardno=001, balance=100, card=cardtype [cardtype=1, cardname=信用卡]]
concretecount [cardno=002, balance=200, card=cardtype [cardtype=2, cardname=借记卡]]
concretecount [cardno=003, balance=300, card=cardtype [cardtype=1, cardname=信用卡]]
concretecount [cardno=004, balance=400, card=cardtype [cardtype=2, cardname=借记卡]]

五、解析

如同第三部分所说,享元模式大都是以数据库外键形式体现在系统中,所以在系统中使用享元思想的很多,但是使用享元对象标准模式写法的还是比较少,所以模式还是要注重思想。

[工作中的设计模式]享元模式模式flyweight的相关教程结束。

网站地图