Too Many
Flyweight: Too many objects (TOO MANY Objects)
The Flyweidht mode may be strange to: it (with other modes of other modes) is a method of improving performance HACK. Usually, a better approach is to simply make everything in the system, but sometimes do this will make the number of objects that are very huge, which may cause the system to be too slow or memory consumption.
Flyweight mode solves this problem by reducing the number of objects. In order to achieve this, externalization is required to be some data, which makes it look more than the actual number of objects. However, this also increases the complexity of the interface when applying these objects, because you must introduce additional information to tell the call to how to find those externalized information.
As a very simple example, consider a DataPoint object, which contains a data member of an int and float type, and an ID data member is used to represent the object number. Suppose you need to create a million such objects and then operate them like this:
//: flyweight: ManyObjects.java class DataPoint {private static int count = 0; private int id = count ; private int i; private float f; public int getI () {return i;} public void setI (int i) { = i;} public float getf () {returnif;} public void setf (float f) {this.f = f;} public string toString () {return "ID:" ID ", i = " i ", f = " f;}} public class manObjects {static final int size = 1000000; public static void main (string [] args) {datapoint [] array = new data [size]; for (int i = 0; i The above program can take a few seconds, depending on your machine. More complex objects and more operations may make additional overhead difficult to maintain. In order to solve this problem, we have reduced the number of objects from one million by externalization of the number of DataPoint data members. //: flyweight: flyweightObjects.java Class externalizeddata { Static firm int size = 5000000; Static int [] id = new int [size]; static int [] i = new int tent Static float [] f = new float [size]; STATIC { For (int i = 0; i ID [i] = i; } } Class FlyPoint { Private flypoint () {} Public Static Int Geti (int obnum) { Return externalizeddata.i [obnum]; } Public Static Void Seti (int Obnum, INT i) { ExternalizedData.i [obnum] = i; } Public Static Float getf (int obnum) { Return ExternalizedData.f [OBNUM]; } Public static void setf (int obnum, float f) { EXTERNALIZEDDATA.F [OBNUM] = F; } Public Static String Str (Int Obnum) { Return "ID:" ExternalizedData.ID [OBNUM] ", i =" ExternalizedData.i [OBNUM] ", f =" EXTERNALIZEDDATA.F [OBNUM]; } } Public class flyweightObjects { Public static void main (String [] args) { For (int i = 0; i FlyPoint.seti (i, flypoint.geti (i) 1); FlyPoint.SETF (I, 47.0F); } System.out.println ( Flypoint.str (externalizeddata.size -1); } } ///: ~ As a result, all data is stored in ExternalizedData, so each of the call to the FlyPoint method must contain an index of ExternalizedData. For consistency, but also to remind the reader's note (the Implicit) of the Implicit THIS pointer, "this index" is incorporated as the first parameter. Naturally, here is also a warning of premicnce optimization. "Let the program can run, if there is this necessary, then find a way to improve the speed." Again once, with the Profiler tool to detect the performance bottleneck, not to guess. Decorative mode: Too Many Classes Decorator Mode refers to adding a function to a single object with a layered object (Layered Objects). Apply Decorator mode when using a derived class to produce too many (unfunctive) classes. All the decorative categories of all overcrowded objects must have the same basic interface. Dynamic Proxy / Surrogate? Decorator Mode For unconventional inheritance structures. Weigh: Using Decoator mode usually makes the code complicated. Basic Decorator structure An example of coffee a coffee example Consider a coffee beanmeup for a local cafe beanmeup. There is usually a variety of different drinks - distilled coffee, lattes, tea, ice coffee, hot chocolate drinks, and there are many additional additives, such as raw cream or extra distillation coffee powder (of course these are different of). You can also change your drink without paying additional costs, such as you can ask for ordinary coffee to remove coffee because of coffee. One thing is very clear, if we want to model all of these drinks and their combination, it will produce a very large class diagram. In order to clearly explain the problem, we only consider a subset of all coffee varieties: Espresso, Espresso Conccino and Café Mocha. We offer 2 additional additives - raw milk ("whipped") and distillation Coffee powder, and three optional drinks - depackage coffee, Steamed Milk ("WET") and FoAmed Milk ("Dry"). Each combination corresponds to a class Class for EACH Combination A solution is to create a class for each combination. Use it to describe each beverage (composition) and prices. The resulting beverage bill is huge, and some of the entire class map may appear like this: Below is a simple implementation of this combination of CAPPuccino: Class cappuccino { PRIVATE FLOAT COST = 1; PRIVATE STRING DESCRIPTION = "Cappucino"; Public float getcost () { Return Cost; } Public string getdescription () { Return description; } } The most critical point to use this method is to find the specific combination you need. After finding the drink you want, the code of the CoffeeEShop class demonstrates how to use it. //: Decorator: Nodecoators: coffeeshop.java // Coffee Example with no decorators Package Decorator.nodecoTORS; Import junit.framework. *; Class Espresso {} Class Doublespresso {} Class Espressoconpanna {} Class cappuccino { PRIVATE FLOAT COST = 1; PRIVATE STRING DESCRIPTION = "Cappucino"; Public float getcost () { Return Cost; } Public string getdescription () { Return description; } Class cappuccinodecaf {} Class cappuccinodecafwhipped {} Class cappuccinodry {} Class cappuccinodrywhipped {} Class CappuccinoExTraespresso {} Class cappuccinoextraespressowhipped {} Class cappuccinowhipped {} Class cafemocha {} Class cafemochadecaf {} Class cafemochadecafwhipped { Private float cost = 1.25F; Private string description = "Cafe mocha decaf whipped cream"; Public float getcost () { Return Cost; } Public string getdescription () { Return description; } } Class cafemochaextraespresso {} Class cafemochaextraespressowhipped {} Class cafemochawet {} Class cafemochawetWhipped {} Class cafemochawhipped {} Class caflatte {} Class caflattedecaf {} Class caflattedecafwhipped {} Class caflatteextraespresso {} Class caflatteextraespressowhipped {} Class caflattewet {} Class caflattewetwhipped {} Class caflattewhipped {} Public class coffeeeshop extends testcase { Public void testcappuccino () { // this Just Makes Sure IT Will Complete // WITHOUT THROWING AN Exception. // Create a Plain Cappuccino Cappuccino cappuccino = new cappuccino (); System.out.println (Cappuccino.GetDescription () ": $" cappuccino.get ()); } Public void testcafemocha () { // this Just Makes Sure IT Will Complete // WITHOUT THROWING AN Exception. // Create a Decaf cafe mocha with whipped // cream Cafemochadecafwhipped cafemocha = New cafemochadecafwhipped (); System.out.println (cafemocha.getdescription () ": $" cafemocha.getcost ()); } Public static void main (String [] args) { JUnit.textui.teStrunner.run (Coffeeeshop.class); } } ///: ~ The corresponding outputs are as follows: Cappucino: $ 1.0cafe mocha decaf Whipped Cream: $ 1.25 You can see that you can create a combination you want is very simple because you can use an instance of a class. However, this method has many problems. First, these combinations are static fixed, and each combination of customers must be pre-created. Second, the menu generated throughout the combination is too big. It is very difficult to find a particular combination and time consuming. Decorator method It can also be used to remove these beverages into components similar to Esspresso and Foamedmilk, and then let customers describe some specific coffee beverage by combining these components. We use the Decorator mode to achieve the above ideas by programming. Decorator adds a component through a package (Wrapping) to add features, but Decorator is compatible with the interface of the class it wrapped, so that the package of Component is transparent. Decorator itself can be wrapped in (other Decorator) and does not lose its transparency. Calling a method of Decorator, calling the Component of Decorator, and the Component method can be called before or after the Decorator method is called. If you add a gettotalcost () and getDescription () method for the DrinkComponent interface, Esspresso looks like the following: Class Espresso Extends Decorator { Private float cost = 0.75F; PRIVATE STRING DESCRIPTION = "Espresso"; Public Espresso (DrinkComponent Component) { Super (Component); } Public float gettotalcost () { Return Component.gettotalcost () COST; } Public string getdescription () { Return Component.getdescription () Description; } } You can create a drink in combination, just like the code below: //: Decorator: alldecoators: coffeeshop2.java // Coffee EXAMPLE Using Decorators Package Decorator.AllDecorators; Import junit.framework. *; Interface drinkcomponent { String getdescription (); Float gettotalcost (); } Class Mug IMPLEMENTS DrinkComponent { Public string getdescription () { Return "Mug"; } Public float gettotalcost () { Return 0; } } Abstract Class Decorator IMPLEments DrinkComponent { Protected DrinkComponent Component; Decorator (DrinkComponent Component) { this.Component = Component } Public float gettotalcost () { Return Component.gettotalcost (); } Public Abstract string getdescription (); } Class Espresso Extends Decorator { Private float cost = 0.75F; PRIVATE STRING DESCRIPTION = "Espresso"; Public Espresso (DrinkComponent Component) { Super (Component); } Public float gettotalcost () { Return Component.gettotalcost () COST; } Public string getdescription () { Return Component.getdescription () Description; } } Class Decaf Extends Decorator { Private string description = "decaf"; Public Decaf (DrinkComponent Component) { Super (Component); } Public string getdescription () { Return Component.getdescription () Description; } } Class Foamedmilk EXTENDS DECorator { Private float cost = 0.25F; Private string description = "Foamed Milk"; Public FoamedMilk (DrinkComponent Component) { Super (Component); } Public float gettotalcost () { Return Component.gettotalcost () COST; } Public string getdescription () { Return Component.getdescription () Description; } } Class Steamedmilk Extends Decorator { Private float cost = 0.25F; Private string description = "steamed milk"; Public SteamedMilk (DrinkComponent Component) { Super (Component); } Public float gettotalcost () { Return Component.gettotalcost () COST; } Public string getdescription () { Return Component.getdescription () Description; } } Class whipped extends decorator { Private float cost = 0.25F; Private string description = "whipped cream"; Public whipped (DrinkComponent Component) { Super (Component); } Public float gettotalcost () { Return Component.gettotalcost () COST; } Public string getdescription () { Return Component.getdescription () Description; } } Class Chocolate Extends Decorator {Private Float Cost = 0.25F; PRIVATE STRING DESCRIPTION = "Chocolate"; Public Chocolate (DrinkComponent Component) { Super (Component); } Public float gettotalcost () { Return Component.gettotalcost () COST; } Public string getdescription () { Return Component.getdescription () Description; } } Public class coffeeeshop2 extends testcase { Public void testcappuccino () { // this Just Makes Sure IT Will Complete // WITHOUT THROWING AN Exception. // Create a Plain Cappucino DrinkComponent Cappuccino = New Espresso New Foamedmilk (New Mug ())); System.out.println (Cappuccino. GetDescription (). Trim () ": $" Cappuccino.gettotalcost ()); } Public void testcafemocha () { // this Just Makes Sure IT Will Complete // WITHOUT THROWING AN Exception. // Create a Decaf cafe mocha with whipped // cream DrinkComponent cafemocha = new espresso New Steamedmilk (New Chippaper (New Whipped NEW DECAF (New Mug ())))))))))))))))))))))))))))))) System.out.println (cafemocha.getdescription (). Trim () ": $" cafemocha.gettotalcost ()); } Public static void main (String [] args) { JUnit.textui.teStrunner.run (Coffeeeshop2.class); } } ///: ~ This method is of course provided with the most flexible and larger menu. You only need to pick out you need from a few components (Components), but stitching these "descriptions about coffee" is very difficult. If you want to describe pure cappussino coffee, you can write this: New Espresso (New Mug ()))); however, "A Decaf Café Mocha with Whipped Cream requires considerable lengthy description. Compromise It is really too long to describe a certain coffee drink with this method. For those that are often used, they will be more convenient to describe them with a faster way. The third method herein is the combination of the front two methods, which is combined with flexibility and ease of use. This fold is achieved by creating a suitable size for regular selection menu, this menu is basically uncomfortable, but if you want to add a partner for these basic drinks (such as Whipped Cream, Decaf, then you Basic drinks can be changed by Decorators. This is actually the menu provided by most cafés. Here is an example of a routine drink (a Decorated Selection) after a partner: //: Decorator: Compromise: coffeeeshop3.java // Coffee Example with a Compromise of Basic // Combinations and Decorators Package Decorator.compromise; Import junit.framework. *; Interface drinkcomponent { Float gettotalcost (); String getdescription (); } Class Espresso IMPLEments DrinkComponent { PRIVATE STRING DESCRIPTION = "Espresso"; Private float cost = 0.75F; Public float gettotalcost () { Return Cost; } Public string getdescription () { Return description; } } Class Espressoconpanna IMPLEments DrinkComponent { Private string description = "espressoconpare"; PRIVATE FLOAT COST = 1; Public float gettotalcost () { Return Cost; } Public string getdescription () { Return description; } } Class Cappuccino Implements DrinkComponent { PRIVATE FLOAT COST = 1; PRIVATE STRING DESCRIPTION = "Cappuccino"; Public float gettotalcost () { Return Cost; } Public string getdescription () { Return description; } } Class Cafelatte Implements DrinkComponent { PRIVATE FLOAT COST = 1; Private string description = "cafe late"; Public float gettotalcost () { Return Cost; } Public string getdescription () { Return description; } } Class Cafemocha Implements DrinkComponent { Private float cost = 1.25F; PRIVATE STRING DESCRIPTION = "Cafe Mocha"; Public float gettotalcost () {return } Public string getdescription () { Return description; } } Abstract Class Decorator IMPLEments DrinkComponent { Protected DrinkComponent Component; Public Decorator (DrinkComponent Component) { this.Component = Component } Public float gettotalcost () { Return Component.gettotalcost (); } Public string getdescription () { Return Component.getDescription (); } } Class extraespresso eXtends decorator { Private float cost = 0.75F; Public Extraespresso (DrinkComponent Component) { Super (Component); } Public string getdescription () { Return Component.getdescription () "extra Espresso"; } Public float gettotalcost () { Return Cost Component.gettotalcost (); } } Class whipped extends decorator { Private float cost = 0.50f; Public whipped (DrinkComponent Component) { Super (Component); } Public float gettotalcost () { Return Cost Component.gettotalcost (); } Public string getdescription () { Return Component.getdescription () "whipped cream"; } } Class Decaf Extends Decorator { Public Decaf (DrinkComponent Component) { Super (Component); } Public string getdescription () { Return Component.getDescription () "DECAF"; } } Class Dry Extends Decorator { Public Dry (DrinkComponent Component) { Super (Component); } Public string getdescription () { Return Component.getdescription () "Extra Foamed Milk"; } } Class Wet Extends Decorator { Public Wet (DrinkComponent Component) { Super (Component); } Public string getdescription () { Return Component.getdescription () "extra steamed milk"; } } Public class coffeeeshop3 extends testcase { Public void testcappuccino () {// this Just Makes Sure IT Will Complete // WITHOUT THROWING AN Exception. // Create a Plain Cappucino DrinkComponent cappuccino = new cappuccino (); System.out.println (Cappuccino.GetDescription () ": $" cappuccino.gettotalcost ()); } Public void testcafemocha () { // this Just Makes Sure IT Will Complete // WITHOUT THROWING AN Exception. // Create a Decaf cafe mocha with whipped // cream DrinkComponent Cafemocha = new whipped New decaf (new cafemocha ())); System.out.println (cafemocha.getdescription () ": $" cafemocha.gettotalcost ()); } Public static void main (String [] args) { JUnit.textui.testrunner.run (Coffeeeshop3.class); } } ///: ~ You can see that the Basic Selection is very fast and simple because the basic drinks become a routine work. Description Add a partner's drink (DRINK) is more troublesome than each combination, however, it is obvious that it is much simpler than only using Decorator mode. The final result is that there is not too much class, and like it is not too much coffee partner (Decorators). In most cases, we have encountered the situation that does not add partners so that we can benefit from the above two methods. Other consideration Other considitys If we intend to change the menu later, if you add a new type of drink, what happens? If we use each combination of the method corresponding to a class, add an additional drink (such as syrup syrup) will result in an exponential growth of the number of classes. However, for the method of using Decorator and the above-mentioned method, you only need to create an additional class. When the milk increases, if we change the price of Steamed Milk and Foamed Milk, what is the impact? If each combination corresponds to a class, you have to change all classes (GetCost) methods, so that there are very many classes of maintenance. By using Decorators, as long as the logic code in a local maintenance (price change) is available. Exercise 1. Use the above Decorator method to add a Syrup class. Then create a syrup that adds Café latte (you have to use Steamed Milk and Espresso). 2. Use "Fold" to re-practice the practice 1.3. Write a simple system, use the Decorator mode to simulate the following: Some birds will fly there will be some will not, some birds will useful and some do not Will, there are some way to fly and swim. 4. Wrote a PIZZA restaurant with Decorator mode, which provides the optional basic menu, also allow you to customize PIZZA. Write a menu with "Fold" to write a menu including Margherita, Havaiian, Regina and Vegetarian Pizza (anyway, Pizza variety), and toppings (Toppings, Decorator) Garlic Garlic, Olives, Spinach Spinach, avocado? AvoCade. Cheese Feta, Pepper? PepperDews. Write a Hawaiian Pizza, write a Margherita Pizza.5 added to the spinach, cheese, and pepper. About Decorator mode, "Design Mode" book is said: "ATTCHING or DETACHING decoration (Decorators), you can add or go to responseibilities in running time (Run-Time). Write a coffee Decoration system, which can remove a function from a series of additives of a complex coffee beverage (Decorators). table of Contents