【问题标题】:Special services for different types of models in OOPOOP中不同类型模型的特殊服务
【发布时间】:2020-10-11 17:58:15
【问题描述】:

这个问题与面向对象语言的语言无关。

我有两个类:DeviceADeviceB,它们继承自模型类Device。 我需要实现两个服务DeviceAServiceDeviceBService,它们继承自DeviceService。 我的语言不支持泛型,我需要在DeviceService 中实现带有Device 参数的方法,该参数将在DeviceAServiceDeviceBService 中被覆盖,并根据Device 的类型以不同方式实现。然后我想从通用的DeviceService 中调用这些函数。

设计这个的最佳实践是什么?在这里使用if 和检查类类型是不可避免的吗?以最佳方式实现此设计的另一个想法?

【问题讨论】:

  • 这听起来像是过程编程而不是 OOP。数据属于一类;逻辑在另一个。您必须将数据结构传递到过程中。 OOP 会将两者结合起来,并在同一个类中使用它需要的数据来实现逻辑。那么逻辑就变成多态了。
  • 您可以让 DeviceA 和 DeviceB 类从 Device 继承,也可以从 mixin Service 继承,或者如果没有多重继承,则 Device 从(或使用)Service 继承(然后可能会调用 mixin一个接口)
  • 对象也可以包含专门的服务对象。

标签: oop design-patterns


【解决方案1】:

如果我正确理解了这个问题,你有一个像这样的抽象基类:

public abstract class DeviceService
{
    public abstract void DoSomething(Device device);
}

您希望实现DeviceAServiceDeviceBService,以便它们的行为根据Device 的类型而有所不同。

多态性

最面向对象的设计是使用多态性。由于Device 已经是多态的,请将您想要不同的行为放入多态方法中,并从您的服务中调用它:

public override void DoSomething(Device device)
{
    // Perhaps do something first...
    device.DoThePolymorphicThing();
    // Perhaps do something else after...
}

DeviceADeviceB 中以不同方式实现DoThePolymorphicThing

开放世界

如果您无法更改Device 基类的API,并且您还需要支持DeviceADeviceB 之外的其他实现,您可能需要在@ 中执行运行时检查987654334@:

public override void DoSomething(Device device)
{
    if (device is DeviceA)
        // Do something...
    else if (device is DeviceB)
        // Do something else...
    else
        // remember to handle the case where it's neither A nor B
}

我们可以将这种类型的场景称为“开放世界”,因为Device 对可扩展性开放。

封闭的世界

另一方面,如果您知道自己只会拥有DeviceADeviceB,那么Visitor 设计模式正是您所需要的: p>

public interface IDeviceVisitor
{
    void VisitA(DeviceA device);
    void VisitB(DeviceB device);
}

public abstract class Device
{
    public abstract void Accept(IDeviceVisitor visitor);
    // Other members go here if you need them...
}

public class DeviceA : Device
{
    public override void Accept(IDeviceVisitor visitor)
    {
        visitor.VisitA(this);
    }

    // Other overrides, if needed, go here...
}

// Define DeviceB in the same way...

您现在可以像这样实现服务:

public override void DoSomething(Device device)
{
    // Perhaps do something first...
    device.Accept(new MyDeviceVisitor());
    // Perhaps do something else after...
}

您可以将此场景视为“封闭世界”场景,因为您无法在不更改访问者 API 的情况下添加第三种设备(从而破坏现有实现)。

【讨论】:

  • 我觉得你的方法很有趣。但是,我宁愿将我的 Device 类保留为普通模型,而不是在其中实现任何业务逻辑方法。我宁愿在服务中实现我的方法。不过,您的意见非常有用,也是一种可行的方法。
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多