Heim  >  Artikel  >  Java  >  Detailliertes Verständnis des Beispielcodes für den Fliegengewichtsmodus (Bilder und Text)

Detailliertes Verständnis des Beispielcodes für den Fliegengewichtsmodus (Bilder und Text)

黄舟
黄舟Original
2017-03-14 10:22:241092Durchsuche


Zusammenfassung:

 Objektorientierte Technologie kann einige Flexibilitäts- oder Skalierbarkeitsprobleme lösen, In vielen Fällen ist es jedoch erforderlich, die Anzahl der Klassen und Objekte im System zu erhöhen. Wenn zu viele Objekte vorhanden sind, sind die Betriebskosten zu hoch, was zu Leistungseinbußen und anderen Problemen führt. FliegengewichtsmodusVerwenden Sie die Sharing-Technologie, um dieselben oder ähnliche Objekte wiederzuverwenden und so die Nutzung von Systemressourcen zu verbessern. In diesem Artikel werden zunächst die durch das Fliegengewichtsmodell zu lösenden Probleme und das Konzept der Problemlösung erläutert, dann wird der Schwerpunkt auf das Wesentliche des Modells aus Implementierungsperspektive gelegt und außerdem werden die darin enthaltenen Rollen und Organisationsstrukturen erläutert. Abschließend werden Anwendungsbeispiele und Nutzungsszenarien des Sharing-Modus gegeben.


1. Motivation

 Objektorientierte Technologie kann einige Flexibilitäts- oder Skalierbarkeitsprobleme gut lösen, muss jedoch in vielen Fällen im System implementiert werden die Anzahl der Klassen und Objekte. Wenn zu viele Objekte vorhanden sind, sind die Betriebskosten zu hoch, was zu Leistungseinbußen und anderen Problemen führt. Um diese Art von Problem zu lösen, wurde das Fliegengewichtsmodell geboren. Der Fliegengewichtsmodus realisiert die Wiederverwendung derselben oder ähnlicher Objekte durch die gemeinsame Nutzung der Technologie. Das schematische Diagramm sieht wie folgt aus (wir können ein Hello-World-Objekt teilen, in dem die Zeichenfolge „Hallo Welt“ steht. ist der interne Zustand , kann geteilt werden; die Schriftfarbe ist ein externer Zustand, kann nicht geteilt werden und wird vom Client festgelegt):

   Detailliertes Verständnis des Beispielcodes für den Fliegengewichtsmodus (Bilder und Text)

Derselbe Inhalt, der im Fliegengewichtsmodus geteilt werden kann, wird als Internal State (Intrinsic State) bezeichnet, und die Inhalte, die von der externen Umgebung festgelegt werden müssen und nicht geteilt werden können, werden als Extrinsischer Zustand (Extrinsischer Zustand) , wobei der externe Zustand und der interne Zustand unabhängig voneinander sind und Änderungen im externen Zustand keine Änderungen im internen Zustand verursachen. Aufgrund der Unterscheidung zwischen internem und externem Status kann dasselbe Objekt durch Festlegen verschiedener externer Zustände unterschiedliche Eigenschaften aufweisen und derselbe interne Zustand kann gemeinsam genutzt werden. Mit anderen Worten: Die Essenz des Fliegengewichtsmodells ist Trennung und Teilen: Trennung ändert sich und ändert sich nicht, und Teilen ändert sich nicht. Teilen Sie den Zustand eines Objekts in einen internen Zustand und einen externen Zustand auf. Durch die gemeinsame Nutzung der unveränderten Teile wird der Zweck erreicht, die Anzahl der Objekte zu reduzieren und Speicherplatz zu sparen .

Im Flyweight-Modus erscheint normalerweise der

