Tuesday, April 9, 2013

Facade Design Pattern - Objective-C


Facade design pattern just hides the sub system's interface and provides single interface to the client.

In everyday life we are using lots of facade design pattern without knowing it.
for example

    [data writeToFile:path atomically:YES];

writeToFile method opens a file pointer in write mode and writes the content and closes the file pointer, All these three functionality is taken care by writeToFile method, It hides the three different activities.

Earlier we use to open the file pointer and write the data, finally close the file pointer. The client has to manage everything but Facade design pattern hides all the details and expose the subject interface to the client. Client has no idea about how its going to write the data into DISK.


I am going to take a problem and solve using FACADE DESIGN PATTERN.

The problem is, 

     When an employee resigns from an organization, the very last day the employee has to go to all the department to get the clearance signature to make sure he/she do not have any pending clearance.
 
    Here the client is an Employee, the sub systems are Admin department, Finance department, Reporting manager.  So i would like to introduce the facade pattern to sort out the employee roaming behind all the department to get the clearance.  The employee only has to go to particular department when he has some pending records which requires in-person meeting. All Resigned employee no need to go to all the department to get the signature.





ClearenceCheckDelegate protocol, Each department should implement the interface. This implementation changes based on the department. But the interface is common for all the department so that facade can call method on each department to know the clearance status of an employee.


//
//  ClearenceCheckDelegate.h
//  FacadeDesignPattern
//
//  Created by Stalin on 09/04/13.
//  Copyright (c) 2013 Stalin. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol ClearenceCheckDelegate <NSObject>

-(BOOL) clearenceCheckForEmployeeID:(NSString*) employeeCode;

@end

//
//  FinanceDepartnment.h
//  FacadeDesignPattern
//
//  Created by Stalin on 09/04/13.
//  Copyright (c) 2013 Stalin. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ClearenceCheckDelegate.h"

@interface FinanceDepartnment : NSObject<ClearenceCheckDelegate>
{
    NSMutableDictionary *employeeClerence;
}


@end


We have hardcoded the employee clearance status, But in real time it may come  from Database or from web service, Since we are discussing about the facade design pattern we do not have to concentrate on the data source.


//
//  FinanceDepartnment.m
//  FacadeDesignPattern
//
//  Created by Stalin on 09/04/13.
//  Copyright (c) 2013 Stalin. All rights reserved.
//

#import "FinanceDepartnment.h"

@implementation FinanceDepartnment

- (id)init
{
    self = [super init];
    if (self) {
        employeeClerence = [[NSMutableDictionary alloc] init];
        
        [employeeClerence setObject:[NSNumber numberWithBool:YES] forKey:@"1234"];
        [employeeClerence setObject:[NSNumber numberWithBool:YES] forKey:@"1235"];
    }
    return self;
}


-(BOOL) clearenceCheckForEmployeeID:(NSString*) employeeCode
{
    NSNumber *isCleared = [employeeClerence objectForKey:employeeCode];
    
    return [isCleared boolValue];
}

@end

//
//  AdminDepartnment.h
//  FacadeDesignPattern
//
//  Created by Stalin on 09/04/13.
//  Copyright (c) 2013 Stalin. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ClearenceCheckDelegate.h"

@interface AdminDepartnment : NSObject<ClearenceCheckDelegate>
{
    NSMutableDictionary *employeeClerence;
}

@end

//
//  AdminDepartnment.m
//  FacadeDesignPattern
//
//  Created by Stalin on 09/04/13.
//  Copyright (c) 2013 Stalin. All rights reserved.
//

#import "AdminDepartnment.h"

@implementation AdminDepartnment

- (id)init
{
    self = [super init];
    if (self) {
        employeeClerence = [[NSMutableDictionary alloc] init];
        
        [employeeClerence setObject:[NSNumber numberWithBool:YES] forKey:@"1234"];
        [employeeClerence setObject:[NSNumber numberWithBool:NO] forKey:@"1235"];
    }
    return self;
}

