It is important for programmers just starting out to understand the differences between model, view and control code. It applies in spades to the common ancestor program.
The pure model code for finding common ancestors is trivial:
Set commonAncestors (Person a, Person b)
{
initialize set A with person a;
initialize set B with person b;
while (intersection(A, B) is empty) {
A = union(A, parents(A));
B = union(B, parents(B));
}
return intersection(A, B);
}
Yes, the model code for this problem is this simple. This is called model code because it is based solely on data structures and quasi-mathematical operations on those data structures. The programming language I provide in the LifeLines system can be programmed to implement this program nearly exactly as shown here. If anyone would like to see complete LifeLines code to solve the common ancestor problem let me know.
The view code is code in GUI applications that displays windows and views on the screen. Control code is responsible for using the data in the model to build the windows and views.
The code to drive the API to FamilySearch is an example of control code. It should never be mixed with model or view code. In this very simple problem, that API code should only exist in one place. Let's find that place. Say the implementation of "parents (Set set)" is the following:
Set parents (Set A)
{
Set parentsSet = new Set;
for (Person p in A) {
parentsSet = union(parentsSet, parents(p));
}
return parentsSet;
}
This is model code also -- pure data structures and quasi-mathematical (actually wholly mathematical in this case) operations.
But we have now reached the level where we need control code, in order to implement the "parents(Person p)" function. (There are two functions called "parents" here, one that takes a Set as a parameter, which is model code, the other that takes a Person as parameter, which is control code -- sorry for the minor confusion):
Set parents (Person p)
{
create FamilySearch API request to return the parents of Person p;
send the request;
create a set of 0, 1, or 2 persons based on the results of the request;
return the set;
}
With this approach all API-control code is relegated to small, trivial modules that perform single, self-contained operations, as required either by model or view code.
If you learn early to structure your code along these three functional lines you will be able to mix and match software for many situations. Note, for example, that the pure model code above could care less about how parents are actually found. By simply replacing the single, control-level function "parents (Person p)" you can make this program work with, for example, local flat files or databases on your local machine, other on-line services that use other APIs, and so on. Alternatively, by changing only the view code (leaving the model code and control code intact), you could convert this program into a command line program, or a GUI application that uses an entirely different graphical user interface.