应用程序委托中全局变量的替代方案

2023-12-03

我正在开发一个带有速度计的应用程序,如动画(一个仪表和一个箭头来指示仪表上的某些内容)。我将箭头的位置存储在应用程序委托中声明的全局变量中。我这样做是因为箭头位置已更新并由多个类使用。

然而,我不确定这是一个好还是坏的设计决策。我的想法是,由于它是一条非关键信息(只是一个浮点数),因此在全局存储它时不会造成任何损害。但每次我对自己说“全局”这个词时,我的 OOP 心都会痛。

另外,我有研究单例,但据我所读,当开发人员希望创建某个对象的一个​​且仅有一个实例时,会使用单例。

我这样做是正确的还是有更合适的方法来做我所做的事情?


我这样做是因为箭头位置已更新并由多个类使用。

在许多情况下,您可以缩小范围。这减少了组件间的依赖性。

然而,我不确定这是一个好还是坏的设计决策。我的想法是,由于它是一条非关键信息(只是一个浮点数),因此在全局存储它时不会造成任何损害。但每次我对自己说“全局”这个词时,我的 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,并且它们不会受到全局状态的影响。再次,我无法使用提供的示例获得太具体的信息,但我认为这应该足以说明我最初概述的概念(我认为不需要进行项目范围的审查)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

应用程序委托中全局变量的替代方案 的相关文章

