两种语言实现设计模式(C++和Java)(十一:享元模式)

享元模式指通过共享的技术来支持大量细粒度对象的复用,它通过共享已经存在的又橡来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。例如围棋和五子棋中的黑白棋子,图像中的坐标点或颜色,局域网中的路由器、交换机和集线器,教室里的桌子和凳子等。这些对象有很多相似的地方,如果能把它们相同的部分提取出来共享,则能节省大量的系统资源,这就是享元模式的产生背景。

如何解决:用唯一标识码判断,如果内存中有,则返回这个唯一标识码所标识的对象。

关键代码:将内部状态作为标识,进行共享。

以下是享元模式的UML:

两种语言实现设计模式(C++和Java)(十一:享元模式)

图中的 UnsharedConcreteFlyweight 是与享元角色,里面包含了非共享的外部状态信息 info;而 Flyweight 是抽象享元角色,里面包含了享元方法 operation(UnsharedConcreteFlyweight state),非享元的外部状态以参数的形式通过该方法传入;ConcreteFlyweight 是具体享元角色,包含了关键字 key,它实现了抽象享元接口;FlyweightFactory 是享元工厂角色,它逝关键字 key 来管理具体享元;客户角色通过享元工厂获取具体享元,并访问具体享元的相关方法。

以在银行中存钱为例,支票和硬币都是货币,具有相同价值的面值,可以作为Money这一抽象享元角色的实现,而设置MoneyCoin和MoneyNote作为具体享元角色。银行可以作为享元工厂类供用户存取金钱。

 

C++实现:

  1 #include <iostream>
  2 #include <vector>
  3 
  4 using namespace std;
  5 
  6 //货币类型,作为享元对象标识Key
  7 enum MoneyCategory{
  8     Coin,
  9     BankNote
 10 };
 11 
 12 //面值,外部标识,需要储存的对象
 13 enum FaceValue{
 14     ValueOne = 1,
 15     ValueTen = 10
 16 };
 17 
 18 //抽象享元角色
 19 class Money{
 20 public:
 21     Money(MoneyCategory _category){category = _category;}
 22     virtual ~Money(){}
 23     virtual void save() = 0;
 24 private:
 25     MoneyCategory category;
 26 };
 27 
 28 //具体享元角色
 29 class MoneyCoin:public Money{
 30 public:
 31     MoneyCoin(MoneyCategory _moneyCategory):Money(_moneyCategory){cout << "Save With Coin" << endl;}
 32     ~MoneyCoin(){}
 33     void save()
 34     {
 35         cout << "save coin" << endl;
 36     }
 37 };
 38 
 39 class MoneyNote:public Money{
 40 public:
 41     MoneyNote(MoneyCategory _moneyCategory):Money(_moneyCategory){cout << "Save With Note" << endl;}
 42     ~MoneyNote(){}
 43     void save()
 44     {
 45         cout << "save note" << endl;
 46     }
 47 };
 48 
 49 //享元工厂类,提供用户存取享元角色的方法
 50 class Bank{
 51 public:
 52     Bank():coin(nullptr),note(nullptr),count(0){}
 53     ~Bank(){
 54         if (coin != nullptr){
 55             delete coin;
 56             coin = nullptr;
 57         }
 58         if (note != nullptr){
 59             delete note;
 60             note = nullptr;
 61         }
 62     }
 63     void saveMoney(MoneyCategory category, FaceValue value){
 64         switch (category) {
 65             case Coin:{
 66                 if (coin == nullptr){
 67                     //避免重复创建对象
 68                     coin = new MoneyCoin(Coin);
 69                 }
 70                 coin->save();
 71                 faceValueVector.push_back(value);
 72                 break;
 73             }
 74             case BankNote:{
 75                 if (note == nullptr){
 76                     note = new MoneyNote(BankNote);
 77                 }
 78                 note->save();
 79                 faceValueVector.push_back(value);
 80                 break;
 81             }
 82             default:{
 83                 break;
 84             }
 85         }
 86     }
 87     int sumSave(){
 88         auto iter = faceValueVector.begin();
 89         for (;iter != faceValueVector.end(); iter++){
 90             count += *iter;
 91         }
 92         return count;
 93     }
 94 private:
 95     vector<FaceValue> faceValueVector;
 96     Money* coin;
 97     Money* note;
 98     int count;
 99 };