Factory-Modus. Sie müssen eine Flyweight-Fabrik erstellen, um einen Flyweight-Pool zu verwalten (der zum Speichern von Flyweights mit demselben internen Status verwendet wird). Im Fliegengewichtsmodus wird der interne Status des Fliegengewichtsobjekts gemeinsam genutzt, und der externe Status muss über die Umgebung festgelegt werden. Bei der tatsächlichen Verwendung ist der interne Status, der gemeinsam genutzt werden kann, begrenzt. Daher sind Fliegengewichtsobjekte im Allgemeinen als kleinere Objekte konzipiert, die weniger internen Status enthalten. Diese Art von Objekt wird auch als feinkörniges Objekt bezeichnet .
Der Zweck des Fliegengewichtsmodus besteht darin, mithilfe der Sharing-Technologie die Wiederverwendung einer großen Anzahl feinkörniger Objekte zu erreichen.


2. Definition und Struktur

Flyweight-Muster: Nutzen Sie die Sharing-Technologie, um die Wiederverwendung einer großen Anzahl feinkörniger Objekte effektiv zu unterstützen. Das System verwendet nur eine kleine Anzahl von Objekten. Diese Objekte sind sich sehr ähnlich und weisen nur sehr geringe Zustandsänderungen auf, sodass die Objekte mehrfach wiederverwendet werden können. Da der

Fliegengewichtsmodus erfordert, dass Objekte, die gemeinsam genutzt werden können, feinkörnige Objekte sein müssen, wird er auch als Leichtgewichtsmodus bezeichnet. Es handelt sich um einen Objektstrukturmodus.

Fliegengewichtsmuster:

Verwenden Sie die gemeinsame Nutzung, um eine große Anzahl feinkörniger Objektes effizient zu unterstützen 1. Am Modus beteiligte Charaktere

 Flyweight: Flyweight Schnittstelle , über die der externe Zustand übergeben und bearbeitet wird;
ConcreteFlyweight: Spezifische Flyweight-Implementierung Das Objekt muss gemeinsam genutzt werden können und muss den internen Zustand des Fliegengewichtsobjekts kapseln;
 UnsharedConcreteFlyweight: Nicht gemeinsam genutztes Fliegengewichtsobjekt, nicht alle Fliegengewichtsobjekte können gemeinsam genutzt werden. Nicht gemeinsam genutzte Fliegengewichtsobjekte sind normalerweise Kombinationen von Fliegengewichtsobjekten >
FlyweightFactory: Flyweight Factory wird hauptsächlich zum Erstellen und Verwalten gemeinsam genutzter Flyweight-Objekte und zur Bereitstellung externer Schnittstellen für den Zugriff auf gemeinsam genutzte Flyweight-Objekte verwendet.


3. ModuserweiterungFlyweight Structure.png-72.6kB


Einfacher Fliegengewichtsmodus: Im reinen Fliegengewichtsmodus können alle Fliegengewichtsobjekte gemeinsam genutzt werden, also alle Unterklassen Die abstrakte Fliegengewichtsklasse kann gemeinsam genutzt werden, und es gibt keine nicht gemeinsam genutzte konkrete Fliegengewichtsklasse.

        
  • Implementierungsbeispiel:

    Detailliertes Verständnis des Beispielcodes für den Fliegengewichtsmodus (Bilder und Text)

     
  • Obwohl der Kunde drei Fliegengewichtsobjekte beantragt hat, sind es beim tatsächlich erstellten Fliegengewicht nur zwei Objekte, das ist es, was Teilen bedeutet.
