Issott_Common Design Patterns for Symbian OS-The Foundations of Smartphone Software_0470516356 (779879), страница 65
Текст из файла (страница 65)
This may be done in cases where the UIdependencies are extensive and cannot be decoupled from the eventhandling of the controller.Java developers are likely also to have encountered Document–View, although as [Cooper, 2000, pp. 3–4] notes, the original JavaSwing implementation in version 1.2 uses the full MVC pattern for itscomponents (e.g. JTable and JList).References• This pattern builds on Observer [Gamma et al., 1994] to allow thethree main classes to stay aligned whilst allowing them to remaindecoupled.• For more information on the standard industry view of MVC, seeen.wikipedia.org/wiki/Model-view-controller .• For a general background on GUI architectures, see martinfowler.com/eaaDev/uiArchs.html .• The Sony Ericsson developer website provides guidance on porting S60 applications to UIQ at developer.sonyericsson.com/site/global/techsupport/tipstrickscode/symbian/p− automatic− conversion− of− series− 60− projects.jsp.• The Forum Nokia website provides guidance on porting UIQ applications to S60 at www.forum.nokia.com/search/?keywords=porting+uiq .346MAPPING WELL-KNOWN PATTERNS ONTO SYMBIAN OSSingletonIntentEnsure a class has only one instance and provide a global point of accessto it.AKAHighlander12ProblemContextYou wish to ’ensure a class only has one instance and provide a globalpoint of access to it.’ [Gamma et al., 1994]Summary• A single instance of a class is required by a component or even thewhole system.
For example, to provide a single point of access to aphysical device, such as a camera, or to a resource or resource pool,such as a logging object, a thread or a block of memory.13• A way of synchronizing access to the single instance may be neededif you wish it to be in scope for different parts of a system and used byseveral threads or processes.• Instantiation of the object should controllable. Instantiation shouldeither be deferred until the first time it is needed, or the objectshould be instantiated in advance of other objects, to ensure a particular order of initialization.DescriptionThis pattern is one of the simplest design patterns and arguably themost popular pattern found in [Gamma et al., 1994].
Hence in thisdiscussion, rather than examine the pattern in itself, we place emphasison how to implement it on Symbian OS, covering a range of differentcircumstances. For detailed discussion of the pattern itself covering, forexample, the overall consequences of the pattern or how to subclass asingleton class, please see [Gamma et al., 1994].The pattern involves just one class that provides a global point ofaccess to a single instance, which instantiates itself, either using Immortal(see page 53) or Lazy Allocation (see page 63).
However, there is a basic12Thanks to Mal Minhas and Mark Jacobs for this alternative name, which is inspired bythe movie of the same name, the tag of which is ‘There can be only one’.13 See Pooled Allocation [Weir and Noble, 2000].SINGLETON347problem for developers working on Symbian OS, which is its incompletesupport for writable static data in DLLs. To explain the issue, we mustdigress briefly: first of all, to discuss what we mean by ‘incomplete supportfor writable static data’ and then to explain why it’s a big deal.The Writable Static Data Restriction on Symbian OSFor the purposes of this discussion, writable static data (WSD) is anymodifiable globally-scoped variable declared outside of a function andany function-scoped static variable.WSD was not allowed in DLLs built to run on target devices based onSymbian OS v8.1a or earlier.14 For an explanation of how this limitationcame about, see [Willee, Nov 2007] and [Stichbury, 2004].
WSD hasalways been allowed in EXEs but, prior to Symbian OS v9, this was oflittle help to application developers because applications were built asDLLs.With the advent of Symbian OS v9, the situation changed for thebetter. The use of WSD in target DLLs is now possible. However, becauseit can be expensive in terms of memory usage, it is not recommendedwhen writing a shared DLL that is intended to be loaded into a numberof processes.
This is because WSD in a DLL typically consumes 4 KB ofRAM for each process which loads the DLL.When a process loads its first DLL containing WSD, it creates a singlechunk to store the WSD. The minimum size of a chunk is 4 KB, since thisis the smallest possible page size, so at least that amount of memory isconsumed, irrespective of how much static data is actually required. Anymemory not used for WSD is wasted.15Since the memory is per process, the potential memory wastage is:16(4 KB − WSD bytes) × number of client processesIf, for example, a DLL is used by four processes, that’s potentially an‘invisible’ cost of almost 16 KB since the memory occupied by the WSDitself is usually in the order of bytes.Furthermore, DLLs that use WSD are not fully supported by theSymbian OS emulator that runs on Windows.
Because of the way theemulator is implemented on top of Windows, it can only load a DLLwith WSD into a single emulated process. If a second emulated processattempts to load the same DLL on the emulator, it will fail with KErrNotSupported.1714 SeeTable 9.2 for the corresponding versions of S60 and UIQ.if subsequent DLLs are loaded into the same process and also use WSD, thesame chunk is used, rather than a separate chunk (at least another 4 KB) for every DLL.16Assuming you don’t use more than 4 KB of WSD.17 Symbian OS v9.4 introduces a workaround (see [Willee, Nov 2007] for a more advanceddiscussion).15 However,348MAPPING WELL-KNOWN PATTERNS ONTO SYMBIAN OSThere are a number of occasions where the benefits of using WSD ina DLL outweigh the disadvantages; for example, when porting code thatuses WSD significantly and for DLLs that will only ever be loaded intoone process.
As a third-party developer, you may find the memory costsof WSD acceptable if you create a DLL that is intended only to be loadedinto a single application. However, if you are working in device creation,perhaps creating a shared DLL that ships within Symbian OS, one of theUI platforms, or on a phone handset, the trade-offs are different.
YourDLL may be used by a number of processes and the memory costs andconstraints are such that using WSD is less likely to be justifiable.Application developers are no longer affected as severely by thelimitation, because a change in the application framework architecturein Symbian OS v9 means that all applications are now EXEs rather thanDLLs.
Writable static data has always been allowed in EXEs built fortarget devices, so an application developer can use WSD if it is required.Table 9.2 summarizes the support for WSD in DLLs and applications onvarious versions of the Symbian UI platforms.Table 9.2 WSD Support Across Versions of Symbian OS and GUI VariantsUI PlatformSymbian OSversionUIQ 2.xv7.0S60 1st and 2ndEditionsv6.1, v7.0s,v8.0a, v8.1aUIQ 3v9.xS60 3rd EditionWSD allowed in DLLs?WSD allowedin applications?NoNoYes, but notrecommended due tothe limitations on theWindows emulatorand potentially largememoryconsumption.Yes, sinceapplicationsare EXEs.Why Is the Limitation on WSD a Problem when Implementing Singleton?Figure 9.4 shows the UML diagram for a typical Singleton.The classic implementation of the Singleton pattern in C++ uses WSD,as shown below:class Singleton{public:static Singleton* Instance();// Operations supplied by SingletonSINGLETON349private:Singleton(); // Implementation omitted for clarity∼Singleton(); // Implementation omitted for clarityprivate:static Singleton* pInstance_; // WSD};/*static*/ Singleton* Singleton::pInstance_ = NULL;/*static*/ Singleton* Singleton::Instance(){if (!pInstance_)pInstance_ = new Singleton;return (pInstance_);}Singleton−pInstance_: *+Instance() : Singleton*Figure 9.4returns plnstance_UML diagram for a typical SingletonBecause of the constraint on the use of WSD, the classic implementation of Singleton cannot be used in DLLs before Symbian OS v9.18 Analternative implementation, which we’ll discuss shortly, must be usedinstead.
This alternative is also recommended when writing DLLs fornewer versions of Symbian OS that do allow WSD in DLLs, simply toavoid unnecessary waste of memory and to enable complete testing onthe Windows emulator.However, let’s have another brief digression and discuss the classiccode above. As you can see, the singleton object effectively owns andcreates itself. The code required to instantiate Singleton is private,so client code cannot create the singleton instance directly. Only thestatic function Instance(), which is a member of the class, can createpInstance_ and it does so the first time that it is called.