我想为某些Unix设备创建驱动程序映射。为了有效地访问驱动程序文件,我希望在第一次访问后保持打开文件句柄,因此我想在地图中存储访问包装。每个设备都有不同(但有时很常见)的方法。
在像Java这样基于OOP的语言中,我将使用此映射和访问该映射的派生类来创建一个抽象类。
class Attribute {
void doSomething() { /* Do Something */ }
}
abstract class Device {
Map<String, Attribute> attributes = new HashMap<>();
}
class Motor extends Device {
void func1() {
attributes.get("elem1").do_something();
}
}
class SpecialMotor extends Motor {
void func2() {
attributes.get("elem2").do_something();
}
}
class Sensor extends Device {
void func1() {
attributes.get("elem1").do_something();
// Its possible that this function has a different return type
}
}
据我所知,在Rust中这是不可能的。我试图用特征来模仿这种行为,以访问此地图,但这为每个设备创建了很多样板代码。
struct Attribute {}
impl Attribute {
fn do_something() {}
}
trait Device {
fn get_attributes(&self) -> HashMap<String, Attribute>;
}
trait Motor: Device {
fn func1(&self) {
self.get_attributes()["elem1"].do_something();
}
}
trait SpecialMotor: Motor {
fn func2(&self) {
self.get_attributes()["elem2"].do_something();
}
}
trait Sensor: Device {
fn func1(&self) {
self.get_attributes()["elem1"].do_something();
}
}
struct MotorImpl {
attributes: HashMap<String, Attribute>,
}
impl MotorImpl {
fn new() -> MotorImpl {
MotorImpl {
attributes: HashMap::new(),
}
}
}
impl Motor for MotorImpl {
fn get_attributes(&self) -> HashMap<String, Attribute> {
self.attributes
}
}
struct SpecialMotorImpl {
attributes: HashMap<String, Attribute>,
}
impl SpecialMotorImpl {
fn new() -> SpecialMotorImpl {
SpecialMotorImpl {
attributes: HashMap::new(),
}
}
}
impl SpecialMotor for SpeicalMotorImpl {
fn get_attributes(&self) -> HashMap<String, Attribute> {
self.attributes
}
}
struct SensorImpl {
attributes: HashMap<String, Attribute>,
}
impl SensorImpl {
fn new() -> SensorImpl {
SensorImpl {
attributes: HashMap::new(),
}
}
}
impl Sensor for SensorImpl {
fn get_attributes(&self) -> HashMap<String, Attribute> {
self.attributes
}
}
是否可能具有多个特征的共同属性,或者是否有更好的设计模式来实现这一目标?