代码之家  ›  专栏  ›  技术社区  ›  Dan

你怎么给洗衣机编代码?

  •  11
  • Dan  · 技术社区  · 14 年前

    . 我看到两个基本的选择:

    1. 我可以有一个洗衣机类的方法 问题是接口没有说明正确的操作顺序。我最多可以抛出invalidopractionexception,如果客户端试图在机器启动前离心。我还可以使用一个separate程序类,它将离心机转速和洗涤分钟数传递给洗衣机,并将简化这些方法。

    2. 我可以让类本身负责正确的转换,并拥有一个方法 下一步操作() . 另一方面,问题是语义不好。客户机将不知道调用nextoOperation()时会发生什么。假设您实现了离心机按钮click事件,因此它调用nextoOperation()。用户按下离心机按钮后,机器被打开和ups!机器开始清洗。我可能需要我的类上的一些属性来参数化操作,或者可能需要一个带有washLength和离心机revs字段的单独的程序类,但这并不是真正的问题。

    哪种选择更好?或者也许有其他更好的选择,我没有描述?

    10 回复  |  直到 12 年前
        1
  •  5
  •   ScottS    14 年前

    我认为 打开() , , 等应该是私有/受保护的方法。公共接口应该是 doTheWash(清洗模式)

        2
  •  15
  •   drfrogsplat    14 年前

    我会有一个“高水平” State Machine 类,该类控制每个状态的进入/运行/退出(其中状态可以是“filling”、“washing”、“rinse”、“emptying”、“spin dry”等)

    起草一份 State Transition Diagram 所有你需要的州,包括(每个州)

    1. 进入状态时需要发生什么(进入操作)
    2. 状态期间发生了什么(任务本身)
    3. 离开州前有什么要求(退出条件)

    您可能需要也可能不需要进入/退出条件(例如,在某些情况下,您可以通过进入/退出操作强制条件)。不过,出于安全考虑,有些情况可能是好的(例如,从“待机”状态退出或进入“危险”状态,如甩干)

    你也创造了 Transitions

    1. “从”状态
    2. “到”状态
    3. 过渡动作(过渡时需要做什么)

    同样,您可能不需要所有这些,并且许多转换将只指定“from”和“to”状态。

    在这两种情况下,试着保持每一个 State Transition 就这么简单 未来(试着把条件/行动放在最有意义的地方,很明显,这些条件/行动可能会在一个特定的环境中被定义 过渡 因为通用设计)

    很明显,在这一点上,你可以做一个相当通用的 类,该类包括所有这些内容的抽象/可重载函数,以及 过渡 状态机 类可以根据请求的转换,根据需要调用这些成员函数中的每一个。

    States 可以注册到 状态机 在构建时,或者您可以只编写 状态机

    然后您可以请求转换,从 在内部 状态(即,一个特定的状态可以知道它何时结束,并知道下一个状态)或者您可以有一个控制状态转换的外部类(每个状态都非常简单,只考虑它自己的操作,外部类决定转换的顺序和时间)。

    根据我的经验,最好将每个动作的顺序/计时的高级逻辑与对某些硬件事件的反应的低级逻辑分开(例如,当水位达到时,从“填充”状态过渡出来)。

    不过,这是一个非常通用的设计,你可以通过多种不同的方式实现完全相同的功能——很少有

        3
  •  1
  •   Erik Funkenbusch    14 年前

    大多数西方洗衣机都使用定时器来在一个周期和另一个周期之间移动。这个计时器可以看作某种状态机。然而,重要的是要认识到,wasching机器是自己运行的,而不是用户。用户设置初始模式,然后继续其业务。

    因此,在内部,可能有Wash、Rinse、Spin私有函数,实际的接口是SetCycle()和Start()以及Stop()。你也可能有一些额外的属性,如水位,搅拌速度,水温等。。。

    开始使时间前进,一段时间后进入下一个状态,直到最后完成。

        4
  •  1
  •   Andreas Dolk    14 年前

    控制器 程序 . 对于旧的和简单的机器,程序和控制器被集成到一个相当复杂的旋钮中,现代的和更昂贵的机器有一台计算机。

    无论哪种情况,机器都有附加的子系统和控制器 通知 执行某些操作的子系统,如 把门锁上 , 把水加热到40度°C 旋转鼓

    控制器本身知道序列,这是相当线性和定时器为基础的旧机器或复杂的现代系统,改变了基于传感器数据的序列。但在这两种情况下,它都会执行一系列命令,通知传感器和参与者。

    如果你从这个角度看洗涤系统,你可能想利用 控制器内部的模式,用于模拟清洗程序和 观察员 通知子系统的模式(如:

        5
  •  0
  •   Michael Mrozek    14 年前

    第一个就是我要做的。 wash centrifuge 离心机 之前

        6
  •  0
  •   griegs    14 年前

    我甚至会看到代表们。所以对于一个特定的洗涤循环类型,起伏,轻,泡沫,经济等,我会说每个接口。

        7
  •  0
  •   Timothy Carter    14 年前

    洗衣机应该知道如何正确地运转。可能在清洗负载之前,需要设置某些配置项(如果未设置,则使用默认值),例如什么类型的负载(亮与暗)或大小(小、中、大)。用户(另一个类)应该知道如何正确配置要运行的负载,但是对于清洗负载,洗衣机应该只需要公开一个方法,比如 washLoad . 在内部,它将管理什么时候需要洗一堆衣服。

    或者,您仍然可以公开用于打开和关闭洗衣机的公共函数,如果 如果在清洗器关闭时调用,则应该抛出异常。另外,在这个场景中,我可能会通过一个方法设置垫圈组 setLoadOptions 那要上另一门课 LoadOptions

        8
  •  0
  •   Joe Phillips    14 年前

    我的洗衣机上有两个把手。我有点搞不清楚你的情况有什么局限性。

    1. 负载大小(小、中、大)
      • 每个循环包含不同的“阶段”,在该阶段可以在

    当你“启动”一个循环时(通过转动旋钮),如果你把它转到一个循环的中间或开始,机器将开始运转。

    下面是一个非常非常基本的例子,我将如何将其转换为一个类:

    class WashingMachine
    {
        public void Activate(Cycle c, LoadSize s);
        ...
    }
    
        9
  •  0
  •   Adam Gent    14 年前

    最近我一直在 功能性 Martin Fowler/JQuery链接流畅风格

    • 我尽可能多地使用类型系统进行重构。
    • 用我的方法,编译器会强迫你做正确的事。
    • 因为对象在某种程度上是不可变的,所以从数学上证明这个状态机是确定性的就更容易了。

    代码:

    public class Washer {
        public void exampleRun() {
            new On()
                .wash(30)
                .spin(100)
                .turnOff();
        }
        public abstract static class State {}
        public static class On extends State {
            public Wash wash(int minutes) {
                return new Wash(minutes);
            }
        }
        public static class Wash extends State {
            private int minutes;
            public Wash(int minutes) {
                super();
                this.minutes = minutes;
            }
    
            public Spin spin(int revs) {
                return new Spin(revs);
            }
    
        }
        public static class Spin extends State {
            private int revs;
            public Spin(int revs) {
                super();
                this.revs = revs;
            }
            public Off turnOff() {
                return new Off();
            }
        }
        public static class Off extends State{}
    }
    
        10
  •  0
  •   Codism    14 年前

    选项A类似于手动洗衣机,而选项B类似于自动洗衣机。这两个选项对目标用户都很有用:

    选择A的用户可以享受手动编程的整个过程(比如加倍洗衣循环,或教导小家伙如果你关掉机器,而它在离心循环)。

    选择B的用户可以享受简单和写一个虚拟的连续剧-教你自己洗21seconds:-)