Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due
Informatics 122: Software Design II
Project #4: Right in the Middle (Implementation)Implementing and adjusting your design
Now that you've completed a preliminary design from Project #3 and received feedback on it, it's time to complete an implementation of the program. Unlike your previous implementation, where you were required to maintain someone else's design as-is, this time you'll be implementing your own design, and you are permitted to make any adjustments you'd like to your design, though you will be required to justify them in a separate document. I expect that most of you will need to make at least a few changes, especially as the realities of writing unit tests show you where your design isn't sufficiently decoupled.
As before, you'll be required to use Git or EGit while you work, and will be including your entire Git repository to us as part of your submittal for this project.
Unit tests and test coverage
One major requirement in your implementation phase is that you must write unit tests using JUnit. (Note that there are other unit test frameworks available for Java, but we will standardize on JUnit for this course, since it is built into Eclipse.) You will not be permitted to put the unit tests off until the end of your implementation phase, for the simple reason that your design can be profoundly affected by the need to write these tests; it would be disastrous to discover, at the end of your implementation, that you have a complete program with an untestable design. So, as part of your development, you will be required to add unit tests whenever you feel you've completed any part of the public functionality of a class. While we won't be checking this with a fine-tooth comb, we will be looking at your Git repositories to verify that you made an honest attempt at writing your unit tests as you went along.
Furthermore, you will be required to achieve 100% code coverage in your unit tests, except for the layer of functionality that actually communicates with external resource (i.e., it must be possible to run all of your unit tests without an Internet connection, without a particular file being present on the file system, etc.). Isolate this part of your functionality as well as possible, and keep an open mind about just how little functionality that can actually be.
The need to get your code coverage metric up will no doubt affect your design in profound ways, requiring you to decouple your classes more than you might otherwise need to do, and to use techniques like dependency injection to avoid hard-coding dependencies into your classes. (For example, a class where you want to write output to the console will instead need to write to a more general PrintWriter, so that the program can write to System.out while the unit tests write to a StringWriter.)
Installing and using the EclEmma plug-in
There is an easy-to-use code coverage plug-in for Eclipse called EclEmma, which we saw in a lecture example. We will be using this tool when we grade your work, as a means of assessing code coverage, and we recommend that you use it as you work on your implementation and unit tests.
It's important to realize what it is you'd like to measure. Your goal is to achieve as close to 100% code coverage as possible, not counting the actual unit test code itself; in other words, you want to know how much of your actual code is exercised by running your unit tests. One very useful way to measure this is to make sure your unit tests are in separate packages from the code under test; so, for example, if you were testing code in a package inf122.example, you might write the unit tests in a package inf122.example.test.
Measuring code coverage is as simple as running all of your unit tests under a "coverage mode" in Eclipse with EclEmma; the result will be a coverage report, as well as highlights throughout your code demonstrating what has been covered and what hasn't.
Installation instructions for the EclEmma Java Code Coverage plug-in for Eclipse are available on the EclEmma web site at this link. A thorough set of usage instructions are available in the User Guide on the EclEmma web site at this link. It is best to get this plug-in set up and running before you proceed with your implementation; it took me only a few minutes to install the plug-in, write a quick dummy example (a short class and a few JUnit tests) and run my first code coverage report.
Basic design and implementation goals
In the Project #3 write-up, some basic design goals were listed, which gave you an idea of the things you should have been thinking about as you worked through your design. The list below is a similar, but slightly broader list, of things you'll want to be thinking about now that you're working on your implementation, part of which is assessing the quality of your own design and making modifications to it.
- Does each class have a single responsibility? Think, for each class, about whether its objective could be accurately described in a single sentence of reasonable length; if not, what could you do to make that possible?
- Do your classes exhibit high cohesion? Is strongly-related functionality grouped together? Is less-related or unrelated functionality separated?
- Do your classes exhibit low coupling? How significantly could you make changes to individual classes without breaking many others?
- Have you used design patterns where they are appropriate? Most of the design patterns we've discussed have, at their core, the goal of decoupling classes from one another; when you used design patterns, did you find that it increased the level of decoupling?
- Did your design make it reasonably straightforward to write unit tests? A design that meets the kinds of goals we've discussed in lecture will have, as a useful side effect, the property of making unit testing easier; or, thought differently, the desire to write unit tests will have a tendency to drive you toward a design that meets these goals.
- How close were you able to come to achieving 100% code coverage with your unit tests? Besides functionality that required outside resources (e.g., the bit.ly web service, files, etc.), what other functionality was left uncovered? What could you to reduce the amount of code that is dependent on those resources and, hence, leave you able to increase code coverage?
Deliverables
You'll need to submit three deliverables for this project.
-
A zip file containing only a Git repository (i.e., a .git directory). In that repository should be (at least) a master branch that points to a commit that you consider complete (i.e., the code that you want us to grade), along with your entire commit history from the time you started your implementation.
- If you used Eclipse and EGit, the Git repository would ideally include your Eclipse project (e.g., the .project and .classpath files in the project directory), but not your entire workspace. If you follow the steps in the section titled Getting Started with EGit in the Project #2 write-up, your repository will contain just the right stuff.
- A zip file containing all of the Java source code that comprises your implemented design, arranged into a directory structure that mirrors the package hierarchy. Please include only the .java files here. We'll use this for our own reference, in case we have issues with your Git repository.
- A document detailing the changes that you made to the design in order to implement it, along with a justification of why those changes were necessary in order to meet the requirements, improve the design, or to be able to write unit tests. This document can be in either Microsoft Word (.doc or .docx) or PDF (.pdf) format.
Follow this link for a discussion of how to submit files via Checkmate. Be aware that we'll be holding you to all of the rules specified in that document, including the one that says that you're responsible for submitting the version of your files that you want graded.