随机推荐

  • GPS 需要互联网吗?

    两个都需要转吗Internet and GPS在我可以在我的应用程序中读取我当前的位置 国家 城市 地区等 之前 如果是的话 那么有什么替代方法可以仅通过 GPS 获取位置吗 由于互联网可用性是一个问题 正如其他人所说 GPS 不需要互联网
  • DoExpressCheckoutPayment 或 /execute 交易始终处于待处理状态。为什么?

    当我将 PayPal 与我的沙盒测试帐户集成时 我通过DoExpressCheckoutPaymentAPI调用 或者PayPal的新 executeREST 呼叫正在等待处理 我必须手动接受它们 否则我必须等待 3 5 天 为什么 这种情
  • 为什么一些 PHP 程序员在其命名空间中使用双反斜杠而不是单个反斜杠?

    今天在扫描一些库代码时 我已经多次看到它 而不是声明一个Namespace Like This it s Done Like This 有人可以启发我吗 这背后的原因是什么 我只能想象它要么是特定于框架的东西 我不相信 要么是一种我不理解的
  • 如何在curses中启用鼠标移动事件

    如何在curses中启用鼠标移动事件 我找到了这个NCurses 中的鼠标移动事件 Xterm 控制序列 and ncurses 鼠标 移动但我不明白如何在 python curses 中启用鼠标移动事件 我认为它与 TERM xterm
  • 使用 Javascript 配置 Parsley,而不是 html 数据属性

    如何使用 javascript 而不是 html 数据属性来配置 Parsley 文档示例展示了如何使用 JS 配置 Parsley 表单实例和一些全局字段选项 但我也希望能够以这种方式添加和配置所有字段实例 我不想使用 html 数据属性
  • WinForms 应用程序由于 SystemEvents.OnUserPreferenceChanged 事件而挂起

    我一直在处理客户端安装中挂起的奇怪应用程序 在尝试了几件事之后 我得出的结论是 如果没有转储 它就无法工作 所以我在闲暇时从我的一位客户那里得到了转储 我必须注意 它只发生在我的安装中 而不是在我的开发计算机中 在我的转储中 我看到 Sys
  • 调用 FirebaseInstanceId.getToken 的行为

    我有两类问题FirebaseInstanceId getToken String authorizedEntity String scope 一是多次调用该方法 一是调用该方法是否触发FirebaseMessagingService onN
  • 解析非标准分号分隔的“JSON”

    我有一个非标准的 JSON 文件要解析 每个项目均以分号分隔 而不是逗号分隔 我不能简单地替换 with 因为可能有一些值包含 前任 你好世界 我怎样才能将其解析为与 JSON 通常解析它的结构相同的结构 client someone se
  • 抽象类的快速灵活的迭代器

    为了以快速灵活的方式遍历数据网格 我设置了一个抽象的 模板化的 GridDataStructure 类 数据应该由 STL 迭代器访问 当有人使用该类时 他不应该担心哪种 STL 迭代器适合特定的子类 这个问题的解决方案似乎是使用迭代器隐藏
  • 如何通过 ODBC 查询名称带有问号的 MS Access 列?

    我有一个 MS Access 数据库 Access 2002 供记录 它有一个名称包含问号的列 例如表 Users 其中包含 uid 和 isAdmin 列 我需要通过 ODBC 连接到该数据库 并按照以下几行查询该列 select uid
  • Excel VBA:“For”和“If”语句在一行上?

    是否有可能在VBA中放置一个For and If在一行中声明 我能得到的最接近的是 For i 0 To n If a i Then a b Next i 如果我写 For i 0 To n If a i Then a b Next i 我
  • Qt:如何使用 QSignalMapper 实现 QDialogBu​​ttonBox 用于非标准按钮?

    我有一个带有所有标准按钮和非标准按钮的 QDialogBu ttonBox 添加 QPushbutton 以创建非标准按钮 我可以为非标准按钮单独实现 SignalMapper 但在这种情况下 我必须添加 2 个插槽 QDialogBu t
  • Google 日历 API 事件空闲/忙碌/阻塞数据

    我一直在使用 Google Calendar API 并试图找出如何判断日历中的事件是否应被视为阻塞时间的事件 例如 哥伦布日 对于美国的许多人来说是一个全天的活动 假期 对他们的工作日没有影响 但会出现在日历上 我在其他地方读到 判断事件
  • 快速翻转动画翻转整个视图而不是子视图

    我需要在两个子视图之间切换 因为我使用翻转动画 但它翻转整个屏幕而不是子视图 这是我用来翻转的代码 UIView transitionFromView frontView toView backView duration 1 options
  • 如何编写一个无限循环来接收UDP数据?

    我正在尝试制作一个应用程序 它接收 UDP 数据并使用 python PyQt5 在列表视图中显示数据 当我启动接收器时 应用程序卡住并且没有响应 我怎样才能解决这个问题 请参阅下面的代码 import sys import os impo
  • 带有 LESS mixin 的“附加”属性值

    我正在寻找 LESS 中可能提供也可能不提供的功能 我有一个 mixin 它添加了带有框阴影的 发光 我在各种元素上使用它 按钮 输入等 glow box shadow 0 0 5px skyBlue 我正在寻找的是一种方法 如果元素已经有
  • 如何使用 PHP 7 安装 ext-curl 扩展?

    我已经使用安装了 PHP 7这个仓库 但是当我尝试跑步时composer install 它给出了这个错误 package 需要 ext curl gt 您的系统中缺少请求的 PHP 扩展curl 对于 PHP 5 您可以通过运行以下命令轻
  • 是否有任何解决方法可以使用最新的 Twitter REST API v1.1 获取 twitter 对话

    我正在开发一个项目 需要检索 Twitter 用户的对话 例如我想得到这条推文的所有回复英国广播公司世界服务台 使用休息 API v1 1我可以获得 Twitter 用户的时间线 推文 转发 但我没有找到任何有关获取特定推文回复的文档 工作
  • RxJS 等待 Promise 解决

    我仍在研究反应式编程 所以我很确定这是非常基础的 但是流转换的数量对于初学者来说是相当巨大的 我正在从 DOM 事件创建一个 Observable 此事件应依次触发 REST 调用 并且所有其他 DOM 事件将被忽略 直到此事件得到解决 c
  • 应用程序委托中全局变量的替代方案

    我正在开发一个带有速度计的应用程序 如动画 一个仪表和一个箭头来指示仪表上的某些内容 我将箭头的位置存储在应用程序委托中声明的全局变量中 我这样做是因为箭头位置已更新并由多个类使用 然而 我不确定这是一个好还是坏的设计决策 我的想法是 由于