100 
101 int main()
102 {
103     Bank bank;
104     bank.saveMoney(Coin, ValueOne);
105     bank.saveMoney(BankNote, ValueTen);
106     bank.saveMoney(Coin, ValueOne);
107     bank.saveMoney(BankNote, ValueTen);
108     cout << "Total Money:" << bank.sumSave() << endl;
109     return 0;
110 }

Java 实现:

  1 public enum MoneyCategory {
  2     Coin,
  3     BankNote
  4 }
  5 
  6 public enum FaceValue{
  7     ValueOne,
  8     ValueTen
  9 }
 10 
 11 public abstract class Money {
 12 
 13     protected MoneyCategory category;
 14 
 15     Money(MoneyCategory category){
 16         this.category = category;
 17     }
 18 
 19     public void save(){}
 20 }
 21 
 22 public class MoneyCoin extends Money {
 23 
 24     public MoneyCoin(MoneyCategory moneyCategory){
 25         super(moneyCategory);
 26         System.out.println("Save With Coin");
 27     }
 28 
 29     public void save(){
 30         System.out.println("Save Coin");
 31     }
 32 }
 33 
 34 public class MoneyNote extends Money {
 35 
 36     public MoneyNote(MoneyCategory moneyCategory){
 37         super(moneyCategory);
 38         System.out.println("Save With Note");
 39     }
 40 
 41     public void save(){
 42         System.out.println("Save Note");
 43     }
 44 }
 45 
 46 public class Bank {
 47 
 48     private static final Map<FaceValue, Integer> valueMap = new HashMap<FaceValue, Integer>(){{put(FaceValue.ValueOne, 1); put(FaceValue.ValueTen, 10);}};
 49 
 50     private Money moneyCoin;
 51 
 52     private Money moneyNote;
 53 
 54     private List<FaceValue> faceValueList;
 55 
 56     public Bank(){
 57         faceValueList = new ArrayList<FaceValue>();
 58     }
 59 
 60     public void saveMoney(MoneyCategory moneyCategory, FaceValue faceValue){
 61         switch (moneyCategory){
 62             case Coin:{
 63                 if (moneyCoin == null){
 64                     moneyCoin = new MoneyCoin(moneyCategory);
 65                 }
 66                 moneyCoin.save();
 67                 faceValueList.add(faceValue);
 68                 break;
 69             }
 70             case BankNote: {
 71                 if (moneyNote == null) {
 72                     moneyNote = new MoneyNote(moneyCategory);
 73                 }
 74                 moneyNote.save();
 75                 faceValueList.add(faceValue);
 76             }
 77             default:
 78                 break;
 79         }
 80     }
 81 
 82     public int getMoney(){
 83         int total = 0;
 84         for (FaceValue faceValue:
 85              faceValueList) {
 86             total += valueMap.get(faceValue);
 87         }
 88         return total;
 89     }
 90 }
 91 
 92 public class Main {
 93 
 94     public static void main(String[] args) {
 95         Bank bank = new Bank();
 96         bank.saveMoney(MoneyCategory.Coin, FaceValue.ValueOne);
 97         bank.saveMoney(MoneyCategory.BankNote, FaceValue.ValueTen);
 98         bank.saveMoney(MoneyCategory.Coin, FaceValue.ValueOne);
 99         bank.saveMoney(MoneyCategory.BankNote, FaceValue.ValueTen);
100         System.out.println("Totally save money:" + bank.getMoney());
101     }
102 }

 

上一篇:【Java-1】设计模式


下一篇:Java基础(单实例设计模式懒汉式解决线程安全)