我在Rust中实现了Repository模式的实现.
我需要两个(或更多)文件:
entity.rs
- 数据描述
repository.rs
- 数据访问方法
...
问题:
一个文件意味着一个mod.这意味着,对于一个功能repository.rs
从有机会获得结构领域entity.rs
,要求field
是pub
.有没有办法避免这种情况?
在Rust中,模块是独立的.与C++或Java不同,它既不会作弊,也不会friend
使用反射.
因此,如果您(任意)尝试将该定义与struct
负责维护其封装的方法分开,您将与该语言作斗争.
解决方案1:首选非会员非朋友功能
定义绝对需要访问字段的方法entity.rs
; 如果您遵循C++中的"首选非成员非朋友功能"指南,您应该看到实际上大多数方法不需要直接访问这些字段.例如,empty
可以用以下术语定义len
:
fn empty(c: &Container) -> bool { c.len() == 0 }
然后,repository.rs
如果需要可以添加许多其他方法,但必须通过导出的"最小"接口entity.rs
来实现其需求.由于您可以控制两个模块,entity.rs
因此无论如何都可以随意调整方法,因此它不应成为问题.
我想指出的是封装的角度来看,这是对明智的决定:减少可能会访问一个对象的内部方法的数量减少了,可能把这个对象处于无效状态的方法数.
这种解决方案是有利的,因为你没有对抗语言.
解决方案2:总分裂
另一种解决方案是复制您的实体:
拥有内部实体,完全公开
拥有外部实体,不透明
这通过以下方式实现:
pub struct SomeEntImpl { pub field0: i32, } pub struct SomeEnt { inner: SomeEntImpl, }
授权模块将被引用a SomeEntImpl
,而其他模块将必须使用可用的受限制接口SomeEnt
.控制谁看到通过谨慎出口将实现什么.
这个解决方案可能会让你疯狂.