iOS

iOS Tasarım Kalıpları (Design Patterns)- 1

Birçoğunuzun başlıktaki konu hakkında bilgisi mutlaka vardır. Tasarım kalıplarınınher ne kadar çok önemli olduğu söylense de bu konuyla ilgili çok ilgi çekici kaynaklar bulamıyoruz. Bunun nedenlerinden biri de geliştiricilerin buna çok vakit ayırmaması ve ilgi duymaması diye...

Abdulbasıt Tanhan |

09.05.2014

 

Birçoğunuzun başlıktaki konu hakkında bilgisi mutlaka vardır. Tasarım kalıplarının her ne kadar çok önemli olduğu söylense de bu konuyla ilgili çok ilgi çekici kaynaklar bulamıyoruz. Bunun nedenlerinden biri de geliştiricilerin buna çok vakit ayırmaması ve ilgi duymaması diyebiliriz. Bu bloğu yazarak biraz konunun içerisine girme fırsatı bulmak, beni motive eden faktörlerden biriydi.

Tasarım kalıpları (Design Patterns) yazılım alanında benzer ve sıkça karşılaşılan problemlere verilen tekrar kullanılabilir çözümlerdir. Bunların birçoğu ve benim bildiklerim, nesne yönelimli yazılım alanında kullanılanlardır. Bu blog yazısında iOS ve Cocoa kütüphanesinde kullanılan tasarım kalıplarından bahsetmek istedim. Daha geniş ve ayrıntılı olarak incelemek isterseniz, Apple Developer belgelerinden faydalanabilirsiniz.

Cocoa Design Pattern'lerinin başlıklarını aşağıdaki gibi sıralayabiliriz;

  • Creational Patterns
    • Singleton
    • Abstract Factory
  • Structural Patterns
    • MVC - Modal View Controller
    • Decorator
    • Adapter
    • Facade
    • Composite
  • Behavioral Patterns
    • Observer
    • Memento
    • Chain of Responsibility
    • Command

 

İlk örnek uygulama

Şimdi bu patternleri bir Movie uygulaması hazırlayarak ve pratiğe dökerek açıklayalım:

Xcode açarak yeni proje seçeneklerinden Single View Application şablonunu seçin ve MovieArchive adındaki projemize başlayalım. 

Şimdi Movie adında bir sınıf oluşturun ve NSObject'in alt sınıfı haline getirin.

Movie.h dosyasını açın ve aşağıdaki satırları ekleyin.

[cpp]#import 

@interface Movie : NSObject

@property (nonatomic, copy, readonly) NSString *title, *genre, *coverUrl, *year;

- (id)initWithTitle:(NSString*)title coverUrl:(NSString*)coverUrl year:(NSString*)year;

@end
[/cpp]

Movie.m dosyasını açarak @implementation ve @end arasında aşağıdaki kodu ekleyin.

[cpp]- (id)initWithTitle:(NSString*)title director:(NSString*)director coverUrl:(NSString*)coverUrl year:(NSString*)year
{
    self = [super init];
    if (self)
    {
        _title = title;
        _director = director;
        _coverUrl = coverUrl;
        _year = year;
        _genre = @"Drama";
    }
    return self;
}[/cpp]

Sonrasında MovieView adında bir sınıf oluşturun ve altsınıf olarak UIView seçin.

MovieView.h dosyasını açarak @interface ve @end arasına aşağıdaki satırı ekleyin.

​[cpp]- (id)initWithFrame:(CGRect)frame movieCover:(NSString*)movieCover;[/cpp]

MovieView.m dosyasını açarak @implementation kısmını aşağıdaki kodla değiştirin.

​[cpp]@implementation MovieView
{
    UIImageView *coverImage;
    UIActivityIndicatorView *indicator;
}

- (id)initWithFrame:(CGRect)frame movieCover:(NSString*)movieCover
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.backgroundColor = [UIColor blackColor];
        // the coverImage has a 5 pixels margin from its frame
        coverImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, frame.size.width-10, frame.size.height-10)];
        [self addSubview:coverImage];
        
        indicator = [[UIActivityIndicatorView alloc] init];
        indicator.center = self.center;
        indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
        [indicator startAnimating];
        [self addSubview:indicator];
    }
    return self;
}

@end
[/cpp]

coverImage filmlerimizin afişlerini gösterecek. indicator film afişleri netten indirilip gösterilene kadar view üzerinde dönecek.

Artık hazırsak patternlere giriş yapalım.

 

MVC - Modal View Controller

