服务工厂方法是一种设计模式,用于动态创建和管理服务实例。它的核心思想是将对象的创建逻辑封装在一个方法中,而不是直接在代码中硬编码对象的创建过程。这样可以提高代码的灵活性、可维护性和可扩展性。
1. 服务工厂方法的核心思想
目的:根据不同的条件(如服务类型、设备名称)动态创建服务实例。
特点:
封装创建逻辑:将对象的创建逻辑集中在一个方法中,避免代码重复。
统一管理:通过工厂方法统一管理对象的创建和缓存。
灵活扩展:可以轻松添加新的服务类型,而无需修改调用方的代码。
2、应用场景
服务工厂方法不仅适用于服务实例的创建,还可以用于以下场景:
数据库连接池:根据数据库类型和配置动态创建日志记录器。
插件系统:根据插件类型动态加载和初始化插件。
根据设备名称和服务类型获取相应的服务实例,主要是为了 实现灵活的服务管理 和 优化资源利用。
1. 多设备支持
场景:在自动化测试或设备管理中,通常需要同时管理多个设备(如多台 Android设备)。
需求:每个设备可能需要独立的服务实例(如 ADBCommand 或 UIAutomation),以便分 别执行命令或操作。
解决方案:通过设备名称(device_name)区分不同设备的服务实例。2. 多服务类型支持
场景:不同的任务可能需要不同的服务类型。例如:
使用 ADBCommand执行 ADB 命令。
使用 UIAutomation 进行 UI 自动化操作。
需求:根据任务类型动态选择服务实例。解决方案:通过服务类型(service_type)区分不同的服务实例。
3. 资源优化
场景:创建服务实例(如 ADBCommand 或 UIAutomation)可能涉及资源开销(如初始化 连接、加载配置等)。
需求:避免重复创建相同的服务实例,减少资源浪费。
解决方案:通过缓存机制(cls.service_collection)复用已创建的服务实例。
3、代码示例
1、获取 driver 对象
通过 ServiceManager 获取 UIAutomation 服务实例,并从中获取 driver 对象。
self.driver = ServiceManager.get_service(SERVICE_UIAUTOMATION, 'media').driver
ServiceManager:服务管理类,用于根据服务类型和设备名称获取服务实例。
get_service:工厂方法,用于获取服务实例。
SERVICE_UIAUTOMATION:服务类型常量,表示 UIAutomation 服务。
'media':设备名称,表示服务实例关联的设备。
返回值:返回 UIAutomation 服务实例。2、 .driver
driver:UIAutomation 服务实例的一个属性,通常是一个 UI 自动化驱动对象(如 Selenium 的 WebDriver 或 Appium 的 AppiumDriver)。
作用:用于控制设备的 UI 自动化操作,如点击、输入、滑动等。self.ui_auto 可以直接操作控制设备,而不需要显式地访问 .driver,这通常是因为UIAutomation 类本身已经封装了设备控制的相关逻辑。
3、self.driver = ...
self.driver:将获取到的 driver 对象赋值给当前类的实例属性。
目的:在当前类中保存 driver 对象,以便后续使用4、整体逻辑
(1)获取服务实例:
通过 ServiceManager.get_service(SERVICE_UIAAUTOMATION, 'media') 获取 UIAutomation 服务实例。
(2)获取驱动对象:
从 UIAutomation 服务实例中获取 driver 对象。
(3)保存驱动对象:
将 driver 对象赋值给 self.driver,以便在当前类中使用。
4、区别
特性 | u2.connect_usb(self.deviceid) | ServiceManager.get_service(...).driver |
用途 | 控制 Android 设备 | 控制特定应用或媒体内容(具体取决于服务实现) |
依赖库 | uiautomator2 | 依赖于 ServiceManager 和 SERVICE_UIAUTOMATION 服务 |
连接方式 | 通过 USB 连接到设备 | 通过服务管理器获取驱动实例 |
适用场景 | Android 设备自动化 | 特定应用或媒体自动化(如 Windows 应用或媒体播放器) |
灵活性 | 直接控制设备,灵活性较高 | 依赖于服务封装,灵活性较低 |