我这样做是因为箭头位置已更新并由多个类使用。
在许多情况下,您可以缩小范围。这减少了组件间的依赖性。
然而,我不确定这是一个好还是坏的设计决策。我的想法是,由于它是一条非关键信息(只是一个浮点数),因此在全局存储它时不会造成任何损害。但每次我对自己说“全局”这个词时,我的 OOP 心都会痛。
也许您可以将状态(浮点值)移至速度计中的 ivar?示例:您可能只显示一个速度计视图:将其添加到视图的模型中是否更有意义?或者也许是它的控制器? (是的,在没有来源的情况下提供更具体的示例有点困难)
另外,我有研究单例,但据我所读,当开发人员希望创建某个对象的一个且仅有一个实例时,会使用单例。
没有必要,并且维持会带来剧烈的疼痛。我见过的大多数可可单身人士都不应该经过考虑的单身人士,并引起了很多头痛。更好的是,您可以编写使用零单例的程序。这是理想的,并且易于测试。事实上,依赖于应用程序控制器的程序/类型已在可测试性和可重用性方面受到损害。
我这样做是正确的还是有更合适的方法来做我所做的事情?
在绝大多数情况下,您可以简单地缩小范围并将其本地化,同时删除全局状态。再多一点努力,您就可以将这个值作为全局值删除——这是最好的。
虽然这不是一件好事...让我们假设你真的真的真的真的真的必须引入全局状态:
-
don't使用单例。当您想重用它时,您很可能会重写它。它给丑陋的事物涂上糖衣。如果你的应用程序控制器由于太多的全局状态而变得一团糟,至少你有太多的全局状态这一事实是显而易见的。
- 在应用程序控制器中保存全局状态。您的应用程序控制器负责其初始化、生命周期和访问。
- 向依赖项提供该状态,因此它们不会引用(甚至不知道)全局域(应用程序控制器)。那么你就可以将影响降到最低。
全局状态和应用程序/执行状态之间也有明显的区别。全局状态应该被消除。执行状态不是全局状态,而是局部执行上下文。执行状态可以在正确的级别重新引入、更改、更新、测试和可预测地重用。一个好的设计将在需要时在正确的级别引入执行状态,同时避免全局状态。
Update
根据OP中的描述,你的样本非常接近我的想象。它提供了一些额外的细节。因此,下面的示例(您需要在明显的区域中添加一些内容才能将它们拼凑在一起)演示了如何更新控制器接口,最后有两个免费的“其他”方法,进一步说明了如何使用这些方法:
@interface MONArrowPosition : NSObject
{
float arrowPosition;
}
@end
@implementation MONArrowPosition
- (id)initWithPosition:(float)position
{
self = [super init];
if (nil != self) {
arrowPosition = position;
}
return self;
}
@end
@interface MyViewController1 : UIViewController
{
MONArrowPosition * arrowPosition; // << may actually be held by the model
}
@end
@implementation MyViewController1
- (void)applyRotation
{
[self rotateLayer:arrow from:self.arrowPosition to:callStatus speed:METER_SPEED];
}
@end
@interface MyViewController2 : UIViewController
{
MONArrowPosition * arrowPosition; // << may actually be held by the model
}
@end
@implementation MyViewController2
- (void)viewDidLoad
{
[super viewDidLoad];
/* ... */
[self.slider addTarget:self action:@selector(sliderValueDidChange) forControlEvents:controlEvents];
}
- (void)sliderValueDidChange
{
self.arrowPosition.arrowPosition = self.slider.value;
[self arrowPositionDidChange];
}
@end
/* elsewhere: */
- (void)initializeArrowPosition
{
/* The variable is set to a default of 0.0f */
MONArrowPosition * arrowPosition = [[MONArrowPosition alloc] initWithPosition:0.0f];
/* ... */
}
- (IBAction)someActionWhichPushesMyViewController1
{
// depending on the flow of your app, the body of initializeArrowPosition
// *could* be right here
MyViewController1 * viewController = [[MyViewController1 alloc] initWithNibName:nibName bundle:bundle];
viewController.arrowPosition = self.arrowPosition;
/* push it */
}
然后如果MyViewController1推MyViewController2,定位和设置箭头位置就会很容易。视图控制器也可能共享模型中的一些信息。在示例中使用全局变量,您将跨越许多实现,这会增加耦合、增加依赖性等。因此,如果您可以采用这种方法并本地化执行状态,那么您就有了一个良好的开端。那么你可以使用任意数量的视图控制器和任意数量的MONArrowPositions,并且它们不会受到全局状态的影响。再次,我无法使用提供的示例获得太具体的信息,但我认为这应该足以说明我最初概述的概念(我认为不需要进行项目范围的审查)。