我正在开发一个带速度计的应用程序,如动画(仪表和箭头表示仪表上的某些东西)。我将箭头的位置存储在我的app delegate中声明的全局变量中。我这样做是因为箭头位置被更新并被几个类使用。
然而,我不确定这是一个好的或坏的设计决定。我的想法是,因为它是一个非关键的信息(只是一个浮动),所以在全局存储时不会造成任何伤害。但每当我对自己说“全球”这个词时,我的OOP心就会受伤。
或者我有单身人士,但据我所知,当开发人员希望创建一个且只有一个特定对象的实例时,会使用单身人士。
我做得对吗还是有更合适的方式做我做的事情?
答案 0 :(得分:2)
我这样做是因为箭头位置被更新并被几个类使用。
在很多情况下,您可以缩小范围。这减少了组件间依赖性。
然而,我不确定这是一个好的或坏的设计决定。我的想法是,因为它是一个非关键的信息(只是一个浮动),所以在全局存储时不会造成任何伤害。但每当我对自己说“全球”这个词时,我的OOP心就会受伤。
也许您可以将状态(浮动值)移动到车速表中的ivar?例如:您可能只显示一个车速表视图:将它添加到视图模型中更有意义吗?或者也许是它的控制器? (是的,在没有源的情况下提供更具体的例子有点困难)
没有必要,并且要保持严重的疼痛。我见过的大多数可可单身人士都不应该被认为是单身人士,并且引起了很多麻烦。更好的是,你可以编写使用零单例的程序。这是理想的,易于测试。因此,依赖于app控制器的程序/类型已经受到可测试性和可重用性的影响。或者我有单身人士,但据我所知,当开发人员希望创建一个且只有一个特定对象的实例时,会使用单身人士。
我做得对吗还是有更合适的方式做我做的事情?
在绝大多数情况下,您可以简单地缩小范围并对其进行本地化,同时删除全局状态。通过更多的努力,您可以将该值作为全局删除 - 这是最好的。
虽然这不是一件好事......让我们假设你真的非常真的必须引入全球状态:
全局状态和应用程序/执行状态之间也存在明显差异。全球国家应该被淘汰。执行状态不是全局状态,而是本地化执行上下文。执行状态可以在适当的级别重新引入,更改,更新,测试和可预测的重用。一个好的设计将在需要时引入执行状态,并在适当的级别同时避免全局状态。
<强>更新强>
根据OP中的描述,您的样本与我想象的非常接近。它提供了一些额外的细节。所以下面的示例(你需要在显而易见的领域中添加一些内容以将它们拼凑在一起)演示了如何更新控制器接口,并且最后有两个免费的“其他”方法,它们进一步说明了如何使用它们: / p>
@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的任意数量的视图控制器,它们将不受全局状态的影响。再次,我不能使用提供的样本过于具体,但我认为这应该说明我最初概述的概念(我不认为需要进行项目范围的审查)。
答案 1 :(得分:0)
这是让很多程序员在晚上工作的东西。
我尽量不要滥用app委托,我会创建一个单例来存储或多或少的全局信息。除了单身人士或应用代表之外,没有其他方法可以做到这一点。
但是如果只有一个viewController需要信息,那么信息永远不会离开那个viewController。该viewcontroller可以将该信息传递给其他viewcontroller。
在你的情况下,可能有一种想法是拥有一些包含浮点数的directionManager,甚至可以保存CLLocationManager。
答案 2 :(得分:0)
对于这类事情,我喜欢使用NSNotifications。您让所有关心箭头位置的视图控制器都会监听特定通知,并且他们都可以立即更新UI。