John Squibb

Washing Machine

The washing machine is based on a very simple Kenmore appliance in the laundry room of my house. It only has two cycles, Permanent Press and Heavy Duty.

There are a couple of interfaces for the knobs. Usually I tend to name interfaces as adjectives, such as chargeable, or deletable, but for the appliances project, I am naming them as if they were true interface objects, such as a Cycle Knob or a Temperature Knob. They represent the real world interfaces on my washer, and not just a suggestion to code by contract!.

Namespaces and constants are used throughout. You'll also require the base classes found in Interval and Debug.

Specification Photos

The Code

<?php
namespace Washing_Machine;

// Defines requirements for a knob that selects cycle settings
interface Cycle_Knob
{
    public function 
start();
    public function 
stop();
    public function 
select_cycle($cycle$length);
}

// Defines requirements for a knob that selects temperature settings
interface Temperature_Knob
{
    public function 
set_temperature($temperature);
}

// Defines requirements for a knob that sets load size settings
interface Load_Size_Knob
{
    public function 
set_load_size($load_size);
}

/**
 * The washing machine unit.
 */
class Unit
implements 
    
Temperature_Knob,
    
Load_Size_Knob,
    
Cycle_Knob
{
    
/**
     * Water Temperatures
     */
    
const TEMPERATURE_COLD 0;
    const 
TEMPERATURE_WARM 1;
    const 
TEMPERATURE_HOT 2;
    
    
/**
     * Load Sizes
     */
    
const LOAD_SIZE_SMALL 0;
    const 
LOAD_SIZE_MEDIUM 1;
    const 
LOAD_SIZE_LARGE 2;
    
    
/**
     * Cycles
     */
    
const CYCLE_HEAVY_DUTY 0;
    const 
CYCLE_PERMANENT_PRESS 1;
    
    
/**
     * Lengths for each cycle. These are not the actual lengths
     * @see $this->cycle_times below for minutes in each lenght/cycle.
     */
    
const LENGTH_SHORT 0;
    const 
LENGTH_REGULAR 1;
    const 
LENGTH_SUPER 2;
    
    
/**
     * Length of Pause in minutes
     */
    
const MINUTES_PAUSE 2;
    
    
/**
     * Length of Spin in minutes
     */
    
const MINUTES_SPIN 3;
    
    
/**
     * Length of Rinse in minutes
     */
    
const MINUTES_RINSE 3;
    
    
/**
     * Cycle times.
     * Set in $this->initialize_cycles() on construct.
     */
    
private $cycle_times = array();
    
    
/**
     * Water temperature
     */
    
private $temperature;
    
    
/**
     * Load size
     */
    
private $load_size;
    
    
/**
     * Cycle
     */
    
private $cycle;
    
    
/**
     * Length
     */
    
private $length;
    
    
/**
     * Constructor
     */
    
public function __construct()
    {
        
// Initialize cycles
        
$this->initialize_cycles();
        
        
// Set default temperature
        
$this->set_temperature(self::TEMPERATURE_COLD);
    }
    
    
/**
     * Sets minutes in each cycle
     * Based on constants set for Cycles and Lengths.
     * All times are in minutes.
     */
    
private function initialize_cycles()
    {
        
$this->cycle_times = array 
        (
            
self::CYCLE_HEAVY_DUTY => array 
            (
                
self::LENGTH_SHORT => 4,
                
self::LENGTH_REGULAR => 8,
                
self::LENGTH_SUPER => 10
            
),
            
self::CYCLE_PERMANENT_PRESS => array 
            (
                
self::LENGTH_SHORT => 4,
                
self::LENGTH_REGULAR => 10,
                
self::LENGTH_SUPER => 14
            
)
        );
    }
    
    
/**
     * Cleans up processes
     */
    
private function shutdown()
    {
        
$this->cycle NULL;
    }
        
    
/**
     * Sets water temperature.
     * 
     * @param integer $temperature
     */
    
public function set_temperature($temperature)
    {
        
$this->temperature $temperature;
    }
    
    
/**
     * Sets load size for water level purposes
     * 
     * @param integer $load_size
     */
    
public function set_load_size($load_size)
    {
        
$this->load_size $load_size;
    }
    
    
/**
     * Starts the unit.
     */
    
public function start()
    {
        
\Debug\Trace::out
        
(
            
"starting machine with cycle of: {$this->cycle}"
        
);
        
$this->run_cycle($this->cycle);
        
$this->stop();
    }
    
    
/**
     * Stops the unit
     */
    
public function stop()
    {
        
\Debug\Trace::out('stopping machine');
    }
    
    
/**
     * Selects the cycle
     * 
     * @param integer $cycle
     * @param integer $length
     */
    
public function select_cycle($cycle$length)
    {
        
$this->cycle $cycle;
        
$this->length $length;
    }
    
    
/**
     * Runs internally set cycle 
     */
    
protected function run_cycle()
    {
        switch (
$this->cycle)
        {
            case 
self::CYCLE_HEAVY_DUTY:
            
                
$this->fill();
                
$this->wash();
                
$this->rinse();
                
$this->spin();
            
            break;
            
            case 
self::CYCLE_PERMANENT_PRESS:
            
                
$this->fill();
                
$this->wash();
                
$this->pause();
                
$this->rinse();
                
$this->spin();
            
            break;
        }
    }
    
    
/**
     * Fills machine with water.
     */
    
protected function fill()
    {
        switch (
$this->load_size)
        {
            case 
self::LOAD_SIZE_SMALL:
            
                
\Debug\Trace::out('Filling unit with water for SMALL load');
            
            break;
            
            case 
self::LOAD_SIZE_MEDIUM:
            
                
\Debug\Trace::out('Filling unit with water for MEDIUM load');
                
            break;
            
            case 
self::LOAD_SIZE_LARGE:
            
                
\Debug\Trace::out('Filling unit with water for LARGE load');
            
            break;
        }
    }
    
    
/**
     * Run wash cycle
     */    
    
protected function wash()
    {        
        
$interval \Time\Interval::get
        
(
            
\Time\Interval::MINUTES_TO_SECONDS,
            
$this->cycle_times[$this->cycle][$this->length]
        );
        
        do
        {
            
\Debug\Trace::out("washing. {$interval} seconds to go");
            
\Time\Interval::tick();
        }
        while (
$interval--);
    }
    
    
/**
     * Run spin cycle
     */
    
protected function spin()
    {
        
$interval \Time\Interval::get
        
(
            
\Time\Interval::MINUTES_TO_SECONDS,
            
self::MINUTES_SPIN
        
);
        
        do 
        {
            
\Debug\Trace::out("spinning. {$interval} seconds to go");
            
\Time\Interval::tick();
        }
        while (
$interval--);
    }
    
    
/**
     * Run rinse cycle
     */
    
protected function rinse()
    {
        
$interval \Time\Interval::get
        
(
            
\Time\Interval::MINUTES_TO_SECONDS,
            
self::MINUTES_RINSE
        
);
        
        do 
        {
            
\Debug\Trace::out("rinsing. {$interval} seconds to go");
            
\Time\Interval::tick();
        }
        while (
$interval--);
    }
    
    
/**
     * Pause/Cool Down Cycle
     */
    
protected function pause()
    {
        
$interval \Time\Interval::get
        
(
            
\Time\Interval::MINUTES_TO_SECONDS,
            
self::MINUTES_PAUSE
        
);
        
        do 
        {
            
\Debug\Trace::out
            
(
                
"pause/cool down. {$interval} seconds to go"
            
);
            
\Time\Interval::tick();
        }
        while (
$interval--);
    }
        
}

Toggle plain-text

Unit Test

<?php
/**
 * Testing the washing machine appliance
 */
require_once '../base/time.php';
require_once 
'../base/debug.php';
require_once 
'washing_machine.php';

$wm = new \Washing_Machine\Unit;
$wm->select_cycle($wm::CYCLE_PERMANENT_PRESS$wm::LENGTH_SHORT);
$wm->start();

Toggle plain-text

More

Back to Appliance List

Tags: Bash,image,resize,imagemagick,php 5.3,google linux search,class constants, magic numbers
Short URL: http://sqb.in/F2t2