Improved ability to abstract the interface class code Reconstruction of iOS

Today, we see the "Code Complete Second Edition," which describes the abstract classes for ADT and the ability to make me a lot, check out our iOS project, immediately find such a bad taste (bad good class interface design), the following share my improvements. (Here's the class name has been modified, not the actual project in the name of the class)


Before improvements:

This is a custom cell class:

@protocol  CustomCellDeletage <NSObject>

- (void)checkDidTouch:(CustomCell *)cell;

@end

@interface CustomCell : UITableViewCell

@property (nonatomic, weak)id<CustomCellDeletage> delegate;

@property (nonatomic, retain)UIButton * checkBtn;
//这里直接暴露了类的成员变量细节,导致类对自身内部控制的松动,按钮的状态改变将难以追踪,并且这个类和按钮对象如何使用也会让调用方摸不着头脑,这次的改动将以此为重

@end

@implementation CustomCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.selectionStyle = UITableViewCellSelectionStyleNone;
        _checkBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [_checkBtn addTarget:self action:@selector(checkBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
        //...省略部分代码

    }
    return self;
}
- (void)checkBtnPressed:(id)sender {
    // 切换选中状态
    _checkBtn.selected = !_checkBtn.selected;
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(checkDidTouch:)]) {
        [self.delegate checkDidTouch:self];
    }
}
复制代码

External Controller call:

cell.checkBtn.selected = [self isChecked:orderDict[@"orderId"]];
复制代码

External Controller callbacks:

#pragma mark  CustomCellDeletage ---- 点击选择按钮事件
- (void)checkDidTouch:(CustomCell *)cell {
    // 如果是选中状态,就添加   反之这移除
    if (cell.checkBtn.selected) {
        [self.checkArray addObject:cell.orderDict];
    } else {
        [self.checkArray removeObject:cell.orderDict];
    }
    [self updateViewInfo];
}
复制代码

Code evaluation here to do according to "Code Complete Second Edition," author of the book describes the benefits of ADT. As a direct exposure to the member variables checkBtn class here and brought a lot of harm.
The ADT (abstract data types)
  • Hide implementation details

If the data type is changed, you only need to modify one without affecting the rest of the program. Here, for example, if the type to UIButton UISwitch, need only be altered to achieve specific interface, the interface without affecting the caller

  • So that the interface can provide more information, the program is more self-explanatory

Here, for example, behind the improved interface selectOn class and a set of methods selectOff more meaningful description

abstract
  • Hide interface class to provide a specific implementation of the abstract in the subsequent
  • Class interface should show the same level of abstraction

Here cell such as a cell class, should provide a selected cell and uncheck the cell interface, not directly exposed member variable

  • And members restricted as much as possible to improve the accessibility of the packaging
  • Do not expose members of the public data
  • Avoid interface into the private implementation details class

The core idea of ​​change

The manipulation of the button to a set of isolation subroutine, a better abstraction layer portion of other programs required to operate the button, and can provide a layer of protection for the button when the operation state of the property changes. Like that entities operating in the real world, rather than operate it on the underlying implementation


Improve

@protocol  CustomCellDeletage <NSObject>

- (void)customCellDidSelectOn:(CustomCell *)cell;

- (void)customCellDidSelectOff:(CustomCell *)cell;

@end

@interface CustomCell : UITableViewCell

@property (nonatomic, weak)id<CustomCellDeletage> delegate;

- (void)selectOn;

- (void)selectOff;

@end

@interface CustomCell ()

@property (nonatomic, strong)UIButton * checkBtn;

@end

@implementation CustomCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.selectionStyle = UITableViewCellSelectionStyleNone;
        _checkBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [_checkBtn addTarget:self action:@selector(checkBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
         //...省略部分代码
    }
    return self;
}
- (void)checkBtnPressed:(id)sender {
    if (_checkBtn.selected) {
        [self selectOff];
        if (self.delegate && [self.delegate respondsToSelector:@selector(customCellDidSelectOff:)]) {
        [self.delegate customCellDidSelectOff:self];
    }
    } else {
        [self selectOn];
        if (self.delegate && [self.delegate respondsToSelector:@selector(customCellDidSelectOn:)]) {
        [self.delegate customCellDidSelectOn:self];
    }
    }
}
- (void)selectOn {
    _checkBtn.selected = YES;
}
- (void)selectOff {
    _checkBtn.selected = NO;
}
@end

复制代码

External Controller call:

if ([self isChecked:orderDict[@"orderId"]]) {
        [cell selectOn];
    } else {
        [cell selectOff];
    }
复制代码

External Controller callbacks:

#pragma mark <CustomCellDelegate>
- (void)customCellDidSelectOn:(CustomCell *)cell {
    
    [self.checkArray addObject:cell.orderDict];
    [self updateViewInfo];

}

- (void)customCellDidSelectOff:(CustomCell *)cell {
    
    [self.checkArray removeObject:cell.orderDict];
    [self updateViewInfo];
}
复制代码

Changes point:

  1. The button as the class of private property
  2. Button will change the status of selected objects packaged to provide a higher level of abstraction selectOn and selectOff interfaces, abstracted into more like the real world, like the operating entity, select the cell and uncheck the cell, rather than direct contact with the low-level details of the button object selected property is set to YES or NO.
  3. Abstract interface selectOn and selectOff method caller calls a higher level, more descriptive sense, without having to be concerned about the implementation details. Internal cell may also change the appearance by this method, since there is no need to change the appearance on the local changes in the plurality.
  4. Callback method duties more single, selected in the original deal with a method and unchecked, now separated into two methods, get rid of an if, it reduces the complexity of the function, after adding check or uncheck might deal with other selected after things will be easier to maintain.
  5. In terms of the object after the button is replaced with another type of object, or a more complex custom button object, it simply changes implemented internally within the package, does not affect other parts of the program.

Improved codes:

  • Hides the implementation details of the improved package of class
  • Class interfaces and classes to maintain a consistent level of abstraction
  • Higher-level interface abstract class
  • Single Responsibility

Some students may feel that these changes are so necessary to do, so get a big way, but we should always keep the code clean and tidy, if each class are not always maintain a high degree of external interfaces consistent level of abstraction, then multiple iterations later, so the class will be increasingly difficult to understand and difficult to maintain, and there is a huge class continued various unrelated data and logic, easier to involve older increased functionality when new features bug, we should always remember that

Not to be evil and small occasions, do good rather than

Reproduced in: https: //juejin.im/post/5cff4ecaf265da1b8d16136a

Guess you like

Origin blog.csdn.net/weixin_34099526/article/details/93176402