SLogo API Design Exercise
An Application Programming Interface, API, is simply all the public classes and their public methods in your program. However, thinking about the public methods together as an interface to your program has the power to change how you perceive those methods from just something necessary to make the program functional to providing a service to other programmers (even those on your own team!). An API, then, essentially becomes a contract and developers, now clients, are enticed to use the API because they know they can rely on that contract (even if the underlying implementation changes). Thus, many see API design as the most critical part of designing a program, because it affects the design of other components dependent on them.
Although the concept is inherently subjective, most developers seem to agree on the main desirable characteristics of an API:
- Easy to learn
- Provides for extension
- Leads to readable code
- Hard to misuse
This exercise asks you to start the process of changing your thinking from simply programming to API design.
Lab Workflow
In your SLogo teams, complete the following activities today:
- Introduce yourselves by sharing:
- where you are and how you are experiencing school this semester
- your motivation/interest in this course
- your knowledge/interest in other programming languages (especially Logo, Alice, Scratch, or something similar)
- areas of the project you interested/concerned about
- Read the Team Contract and share your previous team experiences to try to derive some positive/negative practices you think affect team work
- Clone the shared team repository to each person's machine and Open the project in IntelliJ
- Examine Java's Collections API from a design perspective instead of as a user to see how it is documented and motivated
- Review someone's Cell Society project to understand its existing APIs and to help you create more deliberate ones
- Review each person's answers to the planning questions and discuss high level goals and design ideas for SLogo
- Create a "one page" description of the design goals for each of the four APIs
- Use CRC cards to refine your design, focusing more on the interactions between classes than their implementation
- Use Use Cases to verify the completeness and flexibility of your design, by writing "example code", a sequence of method calls from those on your CRC cards
- Summarize the group's design SLOGO_APIs.md using Gitlab's Markdown format
- Choose a time for the next team meeting
- If you have additional time, discuss and begin working on your team's Plan
For shared WYSIWYG Markdown editing, you can use
Submission
At the end of lab, push your markdown files to the doc folder of your team's provided, shared, slogo_teamNN repository to submit your notes about your teams' discussions.
Make sure the text of your final commit message is of the form "lab_slogo_design - NetIDs".
Understanding an API
Study and discuss the Java's Collections API vision. Feel free to search for other resources about Java Collections beyond the standard Java documentation and tutorial. If there is something you like or dislike or something your learned about design during the discussion, make sure to back it up with a specific example.
Some things for you to consider:
- In your experience using these collections, are they hard or easy to use?
- In your experience using these collections, do you feel mistakes are easy to avoid?
- How many interfaces do specific concrete collection classes implement (such as LinkedList)? What do you think is the purpose of each interface?
- How many different implementations are there for a specific collection class (such as Set)? Do you think the number justifies it being an interface or not?
- How many levels of superclasses do specific concrete collection classes have? What do you think is the purpose of each inheritance level?
- Why does it make sense to have the utility classes instead of adding that functionality to the collection types themselves? Are there any overlapping methods (ones that are in both a specific collection and a utility class)? If so, is there any guidance on which one you should use?
Most APIs are documented using a standard technique like Javadoc to automatically generate nice looking documentation. For this exercise, since you are just starting the process of thinking about APIs, we are not requiring this style of documentation but it will be required for later projects.
API Discovery
Typically there are two kinds of programmers that are interested in your code:
- External:
- typical goal: how to provide useful access to information that encapsulates the implementation details while allowing for extensions for as wide a variety of unexpected features as possible
- such as: between the frontend and backend (e.g., between sub-groups within the project)
- such as: between the platform and developers for the platform (e.g., between iOS and app developers or between Facebook and add-ons or game developers)
- note: all of these methods will need to be
public
- vision:
- How you plan to separate the graphical interface from the interpreter and how do you plan to let them communicate when necessary?
- What objects will be used for communication: making it clear how needed information will get where it is needed, what will be available and what will be encapsulated, what things will be immutable, and what errors may be thrown?
- Internal:
- typical goal: how to provide paths for extension through implementing interfaces or subclasses for expected new features while keeping the core implementation closed to modification
- such as: between the backend and its future maintenance programmers (e.g., between programmers within the same sub-group)
- such as: between the platform and developers that port that platform to new technologies (e.g., between Facebook and its mobile and web teams)
- note: while some of these methods may be
public, many may be protected or package friendly
- vision:
- How you plan to provide paths for extension through interfaces, inheritance, and design patterns for new features you might reasonably expect to be added to the program?
- What subclasses or implementing classes will be used to extend your part to add new features: making it clear what kind of code someone will be expected to write, what parts of your code you expect to be closed to modification, and what errors may be thrown?
Choose someone's previous Cell Society project and examine it from the perspective of an API by categorizing each public or protected method in the Simulation "module" from following perspectives:
- method should not be part of the API (i.e., it should not be public)
- method should be part of the external API because it helps people on the team working in other modules write their code
- method should be part of the internal API because it helps future coders within the module extend it
A simplified view of just the public/protected methods for each team is available here.
Now that you have a sense of the kind of service your project currently provides to programmers, think about the kind of service you wish it provided. In other words, spend this time designing the API instead of just having it happen. write a simplified (i.e., less than one page) API description of both the internal and external Simulation API. Note which classes are abstract/interface and which concrete and, for concrete classes that are part of the external API, justify why they do not need to represent an abstraction.
Then describe how to use your new external and internal APIs to do the following tasks:
- external: as a client of the backend, the frontend selects an existing simulation to display and then starts running that kind of simulation, updating its own grid visualization
- internal: a new developer joins the the backend team and adds a new possible kind of simulation that can be available for the frontend to choose
Your written explanation should include both English and Java descriptions of the task:
- English: how do you want programmers to think of the process of using the API to accomplish this task using metaphors or analogies (e.g., folder paradigm), or standard programming ideas (e.g., step by step or substitution via polymorphism) beyond simply restating the procedural steps
- Java: list the actual Java methods you expect to use from the API to accomplish this task with a comment about how they would be used (e.g., call, implement, or change)
SLogo APIs
Review each person's answers to the planning questions and try to come to a team consensus to start further discussions. Also discuss any issues or concerns anyone has about the specifications or goals of the project (see the Basic Implementation goals for more details if necessary).
Then consider the following additional questions as you discuss the basic design elements of the SLogo project. Write a high-level description of the different parts of the project and how they can interact without worrying about the implementation details.
- When does parsing need to take place and what does it need to start properly?
- What is the result of parsing and who receives it?
- When are errors detected and how are they reported?
- What do commands know, when do they know it, and how do they get it?
- How is the GUI updated after a command has completed execution?
A picture may be helpful to show how your parts are related to and dependent on each other.
Write a simplified description for each of the four APIs in the project (i.e., no more than one page each) that incorporates your vision for each as well as the public classes and methods. Note which classes you expect to be abstractions (e.g., abstract or interface) and which concrete, for the concrete classes, justify why they do not need to be an abstraction. A class's behavior is its public methods, including any parameters and a return value. These method signatures can be written as they would appear in Java code, but your focus should be on describing their purpose in the class, not their implementation. To summarize a class and its purpose, you may only highlight the most important methods in this first draft.
Class-Responsibility-Collaborator Cards
Now that your team has thought about the problem generally, use CRC cards to refine your design and help you focus on interface instead of implementation issues. A CRC card is an index card (which nicely limits how much each class can do) that answers the following questions about a class to describe its behavior without getting into the details of how it implements that behavior. Index cards are also useful because they are easy to change and move around to see their relationship visually.
- What active behaviors is this class responsible for (i.e., not getters/setters)?
- What other classes are required to help this class fulfill those responsibilities?
These other classes will either be passed to this object's constructor or methods, returned from a method, or created by this object internally.
Here are some examples of completed CRC cards. In these examples, the actions are given in English, not as a Java method signature (name, parameters, and return type). Your version must be written as a Java signature to provide more details about the flow of the program.
Use Cases
The following scenarios are provided to help test the completeness and flexibility of your design. By writing the steps needed to complete each case below you will be able to see how effectively your design handles these scenarios and others will be able to better understand how deeply you have considered the basic issues. It may help to role play or draw a
diagram of how your classes collaborate to complete each case. For this exercise each step, try to include both the class used and the method used to accomplish the step. To make things more interesting, pair up with another team and try to do this part using their design.
- The user types 'fd 50' in the
command window, sees the turtle move in the display window leaving a
trail, and has the command added to the environment's history.
- The user types '50 fd' in the
command window and sees an error message that the command was not formatted correctly.
- The user types 'pu fd 50 pd fd 50' in the command window and sees the turtle move twice (once without a trail and once with a trail).
- The user changes the color of the environment's background.
Here are some examples of completed Use Cases. In these examples, the steps are given in English, not as a Java method calls. Your version should be written as a sequence of Java method calls to provide more details about the flow of the program.