-(BOOL) clearenceCheckForEmployeeID:(NSString*) employeeCode
{
    NSNumber *isCleared = [employeeClerence objectForKey:employeeCode];
    
    return [isCleared boolValue];
}

@end

//
//  ReportingManager.h
//  FacadeDesignPattern
//
//  Created by Stalin on 09/04/13.
//  Copyright (c) 2013 Stalin. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ClearenceCheckDelegate.h"

@interface ReportingManager : NSObject<ClearenceCheckDelegate>
{
    NSMutableDictionary *employeeClerence;
}

@end

//
//  ReportingManager.m
//  FacadeDesignPattern
//
//  Created by Stalin on 09/04/13.
//  Copyright (c) 2013 Stalin. All rights reserved.
//

#import "ReportingManager.h"

@implementation ReportingManager

- (id)init
{
    self = [super init];
    if (self) {
        employeeClerence = [[NSMutableDictionary alloc] init];
        
        [employeeClerence setObject:[NSNumber numberWithBool:YES] forKey:@"1234"];
        [employeeClerence setObject:[NSNumber numberWithBool:YES] forKey:@"1235"];
    }
    return self;
}


-(BOOL) clearenceCheckForEmployeeID:(NSString*) employeeCode
{
    NSNumber *isCleared = [employeeClerence objectForKey:employeeCode];
    
    return [isCleared boolValue];
}


@end







employee class acts as facade,  canIGetMyExperienceLetter is the interface to the client and it in turns checks clearance for an employee with all the department.




 
//
//  RelievingManagerFacade.h
//  FacadeDesignPattern
//
//  Created by Stalin on 09/04/13.
//  Copyright (c) 2013 Stalin. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ClearenceCheckDelegate.h"

@interface RelievingManagerFacade : NSObject
{
    NSMutableArray *clearenceDepts;
}

-(void) addClearenceDept:(id<ClearenceCheckDelegate>) dept;

-(BOOL) canIGetMyExperienceLetter:(NSString*) employeeCode;

@end

//
//  RelievingManagerFacade.m
//  FacadeDesignPattern
//
//  Created by Stalin on 09/04/13.
//  Copyright (c) 2013 Stalin. All rights reserved.
//

#import "RelievingManagerFacade.h"
#import "ClearenceCheckDelegate.h"

@implementation RelievingManagerFacade

- (id)init
{
    self = [super init];
    if (self) {
        
        clearenceDepts = [[NSMutableArray alloc] init];
    }
    return self;
}

-(void) addClearenceDept:(id<ClearenceCheckDelegate>) dept
{
        [clearenceDepts addObject:dept];
}

-(BOOL) canIGetMyExperienceLetter:(NSString*) employeeCode
{
    for (id<ClearenceCheckDelegate> dept in clearenceDepts)
    {
        if ([dept conformsToProtocol:@protocol(ClearenceCheckDelegate)])
        {
             if ([dept clearenceCheckForEmployeeID:employeeCode] == false)
             {
                 return false;
             }
        }
    }
    
    return true;
}

@end







    RelievingManagerFacade *hr = [[RelievingManagerFacade alloc] init];
    
    //adding the clearence dept
    [hr addClearenceDept:[[FinanceDepartnment alloc] init]];
    [hr addClearenceDept:[[AdminDepartnment alloc] init]];
    [hr addClearenceDept:[[ReportingManager alloc] init]];
    

    if ([hr canIGetMyExperienceLetter:@"1234"])
    {
        NSLog(@"Employee code 1234.  Yes,  You do not have any pending clearence. You will get it now.");
    }
    else
    {
        NSLog(@"Employee code 1234. NO, You have some pending clearence.");
    }
    
    if ([hr canIGetMyExperienceLetter:@"1235"])
    {
        NSLog(@"Employee code 1235. Yes,  You do not have any pending clearence. You will get it now.");
    }
    else
    {
        NSLog(@"Employee code 1235. NO, You have some pending clearence.");
    }





No comments: