One of the iOS design patterns (mvc mode, Singleton Mode)
Source: Internet
Author: User
<span id="Label3"> </p>In the original text, see: Http://www.raywenderlich.com/46988/ios-design-patterns. translated by @krq_tiger (http://weibo.com/xmuzyq), If you find any translation errors, please contact me thank you. iOS Design patterns-you may have heard the word, but do you really understand what it means? While most developers may think design patterns are important, there are few articles on the topic of design patterns, and sometimes our developers don't pay much attention to it when they write Code. In the field of software design, design patterns are reusable solutions to common Problems. Design patterns are a series of templates that help you write more understandable and reusable code, and design patterns help you create loosely coupled code so that you can change or replace components in your code without much Effort. If you are new to design mode, we have good news to tell you! first, thanks to the way cocoa is built, you've used a lot of design patterns and encouraged best practices. second, This guide will take you through the most (not all) ios design patterns used frequently in Cocoa. This guide is divided into a number of sections, each of which involves a design pattern. In each section, you will learn what the: design pattern is, as Follows: Why do you use design mode? How to use design patterns, and when used, where is appropriate, where is the pit to be noticed. In this guide, you will create a music library app that will display your albums and their associated Information. During the development of this application, you will be familiar with the extensive use of cocoa design patterns: creation: simple interest (mono) and abstract factory structure: model-view-controller, adorner, adapter, appearance (façade) and combination mode behavioral: observer, memo, Responsibility chain and Command mode don't be misled into thinking that this is an article on design pattern theory, you will use most of these design patterns in this music application, and eventually your music app will look like the one shown:<br><br><strong><strong>Let's get started! </strong></strong>Download Starter project, Export the contents of the zip file, and then use Xcode to open the bluelibrary.xcodeproj. there are not too many files in the project, only the default Viewcontroller and the null implemented HTTP Client. note: When you create a new Xcode project, your code actually involves the design pattern, you know? models-views-controllers, delegates, protocols, singleton-you can use them free of charge. Before you dive into the first design pattern, you must first create two classes that use these two classes to save and display information about your music library Albums. In xcode, navigate to "file\new\file ..." (or press command+n shortcut), Select Ios>cocoa Touch, then Objective-c class and click Next. Set the class name to album, Select NSObject for the parent class, click next, and then Create. Open the Album.h file, and add the following properties and method prototypes between @interface and @end: objective-c code <ol class="dp-default" start="1"> <ol class="dp-default" start="1"> <li>@property (nonatomic, copy, readonly) nsstring *title, *artist, *genre, *coverurl, *year;</li> <li>-(id) initwithtitle: (nsstring*) title artist: (nsstring*) artist coverurl: (nsstring*) coverurl year: (nsstring*) year;</li> </ol> </ol><p><p><br><br></p></p>Notice that all the properties in the new code are read-only, because after the album object is created, you do not need to modify their values. The new method is Object initializer, when you create a new album (album) object, you need to pass the album (album) name, artist, album cover url, and Year. Now open the ALBUM.M file and add the following code between @implementation and @end: objective-c code <ol class="dp-default" start="1"> <li><li>-(id) initwithtitle: (nsstring*) title artist: (nsstring*) artist Coverurl: (nsstring*) Coverurl</li></li> <li><li>Year: (nsstring*) Year {</li></li> <li><li>Self = [super init];</li></li> <li><li>If (self)</li></li> <li><li>{</li></li> <li><li>_title = title;</li></li> <li><li>_artist = artist;</li></li> <li><li>_coverurl = coverurl;</li></li> <li><li>_year = year;</li></li> <li><li>_genre = @<span class="string">"Pop"; </span></li></li> <li><li>}</li></li> <li><li>Return self;</li></li> <li><li>}</li></li> </ol><p><p></p></p>There's Nothing fancy here, It's just an initialization method that creates a album Instance. In xcode, once again navigate to "file\new\file ..." Select Cocoa Touch, then Objective-c class and click Next. Set the class name to albumview, but this time set the parent class to UIVIEW. Click Next and click Create. Note: If you find that keyboard shortcuts are easier to use, Command+n will create a new file, command+option+n will create a new group, command+b will build your project, and Command + R will run it. Now open AlbumView.h, Add the following method prototype between the @interface and the @end: objective-c code <ol class="dp-default" start="1"> <ol class="dp-default" start="1"> <li>-(id) initwithframe: (cgrect) frame albumcover: (nsstring*) albumcover;</li> </ol> </ol>Now open albumview.m, Replace all code after @implementation with the following code: objective-c code <ol class="dp-default" start="1"> <li><li>@implementationAlbumView</li></li> <li><li>{</li></li> <li><li>Uiimageview *coverimage;</li></li> <li><li>Uiactivityindicatorview *indicator;</li></li> <li><li>}</li></li> <li><li></li></li> <li><li>-(id) initwithframe: (cgrect) frame albumcover: (nsstring*) albumcover</li></li> <li><li>{</li></li> <li><li>Self = [super initwithframe:frame];</li></li> <li><li>If (self)</li></li> <li><li>{</li></li> <li><li></li></li> <li><li>Self.backgroundcolor = [uicolor blackcolor];</li></li> <li><li>The Coverimage have a <span class="number">5 pixels margin</span> from its frame</li></li> <li><li>Coverimage = [[uiimageview alloc] initwithframe:cgrectmake (<span class="number">5, <span class="number">5, frame.size.width-<span class="number">,</span> </span> </span></li></li> <li><li></li></li> <li><li>frame.size.height-<span class="number">10)]; </span></li></li> <li><li>[self addsubview:coverimage];</li></li> <li><li></li></li> <li><li>Indicator = [[uiactivityindicatorview alloc] init];</li></li> <li><li>Indicator.center = self.center;</li></li> <li><li>Indicator.activityindicatorviewstyle = uiactivityindicatorviewstylewhitelarge;</li></li> <li><li>[indicator startanimating];</li></li> <li><li>[self addsubview:indicator];</li></li> <li><li>}</li></li> <li><li>Return self;</li></li> <li><li>}</li></li> <li><li></li></li> <li><li>@end</li></li> </ol><p><p><br><br></p></p>In the above code, the first thing you need to notice is the Coverimage instance Variable. It represents the cover picture of the Album. The second variable is an indicator that the cover map is being downloaded by Rotation. In the implementation of the initializer you set the background color to black, create a picture view with a 5-pixel border, and create an Indicator. Note: You may wonder why private variables are defined in the implementation file, not in the interface file? This is because classes other than albumview do not need to know the existence of these variables, which are only used within the class intrinsic functions. This Convention is important if you are developing a framework for use by other Developers. Build (Command + B) your project makes sure everything is in order, ok? Then prepare for our first design pattern!<strong><strong>Model-view-controller (MVC) mode-king of design Patterns</strong></strong><br><br>Model-view-controller (MVC) is one of the building blocks of cocoa, and it is no doubt that it is the most frequently used design Pattern. It classifies categories according to General roles, so that the responsibilities of a class can be clearly divided by role. The three roles involved are as follows: Model: models Save the Application's data and define how to manipulate it. For example, in this application the model is the album class. View: views are visual representations of the model and controls for user interaction; basically, all UIView objects and their subclasses belong to the VIEW. Albumview represents a view in this Application. Controller: the director is a mediator (mediator) that coordinates all Work. It accesses the data in the model and displays them in the view, while they also listen for events and manipulate the data as Needed. Can you guess which class is the controller? It is exactly: viewcontroller. A good implementation of an MVC pattern means that each object is divided into the group mentioned Above. We can well describe the interaction of the View-to-model implemented by the Controller:<br><br>The model notifies the controller of any changes to the data, and then the controller updates the view Data. The View object notifies the controller user of the action, and the controller either updates the model as needed or retrieves any requested Data. You might wonder why it's easier to implement views and models in a class just by using a controller? All of this is due to the separation and reuse of code Concerns. In an ideal state, the view should be completely detached from the Model. If a view is not dependent on a real model, The view can be reused to present data from different models. For example, if you're going to add movies or books to your database in the future, you can still use the same albumview to show movies and book Data. further, If you want to create a new project that is associated with the album, you can easily reuse the album class because it does not depend on any VIEW. This is where MVC is Powerful.<strong><strong>How to use the MVC pattern</strong></strong>first, you need to make sure that each class in your project is one of the controllers, models, and views, and do not combine the functions of two roles in one class. So far, You've created a album class and a Albumview class, which is good. second, to ensure that you can fit this approach, you should create three engineering groups (project Group) to hold your code, and each project group will have only one type of Code. Navigate to file \ New \ Group (file\new\group) (or Press COMMAND + Option + N), The named group is model, and repeat the same procedure to create the view and controller Groups. Now drag Album.h and ALBUM.M to the model group, drag AlbumView.h and albumview.m to the view group, and finally drag ViewController.h and VIEWCONTROLLER.M to the controller Group. At this point the engineering structure should look and resemble:<br><br>All the files are scattered all over the time, and now your project has been opened up much better. Obviously you can also have other groups and classes, but the core of this application is contained in these three categories (model,view,controller). Now that all the components have been set up, you need to get the album data from Somewhere. You will create a api-of management data that runs through the Code. this also represents the opportunity to discuss the next design Pattern-singleton (single State) mode.<strong><strong><br></strong></strong><strong><strong>Singleton (single-state) Mode</strong></strong>The singleton design pattern ensures that only one instance of a given class exists, and that the instance has a globally unique access Point. It usually uses lazy loading to create it the first time it is Used. Note: This mode is used extensively by Apple. For example: [nsuserdefaults standarduserdefaults],[uiapplication sharedapplication], [uiscreen mainScreen], [NSFileManager defaultmanager], all of these methods return a singleton object. You'll probably wonder why You're so Concerned. is there more than one instance of a class? After all, the code and the memory are cheap, right? In some cases, only one instance seems very reasonable. For example, you don't need to have multiple instances of logger unless you want to write multiple log files. Or a global configuration processing class: It is easy to implement Thread-safe access to shared instances, such as a configuration file, with many classes modifying the file at the same time.<strong><strong>How to use singleton mode</strong></strong>first, take a look at the following figure:<br><br>The diagram above depicts a class with a single attribute (which is a single instance) and a sharedinstance,init of two methods. When the client sends the SHAREDINSTANCE message for the first time, the instance property has not been initialized, so you need to create a new instance and return its reference. The next time you call sharedinstance, instance does not need any initialization to return immediately. This logic guarantee always has only one instance. You will then use this pattern to create a class that manages all the album Data. You will notice that there is a group of APIs in the project where you can put all the classes that provide services to your app. In this group, create a new class with the Ios\cocoa touch\objective-c class template, name it libraryapi, Set the parent class to Nsobject. open LibraryAPI.h, replacing its contents with the following code: objective-c code <ol class="dp-default" start="1"> <ol class="dp-default" start="1"> <li>@interfaceLibraryAPI: NSObject</li> <li></li> <li>+ (libraryapi*) sharedinstance;</li> <li></li> <li>@end</li> </ol> </ol><p><p></p></p>Now open libraryapi.m, and insert the following method after the @implementation line: objective-c code <ol class="dp-default" start="1"> <li><li>+ (libraryapi*) Sharedinstance</li></li> <li><li>{</li></li> <li><li><span class="number">1</span></li></li> <li><li>static Libraryapi *_sharedinstance = nil;</li></li> <li><li></li></li> <li><li><span class="number">2</span></li></li> <li><li>Static dispatch_once_t oncepredicate;</li></li> <li><li></li></li> <li><li><span class="number">3</span></li></li> <li><li>Dispatch_once (&oncepredicate, ^{</li></li> <li><li>_sharedinstance = [[libraryapi alloc] init];</li></li> <li><li>});</li></li> <li><li>Return _sharedinstance;</li></li> <li><li>}</li></li> </ol><p><p></p></p>In this short approach, there are some points to note: 1. Declare a static variable to hold an instance of the class, ensuring its global availability in the CLASS. 2. Declare a static variable dispatch_once_t, which ensures that the initializer code executes only once 3. use Grand Central Dispatch (GCD) to perform a block that initializes the Libraryapi Variable. this It is the key to the singleton Pattern: once the class has been initialized, the initializer will never be called Again. The next time you call sharedinstance, the code in the Dispatch_once block will not execute (because it has been executed Once) and you will get an instance of the original already initialized. Note: in order to learn more about GCD and how it is used, please see the site Guide multithreading and Grand Central Dispatch and how to use Blocks. You now have a singleton object as an entry for managing your album Data. Let's go a step further to create a class that handles database data persistence. In the API group, create a new class using the Ios\cocoa touch\objective-c class template, name it persistencymanager, and set the parent class to Nsobject. open PersistencyManager.h Add the following import statement to the file header: #import "Album.h" next, after the @interface of the PersistenceManager.h file, add the following code: objective-c code <ol class="dp-default" start="1"> <ol class="dp-default" start="1"> <li>-(nsarray*) getalbums;</li> <li>-(void) addalbum: (album*) Album atindex: (int) index;</li> <li>-(void) deletealbumatindex: (int) index;</li> </ol> </ol><p><p><br><br></p></p>The above is the prototype of the method you need to process the album Data. Open the PERSISTENCYMANAGER.M file, and add the following code before the @implementation line: objective-c code <ol class="dp-default" start="1"> <ol class="dp-default" start="1"> <li>@interfacePersistencyManager () {</li> <li>An array of all albums</li> <li>Nsmutablearray *albums;</li> <li>}</li> </ol> </ol><p><p></p></p>The above adds a class extension, which is another way to add private methods and variables so that the outer class will not see Them. here, you declare an array of Nsmutablearry to save the album Data. This array is variable to facilitate you to add and delete Albums. Now add the following code after @implementation the line in the PERSISTENCYMANAGER.M file: objective-c code <ol class="dp-default" start="1"> <li><li>-(id) Init</li></li> <li><li>{</li></li> <li><li>Self = [super init];</li></li> <li><li>If (self) {</li></li> <li><li>A dummy list of albums</li></li> <li><li>Albums = [nsmutablearrayarraywitharray:</li></li> <li><li>@[[[album alloc] initwithtitle:@<span class="string">"best of Bowie" artist:@<span class="string">"David Bowie" coverurl:@<span class="string">"/http Www.coversproject.com/static/thumbs/album/album_david%20bowie_best%20of%20bowie.png "year:@"<span class="string">1992 "],</span> </span></span></span></li></li> <li><li>[[Album alloc] initwithtitle:@<span class="string">"It's My life" artist:@<span class="string">"No doubt" coverurl:@ "<span class="string">http://www.coversproject.com/ Static/thumbs/album/album_no%20doubt_its%20my%20life%20%20bathwater.png "year:@"<span class="string">2003 "],</span> </span> </span> </span></li></li> <li><li>[[Album alloc] initwithtitle:@ "nothing like the<span class="string">Sun" artist:@<span class="string">"Sting" coverurl:@<span class="string">"http// Www.coversproject.com/static/thumbs/album/album_sting_nothing%20like%20the%20sun.png "year:@"<span class="string">1999 "],</span> </span></span></span></li></li> <li><li>[[Album alloc] initwithtitle:@<span class="string">"staring at the Sun" artist:@ "U2" coverurl:@ "http://www.coversproject.com/<span class="string"><span class="string"> Static/thumbs/album/album_u2_staring%20at%20the%20sun.png "year:@"<span class="string">],</span> </span> </span> </span></li></li> <li><li>[[Album alloc] initwithtitle:@<span class="string">"American Pie" artist:@<span class="string">"Madonna" coverurl:@ "<span class="string">http://www.coversproject.com/ Static/thumbs/album/album_madonna_american%20pie.png "year:@<span class="string">" 2000 "]]; </span></span></span></span></li></li> <li><li>}</li></li> <li><li>Return self;</li></li> <li><li>}</li></li> </ol><p><p></p></p>In init, you populate the array with five sample Albums. If you don't like the album above, you're free to replace them with your favorite albums. Now add the following three methods in the PERSISTENCYMANAGER.M file: objective-c code <ol class="dp-default" start="1"> <ol class="dp-default" start="1"> <li>-(nsarray*) Getalbums</li> <li>{</li> <li>Return albums;</li> <li>}</li> <li></li> <li>-(void) addalbum: (album*) Album atindex: (int) Index</li> <li>{</li> <li>If (albums.count >= Index)</li> <li>[albums Insertobject:album atindex:index];</li> <li>Else</li> <li>[albums addobject:album];</li> <li>}</li> <li></li> <li>-(void) deletealbumatindex: (int) Index</li> <li>{</li> <li>[albums removeobjectatindex:index];</li> <li>}</li> </ol> </ol><p><p></p></p>These methods allow you to add and remove Albums. Building your project ensures that every resource can be compiled correctly. At this time, you may want to know where the Persistencymanager class comes from? Because it is not a singleton class. In the next section, we will explore the relationship between Libraryapi and persistencymanager, when you will see the façade or appearance (facade) Pattern.<p><p>One of the iOS design patterns (mvc mode, Singleton Mode)</p></p></span>
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.
A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service