MVC kuşkusuz Cocoa'da en çok kullanılan design pattern. Aynı zamanda MVC iOS'un temel tasarım stratejisi. Genel anlamda uygulamanızda sınıfların nasıl organize olacağı ile ilgilenir. Bu sınıfları Model, View ve Controller olarak üç kampa ayrırabiliriz. 

  • Model; Uygulamanın temel anlamda ne olduğunu içerir, görünüm ile ilgilenmez, uygulamanın verilerini tutar. Bizim uygulamamızda modelimiz Movie sınıfı olacak.
  • View; Modelin görsel sunumundan sorumludur ve kullanıcının etkileşimde olacağı alanı içerir. Bizim uygulamamızda view MovieView sınıfı olacak.
  • Controller; Model ve View arasındaki iletişimi ve kontrolü sağlar. Verileri modelden alır ve View objeleriyle ekrana yansıtır. Burada bizim controller'ımız ViewController olacak.

Aşağıdaki resimden görebileceğiniz gibi Model ve View sarı ve sürekli çizgilerle ayrılmış. Doğru bir yapıda Model ve View hiçbir şekilde iletişimde olmamalı.

Model'de değişen bir veri Notification veya Key Value Observer ile bir radyo sinyali yayar gibi uygulamaya haber verir. Bu sinyali dinleyen Controller sinyali alarak değişen verilerle View'ı günceller.

iOS projelerinde sınıfları bu tasarıma uygun şekilde gruplamak yaygın bir kullanım şeklidir.

New Group diyerek Model, View, Controller grupları oluşturun ve sınıflarınızı uygun gruplara taşıyın.

 

Singleton

Singleton pattern'i bize bir sınıfın sadece bir örneğinin var olduğundan emin olmamızı sağlar. Ayrıca bu sınıfa erişmek için global bir erişim noktası sunar. iOS'ta kullanılan singleton sınıflara aşağıdaki örnekleri verebiliriz.

[cpp][NSUserDefaults standardUserDefaults];
[UIApplication sharedApplication];
[UIScreen mainScreen];
[NSFileManager defaultManager];[/cpp]

Örneğin aşağıdaki resim bir Logger sınıfını gösteriyor. Bir property ve iki method'tan oluşuyor. Uygulama sharedInstance'a mesaj gönderir ve instance oluşmamış ise yeni bir instance yaratarak kendini döndürür. Tekrar sharedInstance çağrıldığında instance daha önce oluşturulduğu için sınıfın yaratılma kısmını atlayıp, daha önce yaratılan instance'ı döndürecektir. 

Projemiz için bir singleton sınıf yaratalım. Öncelikle bu bir API olacağından API adında bir grup oluşturup altında ArchiveAPI adında bir sınıf yaratalım ve altsınıf olarak NSObject seçelim.

ArchiveAPI.h dosyasına aşağıdaki satırı ekleyiniz.

[code]@interface ArchiveAPI : NSObject

+ (ArchiveAPI*)sharedInstance;

@end[/code]

Daha sonra bu metodu ArchiveAPI.m dosyasında implement edip içini dolduralım.

[code]@implementation ArchiveAPI

+ (ArchiveAPI*)sharedInstance{
    
}

@end[/code]

Xcode code snippets kısmında singleton yazdığınızda size hazır bir kod parçası getirecektir. Bunu ArchiveAPI.m dosyasına sürekleyerek singleton metodunuz oluşturabilirsiniz.

Şimdi eksik satırları aşağıdaki gibi tamamlayalım.

[code]@implementation ArchiveAPI

+ (ArchiveAPI*)sharedInstance{
    
    //1
    static ArchiveAPI *_sharedInstance;
    
    //2
    static dispatch_once_t onceToken;
    
    //3
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[ArchiveAPI alloc] init];
    });
    
    return _sharedInstance;
}

@end[/code]
  1. Sınıfınızın örneğini tutun static bir değişken yarattık.
  2. dispatch_one_t tipinde bir değişken yarattık. Bu değişken sınıfın örneğini bir kere oluştuğundan emin olmak için gerekecek.
  3. Grand Central Dispatch (GCD) kullanarak bir block çalıştırıyoruz ve ArchiveAPI sınıfımızı oluşturuyoruz.

sharedInstance metodunu çağırdığınızda dispatch_once içerisindeki blok daha önce çalıştığı için tekrar çalışmayacak ve daha önce yaratılmış ArchiveAPI bize döndürülmüş olacak.​

Abdulbasıt Tanhan |

09.05.2014

Yorumlar

Tolga
15.07.2014 - 02:11

Çok teşekkürler, benim için faydalı oldu.

Ahmet
15.07.2014 - 02:14

Elinize sağlık.

Yakup
24.06.2014 - 11:40
Elinize saglik