不知怎的,我的一个方法改变了它的领域,即使我复制了自己

时间:2015-06-27 03:23:24

标签: java

这是包含方法的类calculateTotalTipOnTable()calculateTotalTipOnTable方法使用来自Customer类的方法,并且当我测试时该方法没有问题我认为不知何故calculateTotalTipOnTable操纵deque(当我测试calculateTotalTipOnTable时,它缩小了大小TableDequeue)

package com.kristopher.restaurantmanager;

import sofia.graphics.RectangleShape;


public class TableDeque
    extends RectangleShape
    implements Deque<Customer>

{
    // ~ Instance/static variables ............................................
    private Node<Customer> head;
    private Node<Customer> tail;
    private int            size;
    private double         totalDue = 0;
    private double         totalTip = 0;
    private boolean        authorized;
    private TableDeque duplicate;


    /**
     * Constructor of the TableDeque class.
     */
    public TableDeque()
    {
        head = new Node<Customer>(null);
        tail = new Node<Customer>(null);
        head.join(tail);
        size = 0;
        this.setImage("table");

    }


    /**
     * Insert a new Customer at the rear (the tail) of the Tabledequeue.
     *
     * @param value
     *            the Customer to insert.
     */
    public void enqueueCustomerAtRear(Customer value)
    {
        Node<Customer> oldRear = tail.previous();
        tail.previous().split();
        oldRear.join((new Node<Customer>(value)).join(tail));
        size++;
    }


    // ----------------------------------------------------------
    /**
     * Remove the Customer at the front (the head) of the deque.
     *
     * @return The Customer that was removed
     */
    public Customer dequeueCustomerAtFront()
    {
        Node<Customer> oldFrontNext = head.next().next();
        Node<Customer> oldFront = head.next();
        head.next().split();
        head.split();
        head.join(oldFrontNext);
        size--;
        return oldFront.data();
    }


    // ----------------------------------------------------------
    /**
     * Insert a new Customer at the front (the head) of the deque.
     *
     * @param value
     *            the Customer to insert.
     */
    public void enqueueCustomerAtFront(Customer value)
    {
        Node<Customer> oldFront = head.next();
        head.split();
        head.join((new Node<Customer>(value)).join(oldFront));
        size++;
    }


    // ----------------------------------------------------------
    /**
     * Remove the Customer at the rear (the tail) of the deque.
     *
     * @return The Customer that was removed
     */
    public Customer dequeueCustomerAtRear()
    {
        Node<Customer> oldRearPrevious = tail.previous().previous();
        Node<Customer> oldRear = tail.previous();
        oldRearPrevious.split();
        oldRear.split();
        oldRearPrevious.join(tail);
        size--;
        return oldRear.data();

    }


    // ----------------------------------------------------------
    /**
     * Get the Customer at the front (the head) of the deque. Does not alter the
     * deque.
     *
     * @return the Customer at the front of the deque.
     */
    public Customer frontCustomer()
    {
        return head.next().data();
    }


    // ----------------------------------------------------------
    /**
     * Get the Customer at the rear (the tail) of the deque. Does not alter the
     * deque.
     *
     * @return the Customer at the rear of the deque.
     */
    public Customer rearCustomer()
    {
        return tail.previous().data();
    }


    // ----------------------------------------------------------
    /**
     * Get the number of items in this deque. Does not alter the deque.
     *
     * @return The number of items this deque contains.
     */
    public int size()
    {
        return size;
    }


    // ----------------------------------------------------------
    /**
     * Empty the deque.
     */
    public void clear()
    {
        while (frontCustomer() != null)
        {
            dequeueCustomerAtRear();
        }
    }


    // ----------------------------------------------------------
    /**
     * Returns a string representation of this deque. A deque's string
     * representation is written as a comma-separated list of its contents (in
     * front-to-rear order) surrounded by square brackets, like this:
     *
     * <pre>
     * [koo, david, karl, tom]
     * </pre>
     * <p>
     * An empty deque is simply <code>[]</code>.
     * </p>
     *
     * @return Customer lists on a signle table.
     */
    public String customerList()
    {
        String s = "[";
        int count = 0;
        Node<Customer> c = head.next();
        while (c != tail)
        {
            if (count < size() - 1)
            {
                s = s + c.data().getName() + ", ";
                c = c.next();
            }
            else
            {
                s = s + c.data().getName() + "]";
                c = c.next();
            }
            count++;
        }
        return s;
    }


    // -----------------------------------------------------
    // Table money process methods
    // -----------------------------------------------------

    // ----------------------------------------------------------
    /**
     * tableDue calculate the total due amount of the table. This method use
     * duplicated information of the table not to hurt any stored value beside
     * the double value totalDue
     *
     * @return total due on the table.
     */
    public double tableDue()
    {
        duplicate = this.duplicate();
        while (duplicate.size() != 0)
        {
            totalDue += duplicate.dequeueCustomerAtFront().getDueAmount();
        }
        duplicate = null;
        return totalDue;
    }


    // ----------------------------------------------------------
    // somehow this method change the table itself(not duplicated table.)
    // has to be fixed
    /**
     * calculateTotalTipOnTable method calculate the total tip amount that
     * customers gives you. This method must be called only when all of the
     * customer has done payingProcess
     *
     * @return total tip amount on table
     */
    public double calculateTotalTipOnTable()
    {
        duplicate = this.duplicate();
        while (duplicate.size() != 0)
        {
            totalTip += duplicate.frontCustomer().totalTipAmount();
            duplicate.dequeueCustomerAtFront();
        }
        duplicate = null;
        return totalTip;
    }


    // ----------------------------------------------------------
    /**
     * This method will determine if it is okey to remove table based on the
     * bollean value stored in this class, and customer class. This method count
     * the number of customers that is already authorized(means they paid). If
     * counts equal to the size of the deque, this table is authorized and ready
     * to dismiss.
     *
     * @return name of the customer who didn't fully pay yet.
     */
    public String payingProcess()
    {
        duplicate = this.duplicate();
        int count = 0;
        String str = "";
        if (duplicate.size() != 0)
        {
            while (duplicate.size() != 0)
            {
                if (duplicate.frontCustomer().isPaid())
                {
                    count++;
                    this.dequeueCustomerAtFront();
                    duplicate.dequeueCustomerAtFront();
                }
                else
                {
                    str += duplicate.frontCustomer().getName();
                    duplicate.dequeueCustomerAtFront();
                }
            }
            authorized = (count == this.size());
            duplicate = null;
            return str;
        }
        else
        {
            duplicate = null;
            authorized = true;
            return "table is empty";
        }
    }


    // ----------------------------------------------------------
    /**
     * return boolean if this table is ready to be dismissed
     *
     * @return boolean authorized
     */
    public boolean isPaid()
    {
        return authorized;
    }


    // ----------------------------------------------------------
    /**
     * this is the helper method to produce duplicate Table.
     * @return duplicated table.
     */
    public TableDeque duplicate()
    {
        TableDeque duplicate1 = new TableDeque();
        duplicate1 = this;
        return duplicate1;
    }

**payingProcess method of Customer Class.**
public double payingProcess(double d, double t)
    {
        actualTip = t;
        totalTip += t;
        double x = d - this.getDueAmount();
        if (d >= 0.0)
        {
            authorized = (x >= 0.0);
        }
        else
        {
            throw new IllegalStateException("negative value of payment");
        }

        if (authorized)
        {
            totalPayDue = 0;
            paidAmount = paidAmount + d;
            return x;
        }
        else
        {
            totalPayDue -= d;
            paidAmount = paidAmount + d;
            return Math.abs(x);
        }
    }    

TestCase文件 错误部分&gt;&gt; ////// assertEquals(table.calculateTotalTipOnTable(),15.0); //////////////// assertEquals(customer1.totalTipAmount(),15.0); ////

package com.kristopher.restaurantmanager;

import junit.framework.TestCase;

public class TableDequeTests
    extends TestCase
{
    private TableDeque table;
    private Customer   customer1;
    private Customer   customer2;
    private Customer   customer3;
    private Customer   customer4;
    private Food       food1;
    private Food       food2;
    private Food       food3;


    public void setUp()
    {
        table = new TableDeque();
        customer1 = new Customer("Kristopher");// customer who don't order
        customer2 = new Customer("Mike");// customer who order one food
        customer3 = new Customer("Yilong");// customer who order two foods
        customer4 = new Customer("Barnette");// customer who order three foods
        food1 = new Food("Kimchi", 10.00);
        food2 = new Food("Bulgogi", 20.00);
        food3 = new Food("GamzaTang", 30.00);
        // -------------------------------------------------------------------

        customer2.setOrderedFood(food1);// Mike

        customer3.setOrderedFood(food1);// Yilong
        customer3.setOrderedFood(food2);

        customer4.setOrderedFood(food1);// Barnette
        customer4.setOrderedFood(food2);
        customer4.setOrderedFood(food3);
    }


    // ----------------------------------------------------------
    /**
     * Test if tableDue method correctly caclulate the total due of the table.
     */
    public void testTableDue()
    {
        table.enqueueCustomerAtFront(customer3);
        assertEquals(table.tableDue(), 30.0, 0.0);
    }

    // ----------------------------------------------------------
    /**
     * This method must calculate the total tip on the table.
     */
    public void testCalculateTotalTipOnTable()
    {
        table.enqueueCustomerAtFront(customer1);
        table.enqueueCustomerAtFront(customer2);
        customer1.payingProcess(0.0, 15.0);
        customer2.payingProcess(0.0, 35.0);
        assertEquals(50.0, table.calculateTotalTipOnTable());
    }

    // ----------------------------------------------------------
    /**
     * Testing if enqueueCustomerAtRear correctly enque at rear of the table
     * deque.
     */
    public void testTableForSingleCustomer()
    {
        table.enqueueCustomerAtFront(customer1);
        assertEquals(table.size(), 1);
        assertEquals(table.frontCustomer().getName(), "Kristopher");

        Exception thrown = null;
        try
        {
            table.rearCustomer().getOrderFood();
        }
        catch (Exception e)
        {
            thrown = e;
        }
        assertTrue(thrown instanceof IllegalStateException);
        assertEquals(
            thrown.getMessage(),
            "This customer did not order any foods yet");

        assertEquals(table.customerList(), "[Kristopher]");
        assertEquals(table.tableDue(), 0.0, 0.0);
        customer1.payingProcess(0.0, 15.0);
        //////assertEquals(table.calculateTotalTipOnTable(), 15.0);////////////
       //// assertEquals(customer1.totalTipAmount(), 15.0);////
        assertEquals(table.payingProcess(), "table is empty");
        assertTrue(table.isPaid());
    }
}

1 个答案:

答案 0 :(得分:2)

您不是在这里创建副本:

public TableDeque duplicate()
{
    TableDeque duplicate1 = new TableDeque();
    duplicate1 = this;
    return duplicate1;
}

您将返回对原始实例的引用。

您可以使用复制构造函数来代替duplicate方法:

public TableDeque (TableDeque copy)
{
    // copy properties from the source TableDeque to the new instance
}

然后,而不是调用

duplicate = this.duplicate();

你打电话

duplicate = new TableDeque(this);