W. Gardner, R. Sutcliffe, and D. ArielDepartment of Computing Science
Trinity Western University, Langley, BC
{wgardner, rsutc, dariel}@twu.ca
In expanding on the base of our established Applied Mathematics with Computing degree program to create a distinct degree in Computing Science, we wanted to build on strength--to expand, complete, and professionalize our course offerings. However, for pedagogical reasons, we wished to continue teaching beginners using procedural paradigms. We already had a Java course, but not one in C++ (another perceived necessity). We wanted a framework to accommodate both without duplication, and to be versatile enough to use other OO notations instead of or in addition to these two. Our solution was to refactor the material into separate components--the common theory and the notational-specific practice. This paper reports on our motivations, experiences, and conclusions.
Keywords: object-oriented programming, team teaching, C++, Java, pedagogy
Computing science at Trinity Western University, a Christian liberal arts institution near Vancouver, Canada, has a history in the Department of Mathematical Sciences going back to 1983, originally in a combined degree with applied mathematics. In 1997, we commenced offering a specialized B.Sc. in Computing Science, and expect on the basis of current enrolments to be graduating 20-30 students a year in the future.
In the earlier curriculum we emphasized procedural programming, with object-oriented programming (OOP) being taught in third-year courses entitled "Advanced Programming," and "Programming Languages." However, since the ability to use C++ and Java is routinely expected of graduates now, and since we desired to reorient our software engineering courses around OO methodologies, we wanted to move OOP to an earlier, more prominent place in the curriculum.
This paper relates our experience with a new group of team-taught first-year courses in OOP. It begins with a brief rationale for our keeping OOP in the "second language"category, in contrast to the practice at many schools. We then describe the details of what we call our "refactored" curriculum, plus the results of a student survey, and consequent plans for improvement. We hope that our experiences may assist others who are searching, as we are, for optimal ways of teaching OOP.
We believe the purpose of the university computer science curriculum is the preparation of well-rounded, integrated, goal-oriented, competent, professionals ("software engineers"). To this end, students need to be taught with sound pedagogy to use proven and applicable problem-solving tools, and in such a manner as to be themselves versatile and adaptable professionals in a rapidly changing environment.
Students entering a first year university program have a wide variety of backgrounds. It is our (subjective) perception that this is a broader span than, say, a decade ago. More students arrive self-taught, or, having had some informal coursework, usually in a subset of C++. At the same time, more arrive with minimal exposure to problem solving with computers, as few British Columbia high schools teach programming.
Few freshmen (and not many transfer students) have any concept of problem solving, of planning a program, of programming paradigms, of writing for readability and re-use, or of documentation skills. At best, they arrive as "hackers", knowing a few tricks of one particular programming notation, but with no idea that computing science consists of anything beyond throwing together a few lines of non-reusable code to meet short-term objectives. Thus, for all practical purposes, nearly all must start from square one with the most basic concepts--in many cases unlearning numerous bad habits.
It is therefore necessary to begin with the teaching of a discipline of good problem solving habits, and to do so in an environment where the tools assist the process, rather than hinder it. That is, introductory computing courses must be about using a computing system efficiently and effectively as a problem-solving tool; not about the details of a particular programming notation.
Most professionals will be handed programming tools and languages they have never seen before and expected to master these in short order without breaking stride in software production. Thus, we believe, they need to be familiar with a variety of languages and operating systems by the time they graduate. This suggests that beginning with the most teachable notation for the introductory course, and shifting to others (as course material dictates in later years) is a sound strategy.
The perennial problem of choosing the most appropriate beginning programming notation has long sparked periodic outbursts of the "language wars" in computing science departments around the world. There are many ways to evaluate notations for this purpose, but most would include points on what we call the ASTIM scale:
To what extent is the notation used in the "real" world? | |
Is it complex enough to solve real-world problems? |
Is the notation the subject of a complete ISO standard? | |
Can source code in the base notation be used cross-platform with a re-compile? |
How easy is the notation to teach to beginners? | |
Is it simple enough to master in a semester? | |
Do notation rules and typical implementations provide assistance to the beginner, or do they hinder the learning process? |
Are good textbooks available? | |
Are standard-compliant implementations available cross-platform? |
Are modern abstraction features available? |
No one notation meets all the requirements, and for this reason computing science departments show little inclination to standardize on any particular one for beginning instruction.
We believe the first course should deal with standard programming abstractions: sequence, selection, repetition, and composition, (confining the latter to functions, procedures, and libraries, rather than introducing class types.) Despite the notation's other drawbacks, this means Modula-2 [1] is our first choice. Ada would be the probable runner-up.
Afterwards, it makes sense to have a second course in programming in a suitable language for focusing on the object-oriented paradigm. Since the introduction of notations and their features is a relatively low level task, we decided to position the OOP courses in the second semester of the first year.
Our first attempt to move OOP from the upper-level course context was to offer second-year CMPT 241 (Java) for two semester hours of credit. While this is sufficient credit for a second-language course, we found two hours a week too little time to cover the material from a high-level (theoretical) view. So often, when operating in a rushed mode, one teaches just language syntax, not programming principles and practice. We were therefore unsatisfied with the 2-credit approach.
At the same time, we also had demand for a course in C++. Yet there was clearly significant overlap in the two languages, and it seemed a pity to go over the same ground twice by mounting separate courses in the typical watertight compartments. Since we had no great stake in the status quo regarding OOP, it was tempting to try a fresh approach.
This train of thought to the idea of refactoring: extracting the common elements of the languages into a "pure" OO seminar (naturally dubbed the "base class", while teaching the language-specific features in separate sessions. We achieved this by demoting the existing Java course to first year status, paralleling it with a new C++ course, and extracting the common factors in a separate theory course.
Students learning Java would take CMPT 167, "Introduction to Java," and CMPT 160, "OO Seminar." Those learning C++ would take CMPT 165, "Introduction to C++," and the same CMPT 160. Since these were scheduled on different days, students could, in principle, enrol in all three courses and study both languages concurrently.
This approach appeared to present a number of advantages:
We hoped to avoid repetitive teaching (and the students studying) of foundational OO concepts. The Java and C++ instructors could assume the necessary foundation had been laid by the seminar class, and restrict themselves to teaching the language-specific application of the basic OO principles. Students also would benefit from the efficiency, for they would not have to go over old ground if they decided to take a second OO course.
We hoped that by learning the foundational OO concepts in a separate class--the OO seminar--students would better grasp that these are indeed generic principles and not think of them as just the peculiar features of a particular language. This fits our overall philosophy of teaching for the retention of high-level, adaptable programming patterns for professional practice rather than for the memorization of a multiplicity of specific, detailed, low-level minutiae from particular notations.
We desired to provide a "substrate," as it were, into which additional OOP courses (e.g., Smalltalk) could be plugged in the future, should this prove desirable. We felt this would:
1) Does it help or hinder students to study more than one OOP language literally at the same time, i.e., not even in rapid succession? Ideally, the multiple exposures reinforce the common concepts, while the contrasts reinforce the language distinctions. At worst, we feared mass confusion could result.
2) Is it feasible to closely synchronize multiple courses running concurrently, or is it more trouble than it's worth for the instructors to organize themselves like this? This was intensive team-teaching. If our schedule proved impractical, or if we drifted away from it, the neat principle-and-application sequencing of phase two would break down.
1. Third and fourth year students reacted more positively to the unique features of the experiment than did first and second year students, especially with respect to their overall experience. (3.5 vs 3.1). This might suggest that, though the course was intended to be at the first year level, it resonated at a higher level. On the other hand, it might simply reflect that the upper level students had better preparation and were already determined on a career in computing.
2. The few who had taken Java before as a stand-alone language course without the theory seminar in support much preferred things done the new way.
3. Results were sharply bimodal on these questions:
On the latter point there was criticism of the CMPT 160 instructor for placing questions on the exam such as "Show how to declare and instantiate objects in two languages we have studied." Some felt that they ought to be required to know only the theory that applied to the specific language they wanted to study, which would of course partially defeat the purpose of separating theory from language.
4. Despite the bimodal distribution, overall results were quite positive on #1 the separation of theory and notation (3.41) with the Java students (3.73) much more positive that the C++ students (3.35).
5. Very positive results (3.41) were also found from question #3, which asked if the attempt to abstract the big picture of OO concepts from notational details was helpful. Again, the Java students were significantly more positive than the C++ students. Overall, this response would appear to suggest that the basic plan of instruction succeeded with the students.
6. Almost no one thought those taking a second course from the package should have to re-write the 160 (theory) part of the exam. We weren't planning to require this anyway, and expected most students to agree.
7. Most thought that the two-hour classes were too heavy, and preferred two one-hour blocks for the individual languages (question #5), and by the time we took the survey the instructors had come to the same conclusion themselves.
8. Results were quite indecisive on #4 (Were illustrations from a variety of languages helpful?) and #8 (overall experience) but for different reasons. On #4, responses were evenly distributed, except that upper level students were more positive. On #8, responses clustered heavily in the middle, suggesting students did not feel their individual experience was significantly better or worse, even though they had agreed strongly that overall strategy was sound and helpful. We take this to mean that some fine tuning to improve the overall experience is indicated.
9. Despite this, most who answered #10 (would you take the other language in the package) said they would if they got the chance.
10. Students in the Java course were more positive about the two course, 2 instructor aspect (questions #1-4) but found the total experience less satisfactory (#8). This result is somewhat contradictory, but there were only eleven respondents for Java, and so it may not be significant.
11. The four students who responded as taking both languages may not comprise a significant sample, but were uniformly positive about their experience.
1. The topic outline needs to be revised to reflect the fact that some theory portions took longer than a lesson, and others less. Alternately, we could use a sixty-five minute time block instead of a fifty minute block for the theory portion. Either is a minor change.
2. Phase I of the schedule needs to be slightly lengthened to avoid pressuring C++.
3. The bundling of exams needs to be revisited, since it seemed to cause some confusion.
4. With the third- and fourth-year students eliminated from the next round, we need to take more care to target the less-experienced audience in terms of the depth and pacing.
5. We found no significant positive or negative indications on the question of whether students had a problem taking both languages at once.
What follows is an abbreviated form of the survey instrument:
CMPT 16x OO Courses Survey Spring 2000
Help us evaluate the effectiveness of our OO teaching strategy. Anonymity assured.
ESL student?Year # (1-5) (Students were also asked a variety of questions about their TWU course background.)
Please note: Later, you will have a chance to evaluate the individual 16x courses in the normal TWU evaluation process. That is not the purpose of this survey. Here, we are looking for feedback on the 160 + 165/7 packaging concept.
Which OO course(s) are you taking this semester? circle: 160 OO Concepts 165 C++ 167 Java
The 16x experiment: We factored out the language-neutral OO theory into the 1-sem. hr. 160 "base class," and taught the language-specific practical elements in 165 and 167 @ 2 sem. hours each. We hoped that by teaching OOP (object-oriented programming) in this way, we could highlight the underlying theoretical concepts (so you'd be able to identify them more easily when you learn another OO language later), and reduce the redundancy (avoid going over the same ground) in the language-specific courses. Also, if you take the other language course later, you won't have to take 160 again (saving both time and tuition money).
Opinion questions: Write a number 1..5 according to the scale given. Generally, 1 is strongly negative, 5 is strongly positive. Leave blank if not applicable. Explanations or comments are more than welcome!
1. How did you feel about learning the OO concepts in a separate class from Java/C++?
[1=better to learn it all in one class .. 3=doesn't matter .. 5=separate classes helpful]
2. How did you feel about learning the OO concepts from a different instructor than Java/C++?
[1=better with just one instructor .. 3= doesn't matter.. 5=two instructors was great]
3. 160 tried to abstract the OO concepts and give the "big picture," which you would ordinarily not get in a language-specific course. Was this helpful?
[1=NO, I was confused by the "big picture" .. 3=no opinion .. 5=YES, excellent!]
4. 160 introduced examples from a number of OO languages, in order to illustrate differing terminology and syntax. Was this helpful?
[1=NO, I didn't want to learn about other languages .. 3=didn't matter .. 5=YES, excellent!]
5. How did you feel about the 2-hour blocks for 165/167?
[1=use 2 1-hr classes .. 3=don't care .. 5=2-hr class was great]
6. How did you feel about combining 160 and Java/C++ on one midterm exam?
[1=give 2 separate exams .. 3=don't care .. 5=having only one exam was great!]
7. If someone takes the other 16x language course in the future (they won't repeat 160), should they write the 160 part of the midterm and final exams again?
[1=NO, it's not fair .. 3=doesn't matter .. 5=YES, they should still know that material]
8. Rate your overall learning experience with the 16x courses.
[1=well below average .. 3=average .. 5=as good as it gets!]
9. If you would be interested in having us offer another CMPT 16x OOP course (not Java or C++), please write the language name(s) here:_____________ ________________ _____________
Individual situations: Please read the conditions carefully before answering the next questions.
If you have not yet taken both C++ and Java, answer this question #10:
10. Would you like to take the other 16x course in the future (you won't repeat 160)? (check one)
[1] YES, probably.
[2] Wait and see.
[3] NO, I'll study it on my own because I can pick it up without another formal course.
[4] NO, I'll study it on my own because I don't like the 160 + 16x approach.
[5] NO, not interested in the other language.
[6] NO, some other reason. Explain:
If you are presently taking both 165 & 167, answer questions #11-13:
1. What do you think about studying Java and C++ at the same time?
[1=quite confusing .. 3=neither good/bad .. 5=quite helpful] Comments:
2. Did you appreciate having the redundancy removed (into 160), or would it been better to leave it in and have two 3-credit courses with considerable conceptual overlap?
[1=leave in the overlap .. 3=either way OK .. 5=good to remove the redundancy] Comments:
3. Based on your experience, do you prefer studying two OO languages together, or in different semesters?
[1=better apart .. 3=either way OK .. 5=better together] Comments:
If you took 241 Java before, answer question #14:
14. Compare the 160 + 16x combination to taking a single language-specific OOP course.
[1=single course better .. 3=about the same .. 5=combination better] Comments: