RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 777155
Accepted
Мистер Фикс
Мистер Фикс
Asked:2020-01-29 19:21:49 +0000 UTC2020-01-29 19:21:49 +0000 UTC 2020-01-29 19:21:49 +0000 UTC

对象的组成。在大班上遵守“得墨忒耳定律”有意义吗

  • 772

我尝试根据 SOLID 规则培养设计技能。

有一个大的逻辑相关类代表一个真实世界的对象。假设一个类中有大约 40 个方法来表示该对象的行为。

大概有数百种方法。如果它们在逻辑上连接,那么这是允许的,据我所知。

但是使用它们很不方便。我希望类别可以更方便地使用课程。

用三种不同的方式写了一个类似的课程。根据建议,我尝试使用组合而不是继承。

汽车——最简单的,但如果有四十或一百种方法,那就不方便了,过一段时间就很难弄清楚了。

Car2 -是一个组合,但违反了 SOLID 规则的“Demeter 法则”,因为客户不仅知道 Car2,还知道他的朋友。

Car3 -不违反任何东西,封装了每个类,但是方法的数量和第一个版本一样,不是很方便。

在我看来,第二个版本是最方便的。第三个在方法的数量上与第一个没有区别,但似乎是最正确的一个。

如果有人明白,指出错误。我采取了正确的方法吗?哪种方法最合适?

class Car:

    def __init__(self):
        self._speed = 0
        self._name = "Car"

    def __str__(self):
        return self.name

    @property
    def speed(self):
        return self._speed

    @property
    def name(self):
        return self._name

    def turn_left(self): pass

    def turn_right(self): pass

    def accelerate(self): pass

    def brake(self): pass

    def windscreen_wiper_on(self): pass

    def windscreen_wiper_of(self): pass


# -----------------------------------------------------------------------
class Car2():

    def __init__(self):
        self._speed = 0
        self._name = "Car"
        self._stering_wheel = SteringWheel(self)
        self._gas_pedal = GasPedal(self)
        self._windscreen_wiper = WindscreenWiper(self)

    def __str__(self):
        return self.name

    @property
    def speed(self):
        return self._speed

    @speed.setter
    def speed(self, value):
        self._speed = value
        print("Новая скорость машины:", self._speed)

    @property
    def name(self):
        return self._name

    @property
    def stering_wheel(self):
        return self._stering_wheel

    @property
    def gas_pedal(self):
        return self._gas_pedal

    @property
    def windscreen_wiper(self):
        return self._windscreen_wiper


# -----------------------------------------------------------------------
class Car3:
    def __init__(self):
        self._speed = 0
        self._name = "Car"
        self._stering_wheel = SteringWheel(self)
        self._gas_pedal = GasPedal(self)
        self._windscreen_wiper = WindscreenWiper(self)

    def __str__(self):
        return self.name

    @property
    def speed(self):
        return self._speed

    @speed.setter
    def speed(self, value):
        self._speed = value
        print("Новая скорость машины:", self._speed)


    def turn_left(self):
        self._stering_wheel.turn_left()

    def turn_right(self):
        self._stering_wheel.turn_right()

    def accelerate(self):
        car.gas_pedal.press()

    def brake(self):
        car.gas_pedal.depress()

    def windscreen_wiper_on(self):
        car.windscreen_wiper.on()

    def windscreen_wiper_of(self):
        car.windscreen_wiper.off()



# ---------------------------- Компоненты машины ------------------------------
class SteringWheel:

    def __init__(self, car: Car):
        self._car = car

    def rotate_left(self):
        print(self._car.name, "повернула влево")

    def rotate_right(self):
        print(self._car.name, "повернула вправо")


class GasPedal:

    def __init__(self, car: Car):
        self._car = car

    def press(self):
        self._car.speed += 1

    def depress(self):
        self._car.speed -= 1


class WindscreenWiper:

    def __init__(self, car: Car):
        self._car = car

    def on(self):
        print("Дворники", self._car.name, "очищают окно.")

    def off(self):
        print("Дворники", self._car.name, "выключились.")


# ---------------------------------------------------------------------------
def main():
    car = Car2()
    car.gas_pedal.press()
    car.gas_pedal.press()
    car.gas_pedal.depress()
    car.windscreen_wiper.on()
    car.windscreen_wiper.off()
    car.stering_wheel.rotate_left()


main()
ооп
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Kromster
    2020-01-29T19:32:17Z2020-01-29T19:32:17Z

    第二个选项更简单明了。我们只需要稍微不同地看待它。

    得墨忒耳定律说,“司机”不应该知道汽车是如何被控制的——通过方向盘、方向盘或绳索。但是如果一辆车总是有一个实体来控制(经理),那么它可以被移动到一个单独的类并用作car.steering.something。

    这同样适用于gas_pedal- 你不能以这种形式在外面“展示”它。突然间,取而代之的是变阻器或杠杆。但是,如果您将其“设置”为速度控制 ( accelerator),那么一切都会井井有条。

    如果你能挑出一个类的所有后代都实现的行为,并且这种行为与类密不可分(即每台机器都会有一个控制器和speed_controller),那么很有可能将它移到一个单独的类(并替换此类中的不同实现)。

    本质上,通过 2 种方式,您可以获得:

    A. 方法的树分组:

    car.steering_left
       .steering_right
       .steering_center
       .gaspedal_more
       .gaspedal_less
    
    car.steering.left
                .right
                .center
       .gaspedal.more
                .less
    

    B. 替换执行组件的可能性。

    PS 最后,对于反思 - 最佳实践在 80-99.9% 的情况下可能是好的,但是当 goto 或 12 个输入参数,或者 120 行方法将是合理的,比以下更容易或更好时,总会有 %一般好的规则。

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5