Flyweight mode
Flyweight mode is used to avoid a lot of repetitions of similar classes. There is such a situation when programming: you seem to have a large number of instances of a small class to show data. But in some cases, if you can realize that many instances are in addition to a small number of parameters, it is essentially the same, you will be able to reduce different classes that need to be instantiated - if you can move these variables to In addition to the example of the class, as part of the method passes them, the number of instances can be greatly reduced by sharing.
The Flyweight design mode is to provide a way to handle this class. Flyweight refers to internal data that reflects uniqueness of instances and external data as a parameter. Flyweight mode is suitable for small and fine classes, like a single character or icon on the screen. For example, you draw a series of icons on the Windows screen, each representing a folder of a person or a data file, see the figure below:
In this case, each folder has an instance of a class to remember the information such as the human name and the screen position of the icon is not a good method. Under normal circumstances, these icons are a small picture, while the positions drawing their position are dynamically calculated based on the size of Window.
In another example of the design mode, each character in the document is an instance of a character class, but their position on the screen is considered external data. In this case, each character only needs one instance, not one of each character's display.
Flyweight is an instance share of the class.
First, it seems that every class is like a Singleton, but it may actually have a small amount rather than an instance, such as a class that may have an instance of all characters, as well as all icons (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, Folder clauses will have two instances such as selection and unselected file clamps). The number of instances that need to be assigned must be the number of unwanted class instances, and these work is usually done by the FlyweightFactory class. This factory class is usually a Singleton because it needs to track whether a particular instance is generated. It returns a new instance that returns a reference if the instance already exists.
To determine if your part of your program applies to Flyweight, you should consider whether some data may be removed from the class as external data. If this makes it possible to reduce the number of different examples of instances that need to be maintained, then this is where a Flyweight applies.
Example
Suppose we want to draw small folder icons for each person of the organization, and there is a name. If this is a big organization, it may be a large number of such icons, however, all icons are the same picture. Even if we need two icons - a indication selected, a number indicating that unchecked - different icons is also small. In such a system, each person corresponds to an icon object, with a name, selected status, etc., is a great waste of resources.
Therefore, now we create a folderFactory to return a folder class selected or unselected instead of building an excess instance. Since this is a simple example, we only build them and return them in their start.
Public class supplies {
Private Folder Selfolder, unselfolder;
// -----
Public folderfactory () {
// Create The Two Folders
Selfolder = New Folder (Color.brown);
Unselfolder = new folder (color.bisque);
}
// -----
Public Folder getFolder (Bool SELECTED {
IF (SELECTED)
Return Selfolder;
Else
Return unselfolder;
}
}
If there is a plurality of instances, the factory should have a table to record which has been created, only the table does not exist can be created. The only thing we use to use Flyweight is to pass the names and other information to it when you need to draw a folder. Names, etc. are external data, so we can share folder objects, in which case only two instances. The following folders are simply created a folder instance, with two background colors, and a PUBLIC's drawing method for drawing a folder on your specified place.
Public class folder {
// Draws a Folder At the Specified Coordinates
Private const Int w = 50;
Private const INT H = 30;
Private Pen Blackpen, Whitepen;
PRIVATE PEN GRAYPEN;
Private solidbrush backbrush, blackbrush;
PRIVATE FONT FNT;
// ------
Public Folder (Color Color Color Color) {
BACKBRUSH = New Solidbrush (Col);
BlackBrush = New Solidbrush (color.black);
Blackpen = new pen (color.black);
Whitepen = new pen (color.white);
Graypen = new pen (color.gray);
FNT = New Font ("Arial", 12);
}
// -----
Public Void Draw (Graphics G, INT X, INT Y, STRING TITLE) {
// Color Folder
G.FillRectangle (Backbrush, X, Y, W, H);
// Outline In Black
g.drawRectangle (Blackpen, X, Y, W, H);
// LEFT 2 SIDES has WHITE LINE
g.drawline (Whitepen, X 1, Y 1, X W - 1, Y 1);
g.drawline (Whitepen, X 1, Y, X 1, Y H);
// draw tab
g.drawRectangle (Blackpen, X 5, Y - 5, 15, 5);
G.FillRectangle (Backbrush, X 6, Y - 4, 13, 6);
// Gray Line on Right and Bottom
g.drawline (Graypen, X, Y H - 1, X W, Y H - 1);
g.drawline (Graypen, X W - 1, Y, X W - 1,
Y H - 1);
g.drawstring (Title, FNT, BlackBrush, X, Y H 5);
}
}
To use a such flyweight class, your main program must calculate the location of each folder as part of the Flyweight's drawing program, and then passed other information to the folder instance. Since you may need a different layout according to the screen, you don't want to tell the instance new location when you draw, turn, we are dynamically calculated in the drawing program.
According to the above design, we will create a folder list array and simply scan the array to draw each folder. Such an array is different from the "large number of similar instances" that we will talk about, it is not a waste because it is actually just a set of references to the two folder instances. Since we want to display the folder as "selected", and can change the state according to the selection, we will use the Folder plant to automatically return the appropriate instance at each time. There are two locations where we need to calculate the folder in our display procedure: When drawing it and the mouse is suspended above. Therefore, it will be relatively convenient to abstract the location code to be a Positioner class.
Public class positioner {
Private const INT PLEFT = 30;
Private const INT ptop = 30;
Private const Int hspace = 70;
Private const Int vSpace = 80;
Private const Int rowmax = 2;
Private int x, y, cnt;
// -----
Public positioner () {
RESET ();
}
// -----
Public void reset () {
X = PLEFT;
Y = ptop;
CNT = 0;
}
// -----
Public int nextx () {
Return X;
}
// -----
Public void incr () {
CNT ;
IF (CNT> Rowmax) {// Reset to Start New Row
CNT = 0;
X = PLEFT;
Y = vSpace;
}
Else {
X = hspace;
}
}
// -----
Public int nexty () {
Return Y;
}
}
So we can write more simple drawing programs:
Private void Picpaint (Object Sender, Painteventargs E) {
Graphics g = E.Graphics;
Posn.reset ();
For (int i = 0; i FOL = folfact.getfolder (SELECTEDNAME.EQUALS (String) Names [i])); Fol.draw (g, posn.nextx (), posn.nexty (), (String) Names [i]); Posn.incr (); } } Class Diagram The following figure shows the interaction between these classes. (to be continued)