【发布时间】:2014-05-05 23:55:49
【问题描述】:
我正在开发一个 iOS 应用程序,并计划在其中使用 分析 服务,例如 Flurry 或 Google Analytics。问题是:使用这些服务的良好软件设计(松散耦合、高度内聚、易于维护)是什么?
这是我的一个个人项目,我正在使用它来研究新技术和最佳实践。我偶然发现了这个“挑战”,并没有真正找到最佳解决方案。
我已经开发了一些使用这种服务的移动应用程序,并且通常我实现了适配器 + 工厂设计模式的组合:
-
创建代表通用分析服务的基本接口
public interface IAnalytics { void LogEvent(string name, object param); } -
每个服务(Flurry/Google Analytics/etc)API 都通过使用实现此接口的适配器进行封装
public class FlurryService : IAnalyticsService { public LogEvent(sring name, object param) { Flurry.Log(name, param.ToString()); } } -
实现了一个工厂,以便我们在该特定应用程序上拥有所需的任何分析服务
public static class AnalyticsServiceFactory { public IAnalytics CreateService(string servicename) { if(servicename == "google") { return new GoogleAnalyticsService(); } else { return new FlurryService(); } } } -
最后,创建了一个“代理”对象(不是按规定)来记录特定于应用程序的事件
public class MyAnalytics { private static IAnalyticsService _Service = AnalyticsServiceFactory.CreateService("flurry"); public static void LogUserLoggedIn(string user) { _Service.LogEvent("login", user); } public static void LogLoginFailed(string user) { _Service.LogEvent("login", user); } }
这处理了每个服务 API 的封装并且效果很好,特别是在不同平台之间共享代码的应用中。
然而,还有一个问题是事件(或用户执行的操作)本身的日志记录。在我处理过的所有情况下,无论何时发生此类事件,事件的记录都是硬编码的。例如:
public void LogIn(string userName, string pass) {
bool success = this.Controller.LogIn(userName, pass);
if(success) {
MyAnalytics.LogUserLoggedIn(username);
// Change view
} else {
MyAnalytics.LogLogInFailed(username);
// Alert
}
}
这似乎比我想要的更耦合,所以我正在寻找更好的解决方案。
在使用 iOS 时,我考虑过使用 NSNotificationCenter:每当事件发生时,我不会立即记录它,而是在 NSNotificationCenter 中发布通知,另一个观察这些通知的对象负责调用 MyAnalytics 记录事件。然而,这种设计仅适用于 iOS(也就是说,不需要大量的工作)。
看待这个问题的另一种方式是:游戏如何跟踪你的行为以达到 Xbox 成就/Playstation 奖杯?
【问题讨论】:
-
你决定选择什么?
-
@edelaney05 最后,我决定采用我在问题中提出的建议:使用通知中心发布有关事件发生的通知,然后让这些通知的侦听器处理日志记录和所有事情。每个通知都带有事件 ID 和带有相关信息(例如触发事件的用户的名称)的对象(通常是字符串)。在 iOS 之外,您将不得不实现通知中心,这很糟糕,但如果您注意可能存在的内存泄漏,它可能会正常工作。
-
我发现了这种方法 - aspect-oriented programming - 但感觉有点太聪明了。
标签: ios mobile google-analytics flurry