Building the Question and Answer Models

Modeling Question and Answer#

The Question and Answer classes form the backbone of our program. Together they represent the questions and answers users have created.

Questions can have multiple answers but only one chosen answer, and an answer can belong to only one question. The diagram below shows the relationship between Question, Answer, and the other entities in our program:

Question and Answer Class Diagram

We have a circular dependency between Question and Answer, so we can implement either of them first. It's important we hold off on running either of them in isolation until both are implemented to avoid any runtime errors (i.e. Answer calling Question's getSummary() method before it's been implemented).

Building the Answer Model#

Our initial Answer implementation keeps track of an answer's ID, author, text, question, and attachments:

We use a default parameter to initialize the attachments parameter to an empty array if none is provided. Users should be able to add attachments to questions, so we need an addAttachment() method that adds items to the attachments array using Array.prototype.push() as shown below:

Updating an answer's text is simple as we can reassign the private text property to whatever string is passed to the method:

Generating a Summary#

To generate an answer's summary, we outsource part of the logic to User and Question by calling their respective getSummary() methods. We combine those summaries with a truncated version of the answer's text:

If the answer's text is longer than 40 characters, we take the first 37 characters using the String.prototype.substring() method and append three dots to the text to ensure the truncated string's length is also 40 characters long.

For generating a multi-line summary, we use the same strategy we used in Image.ts: Array.prototype.join() converts an array of strings into one big string where each item in the array becomes a new line in the final string.

The author and question sumaries are prefixed with - (a dash surrounded by one space on both sides) to make it easier to see that they live under a heading.

Below is a sample answer summary:

One of the key benefits behind the way we've built getSummary() is that the Question and User classes can add and remove lines in their summaries without having to touch code in the Answer class.

An Answer object is associated with the user that opened the answer by assigning the user to the answer's this.author property, but how will we ensure that the answer is added to the author's question list? And that the answer is added to the question's answers list? One possibility is to do it manually as shown below:

Improving addAnswer#

The problem with that approach is that we have no way of enforcing that User.prototype.addAnswer() and Question.prototype.addAnswer() are called every time an answer is created, so we could end up in a weird state where answers think they're associated with users and questions but the users and questions don't know the answers exist. To ensure that users and questions are always associated with an answer, we should make this association in the Answer constructor by calling the User and Question's addAnswer() method directly:

Adding Private Setters#

To clean things up a bit we introduce two private methods, setQuestion() and setAuthor() that hold the extra logic of associating questions and users with the answer:

 

This page is a preview of Beginners Guide to TypeScript

Start a new discussion. All notification go to the author.