在面向对象编程中使用间接
在学习之前,先看一个过程式编程的例子。
//
// main.m
// OOP
//
// Created by ccyag on 21/4/18.
// Copyright © 2018年 ccyag. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef enum{
kCircle,
kRectangle,
kTriangle
} ShapeType;
typedef enum{
kRed,
kGreen,
kBlue
} ShapeColor;
NSString *colorName(ShapeColor color){
switch (color) {
case kRed:
return @"red";
break;
case kGreen:
return @"green";
break;
case kBlue:
return @"blue";
break;
}
}
typedef struct{
int x, y, widht, height;
} ShapeRect;
typedef struct {
ShapeType type;
ShapeColor color;
ShapeRect bounds;
} Shape;
void drawCircle(ShapeRect bounds, ShapeColor color){
NSLog(@"drawing a circle at(%d %d %d %d) in %@",
bounds.x, bounds.y, bounds.widht, bounds.height, colorName(color));
}
void drawRectangle(ShapeRect bounds, ShapeColor color){
NSLog(@"drawing a rectangle at(%d %d %d %d) in %@",
bounds.x, bounds.y, bounds.widht, bounds.height, colorName(color));
}
void drawTriangle(ShapeRect bounds, ShapeColor color){
NSLog(@"drawing a triangle at(%d %d %d %d) in %@",
bounds.x, bounds.y, bounds.widht, bounds.height, colorName(color));
}
void drawShapes(Shape shapes[], int count){
for(int i = 0; i < count; i++){
switch (shapes[i].type) {
case kCircle:
drawCircle(shapes[i].bounds, shapes[i].color);
break;
case kRectangle:
drawRectangle(shapes[i].bounds, shapes[i].color);
break;
case kTriangle:
drawTriangle(shapes[i].bounds, shapes[i].color);
break;
}
}
}
int main(int argc, const char * argv[]) {
Shape shapes[3];
ShapeRect rect0 = {0, 0, 30, 30};
shapes[0].type = kCircle;
shapes[0].color = kRed;
shapes[0].bounds = rect0;
ShapeRect rect1 = {50, 50, 60, 80};
shapes[1].type = kRectangle;
shapes[1].color = kGreen;
shapes[1].bounds = rect1;
ShapeRect rect2 = {100, 100, 120, 150};
shapes[2].type = kTriangle;
shapes[2].color = kBlue;
shapes[2].bounds = rect2;
drawShapes(shapes, 3);
return 0;
}
运行结果如下:
2018-04-21 14:27:33.330017+0800 OOP[4205:624974] drawing a circle at(0 0 30 30) in red
2018-04-21 14:27:33.330242+0800 OOP[4205:624974] drawing a rectangle at(50 50 60 80) in green
2018-04-21 14:27:33.330255+0800 OOP[4205:624974] drawing a triangle at(100 100 120 150) in blue
这是一段面向过程的代码,功能很简单,实现了图形的绘制功能,每一种图形都有自己的颜色,形状和坐标位置,用到了C语言中的枚举和结构体。
这段代码中有很多重复的地方,而且扩展和维护起来很困难。比如添加一个椭圆图形,完整代码如下:
#import <Foundation/Foundation.h>
typedef enum{
kCircle,
kRectangle,
kTriangle,
kEllipse
} ShapeType;
typedef enum{
kRed,
kGreen,
kBlue
} ShapeColor;
NSString *colorName(ShapeColor color){
switch (color) {
case kRed:
return @"red";
break;
case kGreen:
return @"green";
break;
case kBlue:
return @"blue";
break;
}
}
typedef struct{
int x, y, widht, height;
} ShapeRect;
typedef struct {
ShapeType type;
ShapeColor color;
ShapeRect bounds;
} Shape;
void drawCircle(ShapeRect bounds, ShapeColor color){
NSLog(@"drawing a circle at (%d %d %d %d) in %@",
bounds.x, bounds.y, bounds.widht, bounds.height, colorName(color));
}
void drawRectangle(ShapeRect bounds, ShapeColor color){
NSLog(@"drawing a rectangle at (%d %d %d %d) in %@",
bounds.x, bounds.y, bounds.widht, bounds.height, colorName(color));
}
void drawTriangle(ShapeRect bounds, ShapeColor color){
NSLog(@"drawing a triangle at (%d %d %d %d) in %@",
bounds.x, bounds.y, bounds.widht, bounds.height, colorName(color));
}
void drawEllipse(ShapeRect bounds, ShapeColor color){
NSLog(@"drawing a Ellipse at (%d %d %d %d) in %@",
bounds.x, bounds.y, bounds.widht, bounds.height, colorName(color));
}
void drawShapes(Shape shapes[], int count){
for(int i = 0; i < count; i++){
switch (shapes[i].type) {
case kCircle:
drawCircle(shapes[i].bounds, shapes[i].color);
break;
case kRectangle:
drawRectangle(shapes[i].bounds, shapes[i].color);
break;
case kTriangle:
drawTriangle(shapes[i].bounds, shapes[i].color);
break;
case kEllipse:
drawEllipse(shapes[i].bounds, shapes[i].color);
}
}
}
int main(int argc, const char * argv[]) {
Shape shapes[4];
ShapeRect rect0 = {0, 0, 30, 30};
shapes[0].type = kCircle;
shapes[0].color = kRed;
shapes[0].bounds = rect0;
ShapeRect rect1 = {50, 50, 60, 80};
shapes[1].type = kRectangle;
shapes[1].color = kGreen;
shapes[1].bounds = rect1;
ShapeRect rect2 = {100, 100, 120, 150};
shapes[2].type = kTriangle;
shapes[2].color = kBlue;
shapes[2].bounds = rect2;
ShapeRect rect3 = {200, 200, 40, 80};
shapes[3].type = kEllipse;
shapes[3].color = kRed;
shapes[3].bounds = rect3;
drawShapes(shapes, 4);
return 0;
}
需要修改很多地方,修改的地方越多,程序越容易出错。面向对象编程很好地解决了这些问题。在下一篇随笔中将实现面向对象编程。