Die Laufergebnisse sind wie folgt:
//抽象享元角色类public interface Flyweight {
    //一个示意性方法,参数state是外蕴状态
    public void operation(String state);
}//具体享元角色类//具体享元角色类ConcreteFlyweight有一个内蕴状态,在本例中一个Character类型的intrinsicState属性代表,它的值应当在享元对象
//被创建时赋予。所有的内蕴状态在对象创建之后,就不会再改变了。如果一个享元对象有外蕴状态的话,所有的外部状态都必须存储在客户端,
//在使用享元对象时,再由客户端传入享元对象。这里只有一个外蕴状态,operation()方法的参数state就是由外部传入的外蕴状态。
public class ConcreteFlyweight implements Flyweight {
    private Character intrinsicState = null;    /**
     * 构造函数,内蕴状态作为参数传入
     * @param state
     */
    public ConcreteFlyweight(Character state){        this.intrinsicState = state;
    }    /**
     * 外蕴状态作为参数传入方法中,改变方法的行为,
     * 但是并不改变对象的内蕴状态。
     */
    @Override
    public void operation(String state) {        // TODO Auto-generated method stub
        System.out.println("Intrinsic State = " + this.intrinsicState);
        System.out.println("Extrinsic State = " + state);
    }

}//享元工厂角色类//享元工厂角色类,必须指出的是,客户端不可以直接将具体享元类实例化,而必须通过一个工厂对象,利用一个factory()方法得到享元对象。
//一般而言,享元工厂对象在整个系统中只有一个,因此也可以使用单例模式。
//当客户端需要单纯享元对象的时候,需要调用享元工厂的factory()方法,并传入所需的单纯享元对象的内蕴状态,由工厂方法产生所需要的//享元对象。
public class FlyweightFactory {
    private Map<Character,Flyweight> files = new HashMap<Character,Flyweight>();    
    public Flyweight factory(Character state){        
    //先从缓存中查找对象
        Flyweight fly = files.get(state);        
        if(fly == null){            
        //如果对象不存在则创建一个新的Flyweight对象
            fly = new ConcreteFlyweight(state);            
            //把这个新的Flyweight对象添加到缓存中
            files.put(state, fly);
        }        return fly;
    }
}//客户端类public class Client {

    public static void main(String[] args) {        // TODO Auto-generated method stub
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight fly = factory.factory(new Character(&#39;a&#39;));
        fly.operation("First Call");

        fly = factory.factory(new Character(&#39;b&#39;));
        fly.operation("Second Call");

        fly = factory.factory(new Character(&#39;a&#39;));
        fly.operation("Third Call");
    }

}

   

Detailliertes Verständnis des Beispielcodes für den Fliegengewichtsmodus (Bilder und Text)

Composite-Fliegengewichtsmodus: Verwenden Sie einige einfache Fliegengewichte im
Kombinationsmodus
    Durch ihre Kombination können zusammengesetzte Fliegengewichtsobjekte selbst nicht gemeinsam genutzt werden, sie können jedoch in einfache Fliegengewichtsobjekte zerlegt und letztere gemeinsam genutzt werden.
  •     

    Detailliertes Verständnis des Beispielcodes für den Fliegengewichtsmodus (Bilder und Text) Implementierungsbeispiel:

Die Laufergebnisse lauten wie folgt:

  
//抽象享元角色类public interface Flyweight {
    //一个示意性方法,参数state是外蕴状态
    public void operation(String state);
}//具体享元角色类
//具体享元角色类ConcreteFlyweight有一个内蕴状态,在本例中一个Character类型的intrinsicState属性代表,它的值应当在享元对象
//被创建时赋予。所有的内蕴状态在对象创建之后,就不会再改变了。如果一个享元对象有外蕴状态的话,所有的外部状态都必须存储在客户端,
//在使用享元对象时,再由客户端传入享元对象。这里只有一个外蕴状态,operation()方法的参数state就是由外部传入的外蕴状态。
public class ConcreteFlyweight implements Flyweight {
    private Character intrinsicState = null;    /**
     * 构造函数,内蕴状态作为参数传入
     * @param state
     */
    public ConcreteFlyweight(Character state){        this.intrinsicState = state;
    }    /**
     * 外蕴状态作为参数传入方法中,改变方法的行为,
     * 但是并不改变对象的内蕴状态。
     */
    @Override
    public void operation(String state) {        // TODO Auto-generated method stub
        System.out.println("Intrinsic State = " + this.intrinsicState);
        System.out.println("Extrinsic State = " + state);
    }

}
//复合享元角色类
//复合享元对象是由单纯享元对象通过复合而成的,因此它提供了add()这样的聚集管理方法。由于一个复合享元对象具有不同的聚集元素,
//这些聚集元素在复合享元对象被创建之后加入,这本身就意味着复合享元对象的状态是会改变的,因此复合享元对象是不能共享的。
//复合享元角色实现了抽象享元角色所规定的接口,也就是operation()方法,这个方法有一个参数,代表复合享元对象的外蕴状态。
//一个复合享元对象的所有单纯享元对象元素的外蕴状态都是与复合享元对象的外蕴状态相等的;
//而一个复合享元对象所含有的单纯享元对象的内蕴状态一般是不相等的,不然就没有使用价值了。
public class ConcreteCompositeFlyweight implements Flyweight {

    private Map<Character,Flyweight> files = new HashMap<Character,Flyweight>();    /**
     * 增加一个新的单纯享元对象到聚集中
     */
    public void add(Character key , Flyweight fly){
        files.put(key,fly);
    }    /**
     * 外蕴状态作为参数传入到方法中
     */
    @Override
    public void operation(String state) {
        Flyweight fly = null;        for(Object o : files.keySet()){
            fly = files.get(o);
            fly.operation(state);
        }

    }

}//享元工厂角色类//享元工厂角色提供两种不同的方法,一种用于提供单纯享元对象,另一种用于提供复合享元对象。public class FlyweightFactory {
    private Map<Character,Flyweight> files = new HashMap<Character,Flyweight>();    /**
     * 复合享元工厂方法
     */
    public Flyweight factory(List<Character> compositeState){
        ConcreteCompositeFlyweight compositeFly = new ConcreteCompositeFlyweight();        for(Character state : compositeState){
            compositeFly.add(state,this.factory(state));
        }        return compositeFly;
    }    /**
     * 单纯享元工厂方法
     */
    public Flyweight factory(Character state){        //先从缓存中查找对象
        Flyweight fly = files.get(state);        if(fly == null){            //如果对象不存在则创建一个新的Flyweight对象
            fly = new ConcreteFlyweight(state);            //把这个新的Flyweight对象添加到缓存中
            files.put(state, fly);
        }        return fly;
    }
}//客户端类public class Client {

    public static void main(String[] args) {
        List<Character> compositeState = new ArrayList<Character>();
        compositeState.add(&#39;a&#39;);
        compositeState.add(&#39;b&#39;);
        compositeState.add(&#39;c&#39;);
        compositeState.add(&#39;a&#39;);
        compositeState.add(&#39;b&#39;);

        FlyweightFactory flyFactory = new FlyweightFactory();
        Flyweight compositeFly1 = flyFactory.factory(compositeState);
        Flyweight compositeFly2 = flyFactory.factory(compositeState);
        compositeFly1.operation("Composite Call");

        System.out.println("---------------------------------");        
        System.out.println("复合享元模式是否可以共享对象:" + (compositeFly1 == compositeFly2));

        Character state = &#39;a&#39;;
        Flyweight fly1 = flyFactory.factory(state);
        Flyweight fly2 = flyFactory.factory(state);
        System.out.println("单纯享元模式是否可以共享对象:" + (fly1 == fly2));
    }
}

Detailliertes Verständnis des Beispielcodes für den Fliegengewichtsmodus (Bilder und Text)

Die Kombination aus Fliegengewichtsmodus und anderen Modi
    In der Fliegengewichts-Fabrikklasse des Fliegengewichtsmodus wird normalerweise eine
  • statische

    Fabrikmethode bereitgestellt . Um ein Fliegengewichtsobjekt zurückzugeben, verwenden Sie

    Simple Factory Pattern, um ein Fliegengewichtsobjekt zu generieren. In einem System gibt es normalerweise nur eines Fliegengewichtsobjekt Yuan-Fabrik, also Die Fliegengewichts-Fabrikklasse kann im Singleton-Modus entworfen werden ;

      Der Fliegengewichtsmodus kann mit dem Kombinationsmodus kombiniert werden Zusammengesetztes gemeinsam genutztes Objekt Der Metamodus legt den externen Status von Fliegengewichtsobjekten einheitlich fest.

    3. Der Musteranalysemodus ist ein Design, das die Systemleistung berücksichtigt

    können Sie Speicherplatz sparen und die Systemleistung verbessern, indem Sie den Fliegengewichtsmodus verwenden.

 

Der Kern des Fliegengewichtsmodells ist die Fliegengewichts-Fabrikklasse. Die Funktion der Fliegengewichts-Fabrikklasse besteht darin, einen Fliegengewichtspool zum Speichern von Fliegengewichtsobjekten bereitzustellen Wenn ein Objekt benötigt wird, wird es zunächst aus dem Flyweight-Pool abgerufen. Wenn es nicht im Flyweight-Pool vorhanden ist, wird ein neues Flyweight-Objekt erstellt und an den Benutzer zurückgegeben, und das neue-Objekt wird im gespeichert Pool im Fliegengewicht. Typischer Fabrikklassencode für das Fliegengewicht:

Der Fliegengewichtsmodus unterstützt effizient eine große Anzahl feinkörniger Objekte auf gemeinsame Weise, Der Schlüssel zum Teilen von Flyweight-Objekten liegt in der Unterscheidung zwischen internem Zustand (Internal State) und externem Zustand (External State). Wobei:

public class FlyweightFactory{
    private HashMap flyweights = new HashMap();    public Flyweight getFlyweight(String key)
    {        if(flyweights.containsKey(key))
        {            return (Flyweight)flyweights.get(key);
        }        else
        {
            Flyweight fw = new ConcreteFlyweight();
            flyweights.put(key,fw);            return fw;
        }
    }
}
Interner Zustand

ist ein Zustand, der im Flyweight-Objekt gespeichert ist und sich nicht mit der Umgebung ändert, sodass der interne Zustand geteilt werden kann .

Externer Zustand
    ist ein Zustand, der sich mit der Umgebung ändert und nicht geteilt werden kann. Der externe Status des Flyweight-Objekts muss vom Client gespeichert und an das Flyweight-Objekt übergeben werden, wenn er nach der Erstellung des Flyweight-Objekts benötigt wird. Ein externer Zustand ist unabhängig von einem anderen externen Zustand.
  • Typischer Code im Fliegengewicht:

    public class Flyweight{
            //内部状态作为成员属性
        private String intrinsicState;    public Flyweight(String intrinsicState)
        {        this.intrinsicState = intrinsicState;
        }    public void operation(String extrinsicState)
        {
            ......
        }   
    }

    四. 模式的应用

    • 享元模式在编辑器软件中大量使用,如在一个文档中多次出现相同的图片,则只需要创建一个图片对象,通过在应用程序中设置该图片出现的位置,可以实现该图片在不同地方多次重复显示。

    • 广义上讲,在JDK类库中定义的String类也是使用享元模式的典型。

    public class Demo{
        public static void main(String args[])
        {
            String str1 = "abcd";
            String str2 = "abcd";
            String str3 = "ab" + "cd";
            String str4 = "ab";
            str4 += "cd";
            System.out.println(str1 == str2);      //true
            System.out.println(str1 == str3);      //true
            System.out.println(str1 == str4);      //false
        }
    }

    五. 总结

    1、模式适用环境
      
    在以下情况下可以使用享元模式:

    • 一个系统有大量相同或者相似的对象,由于这类对象的大量使用,造成内存的大量耗费;

    • 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中(细粒度对象);

    • 使用享元模式需要维护一个存储享元对象的享元池,而这需要耗费资源,因此,应当在多次重复使用享元对象时才值得使用享元模式。


    2、模式的优点

      (1)它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份;
      (2)享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。


    3、模式的缺点

      (1)享元模式使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化;
      (2)为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。


    4、模式的实现

    • 享元模式运用共享技术有效地支持大量 细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用,它是一种对象结构型模式。

    • 享元模式包含四个角色:抽象享元类声明一个接口,通过它可以接受并作用于外部状态;具体享元类实现了抽象享元接口,其实例称为享元对象;非共享具体享元是不能被共享的抽象享元类的子类;享元工厂类用于创建并管理享元对象,它针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中。

    • 享元模式以共享的方式高效地支持大量的细粒度对象,享元对象能做到共享的关键是区分内部状态和外部状态。其中内部状态是存储在享元对象内部并且不会随环境改变而改变的状态,因此内部状态可以共享;外部状态是随环境改变而改变的、不可以共享的状态。

Das obige ist der detaillierte Inhalt vonDetailliertes Verständnis des Beispielcodes für den Fliegengewichtsmodus (Bilder und Text). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn