1.需求:(3种车机/手机UI切换)
Android 新能源车机,手机竖屏,手机横屏3种情况的UI, 数据来源有多个,分不同的品牌,有小米,蔚来,理想,比亚迪,大部分相同,仅仅有一点差别
2.方案:(抽象工厂+策略模式)
为了满足 Android 车机、手机竖屏、手机横屏 三种 UI 场景下使用 同一份数据源(DataManager) ,且 不同品牌间数据结构基本一致、仅少量差异 的需求,我们可以采用以下设计原则:
- 单一数据源 :
DataManager提供统一接口。 - 策略模式 / 工厂模式:根据设备类型和品牌动态提供适配器或视图模型。
- 低耦合 + 高扩展性:UI 层不直接依赖具体品牌逻辑,而是通过抽象接口获取数据。
根据需求,这里采用MVP模式+抽象工厂+策略模式来处理不同品牌和设备的UI差异:
3.架构图

4.主要的代码
因为公司的保密问题,把核心的思想分析成一个demo!如下:
🔹 数据层:统一接口
csharp
/**
* 品牌数据统一接口(IBrandData)
* 所有新能源汽车品牌必须实现此接口,保证上层调用一致性
*/
public interface IBrandData {
String getCommonField(); // 通用信息(如续航、车型)
String getBrandSpecificField(); // 品牌特有功能(如换电、生态互联等)
}
🚗 数据层实现:四个品牌(小米、蔚来、理想、比亚迪)
typescript
/** 小米汽车数据 */
class XiaomiBrandData implements IBrandData {
@Override
public String getCommonField() {
return "小米SU7 通用信息:800V高压平台,CLTC续航800km";
}
@Override
public String getBrandSpecificField() {
return "小米澎湃OS生态互联:手机-车机无缝流转";
}
}
/** 蔚来汽车数据 */
class NIOBrandData implements IBrandData {
@Override
public String getCommonField() {
return "蔚来ET5 通用信息:双电机四驱,换电兼容";
}
@Override
public String getBrandSpecificField() {
return "蔚来换电站 + NOMI智能情感引擎";
}
}
/** 理想汽车数据 */
class LiAutoBrandData implements IBrandData {
@Override
public String getCommonField() {
return "理想L系列 通用信息:家庭六座SUV,增程电动";
}
@Override
public String getBrandSpecificField() {
return "城市NOA + 增程式无里程焦虑";
}
}
/** 比亚迪汽车数据 */
class BYDBrandData implements IBrandData {
@Override
public String getCommonField() {
return "比亚迪汉EV 通用信息:刀片电池,e平台3.0";
}
@Override
public String getBrandSpecificField() {
return "云辇智能车身控制系统 + DiLink生态";
}
}
📱 设备类型 & UI 策略(保持不变,仅微调注释)
kotlin
/**
* 设备类型枚举:用于区分 UI 渲染上下文
*/
public enum DeviceType {
CAR, // 车载中控(大屏、驾驶安全优先)
PHONE_PORTRAIT, // 手机竖屏(信息精简)
PHONE_LANDSCAPE // 手机横屏(信息完整展示)
}
/**
* UI 渲染策略接口:不同设备使用不同展示逻辑
*/
public interface IUiStrategy {
void render(IBrandData data);
}
// 具体策略实现(略,同你原有代码,仅接口名改为 IBrandData)
class CarUiStrategy implements IUiStrategy {
@Override
public void render(IBrandData data) {
System.out.println("[CAR] " + data.getCommonField() + " | " + data.getBrandSpecificField());
}
}
class PhonePortraitStrategy implements IUiStrategy {
@Override
public void render(IBrandData data) {
System.out.println("[PHONE-PORTRAIT] " + data.getCommonField());
}
}
class PhoneLandscapeStrategy implements IUiStrategy {
@Override
public void render(IBrandData data) {
System.out.println("[PHONE-LANDSCAPE] " + data.getCommonField() + " + " + data.getBrandSpecificField());
}
}
🧩 数据管理器(DataManager)------ 支持四大品牌
java
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
/**
* 数据管理器:统一入口,按品牌返回对应数据
* 使用工厂注册机制,支持动态扩展
*/
public class DataManager {
private static final Map<String, Supplier<IBrandData>> BRAND_FACTORY = new HashMap<>();
static {
BRAND_FACTORY.put("xiaomi", XiaomiBrandData::new);
BRAND_FACTORY.put("nio", NIOBrandData::new);
BRAND_FACTORY.put("liauto", LiAutoBrandData::new);
BRAND_FACTORY.put("byd", BYDBrandData::new); // ✅ 新增比亚迪
}
private final String brand;
public DataManager(String brand) {
this.brand = brand.toLowerCase();
}
public IBrandData getBrandData() {
Supplier<IBrandData> factory = BRAND_FACTORY.get(brand);
if (factory == null) {
throw new IllegalArgumentException("不支持的品牌: " + brand + "。支持: " + BRAND_FACTORY.keySet());
}
return factory.get();
}
}
🔗 UI 协调器(核心适配器)
arduino
/**
* UI 协调器:组合品牌数据 + 设备策略
* 是 MVP 中 Presenter 层的理想载体
*/
public class UiCoordinator {
private final DataManager dataManager;
private final IUiStrategy uiStrategy;
public UiCoordinator(String brand, DeviceType deviceType) {
this.dataManager = new DataManager(brand);
this.uiStrategy = createStrategy(deviceType);
}
private IUiStrategy createStrategy(DeviceType type) {
switch (type) {
case CAR: return new CarUiStrategy();
case PHONE_PORTRAIT: return new PhonePortraitStrategy();
case PHONE_LANDSCAPE: return new PhoneLandscapeStrategy();
default: throw new IllegalStateException("未知设备类型: " + type);
}
}
public void display() {
IBrandData data = dataManager.getBrandData();
uiStrategy.render(data);
}
}
🖥️ 主程序(测试入口)
typescript
public class Main {
public static void main(String[] args) {
String[] brands = {"xiaomi", "nio", "liauto", "byd"}; // ✅ 包含比亚迪,不含小鹏
DeviceType[] devices = {DeviceType.CAR, DeviceType.PHONE_PORTRAIT, DeviceType.PHONE_LANDSCAPE};
for (String brand : brands) {
System.out.println("🔹 品牌: " + brand.toUpperCase());
for (DeviceType device : devices) {
new UiCoordinator(brand, device).display();
}
System.out.println();
}
}
}
✅ 最终架构图
sql
+---------------------+
| UI 展示层 (View) |
| - Activity/Fragment |
| - 根据配置调用 |
| UiCoordinator |
+----------+----------+
|
+----------v----------+
| 适配层 (Presenter) |
| - UiCoordinator |
| - IUiStrategy |
| - DeviceType |
+----------+----------+
|
+----------v----------+
| 数据层 (Model) |
| - DataManager |
| - IBrandData |
| - Xiaomi/NIO/Li/BYD |
+---------------------+
5 .设计要点说明总结:
| 特性 | 实现方式 | 优势 |
|---|---|---|
| 品牌扩展 | BRAND_FACTORY 注册 |
新增品牌只需加一行 |
| 设备适配 | DeviceType + 策略模式 |
横竖屏/车机自动切换 |
| 低耦合 | 全程依赖接口(IBrandData, IUiStrategy) |
易测试、易替换 |
| MVP友好 | UiCoordinator ≈ Presenter |
业务逻辑与 View 分离 |
| 健壮性 | 非法品牌抛出明确异常 | 快速定位配置错误 |
-
数据层:
DataManager单例管理数据,通过策略模式处理品牌差异IBrandDataStrategy接口允许灵活扩展新品牌
-
UI层:
- 抽象工厂模式创建不同设备类型的视图
- 每种设备类型有基类视图,品牌再继承实现差异
- 支持屏幕旋转自动适配
-
业务层:
- MVP模式分离业务逻辑
- 不同设备类型可有特定Presenter
-
扩展性:
- 新增品牌:实现
IBrandDataStrategy和IUIFactory - 新增设备类型:添加
DeviceType枚举和对应视图 - 数据变化:观察者模式通知更新
- 新增品牌:实现
-
低耦合:
- 依赖接口而非实现
- 各层之间通过接口通信
- 配置集中管理
5.2 设计模式应用总结
5.2.1. 策略模式 (Strategy Pattern)
- 应用 :
IUiStrategy接口 + 具体策略类 - 目的: 根据不同设备类型切换UI渲染逻辑
- 优势: 易于扩展新设备类型,符合开闭原则
5.2.2. 工厂模式 (Factory Pattern)
- 应用 :
DataManager中的品牌工厂注册表 - 目的: 统一创建品牌数据对象
- 优势: 集中管理对象创建,支持动态注册
5.2.3. 接口隔离原则 (Interface Segregation)
- 应用 :
IBrandData只定义必要方法 - 目的: 品牌实现类只实现需要的方法
- 优势: 避免接口臃肿,提高灵活性
5.2.4. 依赖倒置原则 (Dependency Inversion)
- 应用: 高层模块依赖抽象接口而非具体实现
- 目的: 降低模块间耦合度
- 优势: 提高代码可测试性和可维护性
这个架构支持灵活扩展新品牌和设备类型,同时保持代码的可维护性和可测试性。