| ////////////////////////////////////////// |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| |
| ////////////////////////////////////////// |
| |
| = Flyweight Pattern |
| |
| The http://en.wikipedia.org/wiki/Flyweight_pattern[Flyweight Pattern] is a pattern for greatly reducing memory requirements by not requiring that heavy-weight objects be created in large numbers when dealing with systems that contain many things that are mostly the same. If for instance, a document was modelled using a complex character class that knew about unicode, fonts, positioning, etc., then the memory requirements could be quite large for large documents if each physical character in the document required its own character class instance. Instead, characters themselves might be kept within Strings and we might have one character class (or a small number such as one character class for each font type) that knew the specifics of how to deal with characters. |
| |
| In such circumstances, we call the state that is shared with many other things (e.g. the character type) __instrinsic__ state. It is captured within the heavy-weight class. The state which distinguishes the physical character (maybe just its ASCII code or Unicode) is called its __extrinsic__ state. |
| |
| == Example |
| |
| First we are going to model some complex aircraft (the first being a hoax competitor of the second - not that is relevant to the example). |
| |
| |
| [source,groovy] |
| ---- |
| include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=flyweight_boeing797,indent=0] |
| ---- |
| |
| image::assets/img/b797-hoax.jpg[] |
| |
| [source,groovy] |
| ---- |
| include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=flyweight_airbus380,indent=0] |
| ---- |
| |
| image::assets/img/a380.jpg[] |
| |
| If we want to model our fleet, our first attempt might involve using many instances of these heavy-weight objects. It turns out though that only a few small pieces of state (our extrinsic state) change for each aircraft, so we will have singletons for the heavy-weight objects and capture the extrinsic state (bought date and asset number in the code below) separately. |
| |
| [source,groovy] |
| ---- |
| include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=flyweight_factory,indent=0] |
| ---- |
| |
| So here, even if our fleet contained hundreds of planes, we would only have one heavy-weight object for each type of aircraft. |
| |
| As a further efficiency measure, we might use lazy creation of the flyweight objects rather than create the initial map up front as in the above example. |
| |
| Running this script results in: |
| |
| ---- |
| Asset Number: 1001 |
| Capacity: 555 people |
| Speed: 912 km/h |
| Range: 10370 km |
| Bought: 10-May-2007 |
| |
| Asset Number: 1002 |
| Capacity: 555 people |
| Speed: 912 km/h |
| Range: 10370 km |
| Bought: 10-Nov-2007 |
| |
| Asset Number: 1003 |
| Capacity: 1000 people |
| Speed: 1046 km/h |
| Range: 14400 km |
| Bought: 10-May-2008 |
| |
| Asset Number: 1004 |
| Capacity: 1000 people |
| Speed: 1046 km/h |
| Range: 14400 km |
| Bought: 10-Nov-2008 |
| ---- |