Design Pattern - Structural Patterns - Flyweight Pattern
来源:互联网 发布:淘宝快速提升信誉 编辑:程序博客网 时间:2024/05/16 23:09
2007
2007
Section 6, Chapter 4
Section 2, Chapter 3
2007
Section 6, Chapter 4
Section 2, Chapter 3
Flyweight Pattern
Concept
Put all the content from both books together, the highlights of Flyweight Pattern are listed as below:
- The objects are small, which means the volume of the information they carry is not big;
- The amount of such objects is big, which rises a concern of memory, and that is exactly the issue this pattern is meant to solve;
- The information carried by those small objects can be categorized into two groups: intrinsic & extrinsic;
- Intrinsic information can be reused again and again, and it therefore should not be specific to any scenario, that is why Christopher described it as independent of context, and this piece of info is usually referred as intrinsic state of the object;
- Context is defined by Chris as the particular placement of each object in code flow, with the particular values and states associated with that context;
- Extrinsic information are still be carried by those objects, but it is meant to be context-related, and in the pattern,it is computed on the fly at the expense of CPU power in order to save memory resource, so, it is a trade-off.
- Extrinsic state can be computed either by the objects themselves, or by the clients, with the latter manner, you will need to provide the methods to accept those extrinsic data.
- In Christopher's demonstration, there is no clear boundary between intrinsic info and extrinsic one, they can overlap, and intrinsic info can be used as default state, or overridden by extrinsic info to calculate a result in some cases as needed, but their values in the objects won't be overwritten by the extrinsic info.
- In Christopher's design, there is a component called unshared flyweight, and in his example of text processing, the position of a character is stored as intrinsic information, and it is context related, so it cannot be shared as it only makes sense in some specific situations. Such info is passed through constructor by the context, and will not be changed. How this could be helpful is not revealed clearly in his demonstration, and he also gives following comments: "Since there is one unshared flyweight instance per context location, having intrinsic methods that associate with the context do not interfere with any other implementation of this object within the program...This gives us both the option of sharing objects or allowing many instances of objects to be created. This might be useful if we had a character that was only used rarely or needed special context-related conditions to be useful in the document, such as a paragraph element...The particular context of the unshared character object gives us back the intrinsic values from that context." However, I don't get it, the benefit is not so apparent without a concrete example.
Use
- There is a very large number of objects (thousands) that may not fit in memory.
- Most of the state can be kept on disk or calculated at runtime.
- The remaining state can be factored into a much smaller number of objects with shared state.
There are:
- Many objects to deal with in memory
- Different kinds of state, which can be handled differently to achieve space savings
- Groups of objects that share state
- Ways of computing some of the state at runtime
You want to:
- Implement a system despite severe memory constraints
Design
Photo Group Example by Judith:
Text Processing Example by Chris:
Illustration
Photo Gallery Example:
namespace FlyweightPattern {// Flyweight Pattern Judith Bishop Sept 2007public interface IFlyweight {void Load (string filename);void Display (PaintEventArgs e, int row, int col);}public struct Flyweight : IFlyweight {// Intrinsic stateImage pThumbnail;public void Load(string filename) {pThumbnail = new Bitmap("images/"+filename).GetThumbnailImage(100, 100, null, new IntPtr());}public void Display(PaintEventArgs e, int row, int col) {e.Graphics.DrawImage(pThumbnail, col*100+10, row*130+40, pThumbnail.Width, pThumbnail.Height);}}public class FlyweightFactory {// Keeps an indexed list of IFlyweight objects in existenceDictionary<string, IFlyweight> flyweights = new Dictionary<string, IFlyweight>();public FlyweightFactory() {flyweights.Clear( );}public IFlyweight this[string index] {get {if (!flyweights.ContainsKey(index))flyweights[index] = new Flyweight();return flyweights[index];}}}class Client {// Shared state - the imagesstatic FlyweightFactory album = new FlyweightFactory();// Unshared state - the groupsstatic Dictionary<string, List<string>> allGroups = new Dictionary<string, List<string>>();public void LoadGroups() {var myGroups = new [] {new {Name = "Garden",Members = new [] {"pot.jpg", "spring.jpg", "barbeque.jpg", "flowers.jpg"}},new {Name = "Italy",Members = new [] {"cappucino.jpg","pasta.jpg", "restaurant.jpg", "church.jpg"}},new {Name = "Food",Members = new [] {"pasta.jpg", "veggies.jpg", "barbeque.jpg","cappucino.jpg","lemonade.jpg" }},new {Name = "Friends",Members = new [] {"restaurant.jpg", "dinner.jpg"}}};// Load the Flyweights, saving on shared intrinsic stateforeach (var g in myGroups) { // implicit typingallGroups.Add(g.Name, new List<string>());foreach (string filename in g.Members) {allGroups[g.Name].Add(filename);album[filename].Load(filename);}}}public void DisplayGroups(Object source, PaintEventArgs e) {// Display the Flyweights, passing the unshared stateint row;foreach(string g in allGroups.Keys) {int col;e.Graphics.DrawString(g, new Font("Arial", 16), new SolidBrush(Color.Black), new PointF(0, row*130+10));foreach (string filename in allGroups[g]) {album[filename].Display(e, row, col);col++;}row++;}}}class Window : Form {Window() {this.Height = 600;this.Width = 600;this.Text = "Picture Groups";Client client = new Client();client.LoadGroups();this.Paint += new PaintEventHandler(client.DisplayGroups);}static void Main() {Application.Run(new Window());}}}
And in this example:
The Client class -> client.
Interface IFlyweight -> specification of an image view drawer.
Class Flyweight -> the thumbnail drawer.
The intrinsic state -> thumbnail.
The extrinsic state -> full image.
The unshared information -> the data of a group.
0 0
- Design Pattern - Structural Patterns - Flyweight Pattern
- Design Pattern----Structural Patterns
- Design Pattern - Structural Patterns - Adapter Pattern
- [Special] Design Pattern - Structural Patterns - Proxy Pattern
- Design Pattern - Structural Patterns - Decorator Pattern
- Design Pattern - Structural Patterns - Composite Pattern
- Design Pattern - Structural Patterns - Facade Pattern
- Design Pattern - Structural Patterns - Bridge Pattern
- Structural Patterns Part 6/7: Flyweight Pattern
- Design Pattern - Structural Pattern - Adapter
- Design Pattern - Structural Pattern - Decorator
- Design Pattern - Structural Pattern - Proxy
- Design Pattern 7: Flyweight Pattern
- Design Pattern 4-flyweight
- design pattern Flyweight
- Design Pattern: Flyweight 模式
- Design Pattern----Creational Patterns
- Design Pattern----Behavioral Patterns
- 水平竖直居中方式选择
- 标签为什么要语义化?
- Java语言学习中
- 剑指offer——二进制中1的个数
- GZIP压缩原理分析(10)——第五章 Deflate算法详解(五01) 章前语
- Design Pattern - Structural Patterns - Flyweight Pattern
- 16.2 函数式接口
- AJAX问题之XMLHttpRequest status = 0
- Android内部类,抽象类,接口以及监听事件
- linux c 编程实战:进程控制总结(二)
- 训练第三周之dp-背包训练
- 报错:1130-host ... is not allowed to connect to this MySql server 开放mysql远程连接 不使用localhost
- 16.3 Stream流式编程
- PHP函数之日期时间函数date()详解