启动重构,Objective-C

启动重构,Objective-C,objective-c,refactoring,design-patterns,Objective C,Refactoring,Design Patterns,我有两个类似的类,MultiSlotBlock和SingleSlotBlock。他们已经开始共享很多常用代码,所以我决定进行一些重构,并将一些方法提升到一个新的超类,我们称之为Block 现在,我提出的其中一种方法(简化为示例)如下所示: // (Block.mm) - (void)doACommonBehaviour { // .. does some stuff [self doAUniqueBehaviour]; } 这里的问题是,[self-d

我有两个类似的类,
MultiSlotBlock
SingleSlotBlock
。他们已经开始共享很多常用代码,所以我决定进行一些重构,并将一些方法提升到一个新的超类,我们称之为
Block

现在,我提出的其中一种方法(简化为示例)如下所示:

// (Block.mm)

- (void)doACommonBehaviour
{       
      // .. does some stuff

      [self doAUniqueBehaviour];
}
这里的问题是,
[self-doaniquebehavior]
显示了一个警告,因为我的超类当然没有在任何地方实现这个方法

我想到的两个解决方案对我来说听起来不太好。一种是使用协议(我目前的做法),如下所示:

//(Block.mm)
-(无效)行为
{       
//…做一些事情
if([自我确认协议:@协议(唯一行为协议)])
{
id块=(id)self;
[块行为];
}
}
另一种方法是在我的超类中有一个空白的方法体(在这种情况下会有很多),只返回
doesNotRespondToSelector

在我的脑海深处有一种刺痛感,那就是我应该使用战略模式,但我可能离这太远了,我还没有考虑如何实现这一点

有什么想法吗?谢谢


编辑:我知道,
doUniqueBehavior
将在所有子类中实现,只是实现不同而已

Objective-C中没有抽象类的概念。为了避免警告,必须在基类中提供默认实现。通常,此实现会在运行时抛出
doesNotRespondToSelector
错误:

- (id)someMethod:(SomeObject*)blah 
     [self doesNotRecognizeSelector:_cmd];
     return nil;
}

注意:_cmd参数是调用的选择器。

Objective-C中没有抽象类的概念。为了避免警告,必须在基类中提供默认实现。通常,此实现会在运行时抛出
doesNotRespondToSelector
错误:

- (id)someMethod:(SomeObject*)blah 
     [self doesNotRecognizeSelector:_cmd];
     return nil;
}

注意:_cmd参数是被调用的选择器。

超类不应该知道它的子类。你应该实施
-(void)doacomonBehavior
方法在每个子类中,并且:

- (void)doACommonBehaviour
{     
      [super doACommonBehaviour];
      [self doAUniqueBehaviour];
}
编辑-澄清:

如果所有的子类都要实现
-doUniqueBehavior
,那么它应该在超类中实现(甚至是空的),每个子类都会根据自己的需要覆盖它

如果子类1实现了
-doUniqueBehavior 1
,子类2实现了
-doUniqueBehavior 2
等,那么按照我上面的建议执行;例如,在第1款中:

- (void)doACommonBehaviour
{     
      [super doACommonBehaviour];
      [self doAUniqueBehaviour1];
}

超类不应该知道它的子类。你应该实施
-(void)doacomonBehavior
方法在每个子类中,并且:

- (void)doACommonBehaviour
{     
      [super doACommonBehaviour];
      [self doAUniqueBehaviour];
}
编辑-澄清:

如果所有的子类都要实现
-doUniqueBehavior
,那么它应该在超类中实现(甚至是空的),每个子类都会根据自己的需要覆盖它

如果子类1实现了
-doUniqueBehavior 1
,子类2实现了
-doUniqueBehavior 2
等,那么按照我上面的建议执行;例如,在第1款中:

- (void)doACommonBehaviour
{     
      [super doACommonBehaviour];
      [self doAUniqueBehaviour1];
}

@Dimitri的建议会起作用,但您可以在块中声明一次,而不是强制每个子类实现同一个方法,并在该方法的正上方(在实现文件中,而不是标头中)声明唯一的方法,如下所示:

- (void) doUniqueBehaviour { }

- (void) doCommonBehaviour {     
    // any common code you need
    [self doUniqueBehaviour];
}

这将防止任何编译器警告,并且您可以在子类中随意重写
-douniquebehavior
。它还避免了代码重复,减少了在一个子类而不是另一个子类中更改代码的可能性。另外,您不需要单独的协议,动态类型也会保留下来。

@Dimitri的建议会起作用,但您可以在块中声明一次,而不是强制每个子类实现同一个方法,并在该方法的正上方(在实现文件中,而不是头中)声明唯一的方法,如下所示:

- (void) doUniqueBehaviour { }

- (void) doCommonBehaviour {     
    // any common code you need
    [self doUniqueBehaviour];
}

这将防止任何编译器警告,并且您可以在子类中随意重写
-douniquebehavior
。它还避免了代码重复,减少了在一个子类而不是另一个子类中更改代码的可能性。另外,您不需要单独的协议,而且动态类型被保留。

如果我知道所有子类都实现了
douniquebehavior
,那该怎么办?我真的想在超类中为这个方法提供接口,而不是实现。如果他们都实现了它,那么将它添加到超类中——接口和实现。然后在每个子类中独立地重写它。我假设-DoaUniqueBehavior是由一些子类实现的。如果它是由所有子类实现的(即使是以不同的方式),那么它应该由超类实现。然后每个子类将在其自己的方法实现中执行它需要执行的任何操作。在任何情况下,都不需要协议,也不需要超类来检查子类可以做什么。这是可行的,所以我不会否决它,但如果只在父类中使用此方法,会更干净,并在
.mm
文件中提供一个空的
-doUniqueBehavior
方法以防止重复。如果我知道所有子类都实现了
doUniqueBehavior
?我真的想在超类中为这个方法提供接口,而不是实现。如果他们都实现了它,那么将它添加到超类中——接口和实现。然后在每个子类中独立地重写它。我假设-DoaUniqueBehavior是由一些子类实现的。如果它是由所有子类实现的(即使是以不同的方式),那么它应该由超类实现。然后每个子类将在其自己的方法实现中执行它需要执行的任何操作。在任何情况下,都不需要协议,也不需要超类来检查子类可以做什么