You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust实现工厂模式时Terminal私有id字段无法被工厂赋值如何解决

解决方案

1. 用模块可见性控制构造权限(最简便)

Rust的可见性系统支持细粒度的访问限制,不需要friend关键字就能实现仅允许工厂访问构造函数的需求。你可以将Terminal和TerminalFactory放在同一模块下,给Terminal的构造函数设置模块级可见性,完全不会暴露给外部调用者:

mod terminal_core {
    #[derive(Debug)]
    pub struct Terminal {
        id: u32,
        pub name: String,
    }

    impl Terminal {
        // pub(crate) 仅当前 crate 可见,库的外部使用者完全无法调用
        pub(crate) fn new(id: u32, name: String) -> Self {
            Self { id, name }
        }

        pub fn get_id(&self) -> u32 {
            self.id
        }
    }

    pub struct TerminalFactory {
        next_id: u32,
    }

    impl TerminalFactory {
        pub fn new() -> Self {
            Self { next_id: 1 }
        }

        pub fn create_terminal(&mut self, name: String) -> Terminal {
            let terminal = Terminal::new(self.next_id, name);
            self.next_id += 1;
            terminal
        }
    }
}

// 对外仅暴露两个公共类型,隐藏构造函数
pub use terminal_core::{Terminal, TerminalFactory};

如果需要更严格的限制,可以把pub(crate)替换为pub(super)(仅父模块可见)或者pub(in crate::path::to::factory)(精确限定仅工厂所在路径可见),权限控制粒度远高于friend关键字。

2. 构造令牌方案(跨模块场景更灵活)

如果后续重构需要把两个类型拆分到不同模块,可以用零成本的私有令牌做权限校验,外部没有令牌根本无法调用构造函数:

// 私有令牌类型,仅工厂所在模块可以生成
#[derive(Debug, Clone, Copy)]
struct TerminalConstructToken;

pub struct Terminal {
    id: u32,
    pub name: String,
}

impl Terminal {
    // 构造函数强制要求传入私有令牌
    pub fn new(_token: TerminalConstructToken, id: u32, name: String) -> Self {
        Self { id, name }
    }

    pub fn get_id(&self) -> u32 {
        self.id
    }
}

pub struct TerminalFactory {
    next_id: u32,
}

impl TerminalFactory {
    pub fn new() -> Self {
        Self { next_id: 1 }
    }

    pub fn create_terminal(&mut self, name: String) -> Terminal {
        // 只有工厂能生成令牌完成构造
        Terminal::new(TerminalConstructToken, self.next_id, name)
    }
}

令牌是零大小类型,编译后会被完全优化,没有任何运行时开销。

关于设计模式与SOLID的说明

经典设计模式不需要硬套其他语言的实现逻辑,结合Rust的语言特性适配即可。你担心的非法实例问题Rust天然就能规避:只要Terminal存在私有字段,且没有对外暴露全参数构造函数,外部代码完全无法手动初始化Terminal实例,不可能出现非法的id值。
Rust的组合优先、trait接口隔离、所有权规则本身就非常贴合SOLID原则的核心要求,中等规模项目完全可以落地,不需要照搬OOP语言的实现套路。

内容的提问来源于stack exchange,提问作者pid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 15:36:04