Objective-C继承多态静态工厂模式
2016-03-23 本文已影响49人
fakepinge
继承和多态
静态工厂方法模式
#import <Foundation/Foundation.h>
// objective-c 推荐用以下方式创建枚举
typedef NS_ENUM(NSUInteger, ZPEmployeeType) {
ZPEmployeeTypeManager,
ZPEmployeeTypeEngineer,
ZPEmployeeTypeSalesman
};
@interface ZPEmployee : NSObject
/**名字*/
@property (nonatomic, copy) NSString *name;
/**工资*/
@property (nonatomic, readonly) double salary;// 只读,要写getter方法
/**初始化*/
// 隐藏多种员工子类型的细节只暴露员工接口给用户调用
+ (instancetype) employeeWithType:(ZPEmployeeType) type;
@end
#import "ZPEmployee.h"
#import "ZPEngineer.h"
#import "ZPManager.h"
#import "ZPSalesman.h"
@implementation ZPEmployee
// 终极原则:高内聚 低耦合
// 面向对象七原则:
// 单一职责原则
// 开闭原则
// 依赖倒转原则
// 里氏替换原则
// 接口隔离原则
// 合成聚合复用原则
// 迪米特法则
// GoF设计模式(23种设计模式)
// 创建型模式:单例、工厂
// 结构型模式:适配器、门面、装潢、桥梁
// 行为型模式:观察者、代理
//类簇 (class cluster)
// 设计模式:静态工厂方法模式
+ (instancetype) employeeWithType:(ZPEmployeeType) type {
ZPEmployee *employee = nil;
switch (type) {
case ZPEmployeeTypeManager:
employee = [[ZPManager alloc] init];
break;
case ZPEmployeeTypeEngineer:
employee = [[ZPEngineer alloc] init];
break;
case ZPEmployeeTypeSalesman:
employee = [ZPSalesman new];
break;
}
return employee;
}
@end
#import "ZPEmployee.h"
/**部门经理*/
@interface ZPManager : ZPEmployee
@end
#import "ZPManager.h"
@implementation ZPManager
- (double) salary {
return 10000;
}
@end
#import "ZPEmployee.h"
/**技术工人*/
@interface ZPEngineer : ZPEmployee
/**工作时间*/
@property (nonatomic, strong) NSNumber *workingHour;
@end
#import "ZPEngineer.h"
@implementation ZPEngineer
- (double) salary {
return 200 * [_workingHour integerValue];
}
@end
#import "ZPEmployee.h"
/**销售员*/
@interface ZPSalesman : ZPEmployee
/**销售额*/
@property (nonatomic, strong) NSNumber *sales;
@end
#import "ZPSalesman.h"
@implementation ZPSalesman
- (double)salary {
return 1500 + 0.05 * [_sales doubleValue];
}
@end
#import <Foundation/Foundation.h>
#import "ZPManager.h"
#import "ZPSalesman.h"
#import "ZPEngineer.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray *empNames = @[@"马超", @"赵云", @"典韦", @"许褚", @"陆逊", @"魏延",@"张飞"];
NSMutableArray *empsArray = [@[] mutableCopy];
for (NSString *name in empNames) {
ZPEmployee *emp = [ZPEmployee employeeWithType:arc4random() % 3];
emp.name = name;
[empsArray addObject:emp];
// ZPEmployee *emp = nil;
// int num = arc4random() % 3;
// switch (num) {
// case 0:
// emp = [ZPManager managerWithName:name];
// break;
// case 1:
// emp = [ZPEngineer engineerWithName:name];
// break;
// case 2:
// emp = [ZPSalesman salesmanWithName:name];
// break;
// }
// [empsArray addObject:emp];
}
for (ZPEmployee *emp in empsArray) {
//printf("%s", emp.name.UTF8String);
// 判断类型
if ([emp isKindOfClass:[ZPEngineer class]]) {
printf("请输入%s的本月工作时间: ", emp.name.UTF8String);
int workingHour;
scanf("%d", &workingHour);
// 通过选择器去执行对象方法。
[emp performSelector:@selector(setWorkingHour:) withObject:@(workingHour)];
//将父类型指针转换成子类型指针(向下转型,需要强制类型转换)
// ZPEngineer *engineer = (ZPEngineer *)emp;
// engineer.workingHour = @(workingHour);
}
else if ([emp isKindOfClass:[ZPSalesman class]]) {
printf("请输入%s的本月的销售额: ", emp.name.UTF8String);
double sales;
scanf("%lf", &sales);
// id 是任意类型的指针
[emp performSelector:@selector(setSales:) withObject:@(sales)];
// ZPSalesman *salesman = (id) emp;
// salesman.sales = @(sales);
}
printf("%s本月工资为:$%.1f\n", emp.name.UTF8String, emp.salary);
}
}
return 0;
}