1. 程式人生 > 實用技巧 >java23種設計模式-結構型模式-享元模式

java23種設計模式-結構型模式-享元模式

一、定義

享元模式(Flyweight Pattern)主要用於減少建立物件的數量,以減少記憶體佔用和提高效能。這種型別的設計模式屬於結構型模式,它提供了減少物件數量從而改善應用所需的物件結構的方式。

分為:單純享元模式和組享元模式。

一個複合享元物件的所有單純享元物件元素的外蘊狀態都是與複合享元物件的外蘊狀態相等的;而一個複合享元物件所含有的單純享元物件的內蘊狀態一般是不相等的,不然就沒有使用價值了。

二、優點及缺點

優點:

1、大大減少物件的建立,降低系統的記憶體,使效率提高。

缺點:

1、提高了系統的複雜度,需要分離出外部狀態和內部狀態,而且外部狀態具有固有化的性質,不應該隨著內部狀態的變化而變化,否則會造成系統的混亂。

三、程式碼實現:

單純享元模式:

享元抽象類:

package com.example.demo.sjms.danchunxiangyuanmoshi;

/**
 *  @Author: caesar
 *  @Date:2020年11月02日 10:11:45
 *  @Description: 抽象享元角色
 */
public interface PersonInterdface {
    // 傳入外蘊角色
    public void say(String name);
}

享元實現角色:

package com.example.demo.sjms.danchunxiangyuanmoshi;

/** * @Author: caesar * @Date:2020年11月02日 10:11:41 * @Description: 具體享元角色 */ public class Person implements PersonInterdface{ // 傳入內蘊角色 private Integer id; public Person(Integer id) { this.id = id; } @Override public void say(String words) { System.out.println(
"id為"+id+"的員工說"+words); } }

享元工廠:

package com.example.demo.sjms.danchunxiangyuanmoshi;

import java.util.HashMap;
import java.util.Map;

/**
 *  @Author: caesar
 *  @Date:2020年11月02日 10:11:53
 *  @Description: 享元工廠角色
 */
public class PersonFactory {
    private Map<Integer, PersonInterdface> personMap = new HashMap<Integer, PersonInterdface>();
    public PersonInterdface getPersonInterdface(Integer id){
        PersonInterdface person = personMap.get(id);
        if(null == person){
          person = new Person(id);
          personMap.put(id, person);
        }
        return person;
    }
}

測試方法:

package com.example.demo.sjms.danchunxiangyuanmoshi;

/**
 *  @Author: caesar
 *  @Date:2020年11月02日 10:11:54
 *  @Description: 測試類
 */
public class Test {
    public static void main(String[] args) {
        PersonFactory personFactory = new PersonFactory();
        PersonInterdface person = personFactory.getPersonInterdface(1);
        person.say("加油呀!!!");
        PersonInterdface person2 = personFactory.getPersonInterdface(1);
        person.say("加油呀!!!");
        System.out.println(person == person2);
    }
}

複合享元模式:

享元抽象角色:

package com.example.demo.sjms.fuhexiangyuanmoshi;

/**
 *  @Author: caesar
 *  @Date:2020年11月02日 10:11:45
 *  @Description: 抽象享元角色
 */
public interface PersonInterdface {
    // 傳入外蘊角色
    public void say(String name);
}

享元實現角色:

package com.example.demo.sjms.fuhexiangyuanmoshi;

/**
 *  @Author: caesar
 *  @Date:2020年11月02日 10:11:41
 *  @Description: 具體享元角色
 */
public class Person implements PersonInterdface {
    // 傳入內蘊角色
    private Integer id;

    public Person(Integer id) {
        this.id = id;
    }

    @Override
    public void say(String words) {
        System.out.println("id為"+id+"的員工說"+words);
    }
}

複合享元角色:

package com.example.demo.sjms.fuhexiangyuanmoshi;

import java.util.HashMap;
import java.util.Map;

/**
 *  @Author: caesar
 *  @Date:2020年11月02日 11:11:27
 *  @Description: 複合享元類
 */
public class MorePerson implements PersonInterdface{
    private Map<Integer, PersonInterdface> personMap = new HashMap<Integer, PersonInterdface>();
    public void add(Integer key, PersonInterdface value){
        if(null == personMap.get(key)){
            personMap.put(key, value);
        }
    }
    @Override
    public void say(String name) {
        personMap.forEach((k, v) -> {
            v.say(name);
        });
    }
}

享元工廠角色:

package com.example.demo.sjms.fuhexiangyuanmoshi;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  @Author: caesar
 *  @Date:2020年11月02日 10:11:53
 *  @Description: 享元工廠角色
 */
public class PersonFactory {
    private Map<Integer, PersonInterdface> personMap = new HashMap<Integer, PersonInterdface>();

    /**
     *  @Author: caesar
     *  @Date:2020年11月02日 11:11:50
     *  @Description: 複合享元方法
     */
    public PersonInterdface getPersonInterdface(List<Integer> idList){
        MorePerson morePerson = new MorePerson();
        idList.forEach(x ->{
            morePerson.add(x,this.getPersonInterdface(x));
        });
        return morePerson;
    }

    /**
     *  @Author: caesar
     *  @Date:2020年11月02日 11:11:05
     *  @Description: 單純享元方法
     */
    public PersonInterdface getPersonInterdface(Integer id){
        PersonInterdface person = personMap.get(id);
        if(null == person){
          person = new Person(id);
          personMap.put(id, person);
        }
        return person;
    }
}

測試類:

package com.example.demo.sjms.fuhexiangyuanmoshi;

import java.util.ArrayList;
import java.util.List;

/**
 *  @Author: caesar
 *  @Date:2020年11月02日 10:11:54
 *  @Description: 測試類
 */
public class Test {
    public static void main(String[] args) {
        PersonFactory personFactory = new PersonFactory();
        List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        PersonInterdface person = personFactory.getPersonInterdface(list);
        person.say("加油呀!!!");
    }
}

四、原始碼級別

五、總結

注意點:1、注意劃分外部狀態和內部狀態,否則可能會引起執行緒安全問題。 2、這些類必須有一個工廠物件加以控制。3、有大量相同物件時使用。