Fall 2012 Midterm CC-BY-NC

Maintainer: admin

Disclaimer: These are student-generated solutions and may therefore be error-prone

1Question 1

a) Question 1

Additional comments: notifyObservers is called each time a number is generated in generateNumber() and notifies each Observer attached to the Observable by invoking notify() on it. In Viewer, when notify() is called, a number is displayed via displayNumber(). Likewise, notify() in Auditor calls checkSequence(). The views (Viewer and Auditor) obtain the information they need from Generator via getNumList().

b) Not sure what "data-flow model" refers to. At first, I thought the question was asking which data structure to use to store the generated numbers and thus argued in favour of an ArrayList because we can use relevant Collections methods such as shuffle(). That was wrong.

I'm waiting for someone to submit the correct answer but I'll venture the following guess:

The data-flow model to use is the Model-View-Controller model where:

  • the model is Generator and holds information about the sequence of generated number in an ArrayList data structure
  • the views include Viewer since it displays the data in a format that is specific to it
  • the controller??

c)

addObserver(new Viewer());

d)

getNumList() returns a cloned ArrayList to ensure that the clien does not change the data held in Generator. The client would then use the ArrayList.iterator() to access previously generated numbers or access a number specifically using ArrayList.get().

e)

Can't draw this but see additional comments in a)

2Question 2

a) will draw this if I have time

b)

    public String[] list() 
    {
        ArrayList<String> lList = new ArrayList<String>();
        if (isFile())
        {
            lList.add(name());
        }
        else
        {
            for(Data d: getChildren())
                lList.addAll(d.list());
        }
        return lList.toArray();
    }

c)

The strategy design pattern supports this requirement since the Data interface (File or Directory) can benefit from different variants of a comparison algorithm and the client of Data wants to supply a custom version of this algorithm. This can be achieved by using the Comparable interface type and implementing compare in the concrete Comparators (e.g. ComparatorByName and ComparatorByContent):

    public interface Comparator()
    {
        int compare(Data data1, Data data2);
    }

3Question 3

a)

    assert pArray != null;
    assert pIndex >= 0;
    assert pIndex + 3 <= pArray.length;

b) No, by Liskov's substitution principle, since overriding the method will restrict preconditions of the superclass.

c)

    public class TestSave extends TestCase
    {
        public void testSave()
        {
            String[] testString = {"A", "B", null, "C", "D"};
            try
            {
                concat3(testString,1);
                fail();
            }
            catch(NullStringException e)
            {}
        }
    }

d) Exception is too generic e.g. will have same behaviour for both NullStringException and other unrelated exceptions. (I got 1/2 for giving this answer)

Discussion:
eleyine: I got full points for the above answer, guess I had a more lenient TA.

4Question 4

(a) The name of the method becomes less clear because the function is being described by the parameters (I got 1/2 for this)

Discussion
eleyine: I really would like a full-mark answer for this. I wrote that unexpected return types would break the client's code but didn't get any points for it e.g. int add(int, int) vs double add(double, double)

(b) The purpose of the Iterator design pattern is to retrieve elements in the natural order described by the aggregate object such that each element is visited once. The internal data structure is abstracted from the client. Useful to perform operations on all objects in an aggregate or to filter for a particular condition.

(c) No, if the fields are references (e.g. ArrayList) then the client cannot reassign a value to the reference field however, he can chage its contents e.g. finalList.set(0, E)

(d) commit adds the changes on the local repository copy to the master central repository as long as there are no conflicts (conflicts can be avoided by updating to newest version then committing).

(e) super.aMethodName runs the superclass' aMethodName (and not the potentially overriden one in this subclass).

(f) Extensibility and loose coupling.