Assignment 9: Programming Paradigms
Working on the Assignment
Find the Refactoring Technique
5 points
We started the lecture discussing the tradeoffs between functional and object-oriented programming. The following is code in a functional style:
class Rock {}
class Paper {}
class Scissors {}
function toString(playerChoice) {
if (playerChoice instanceof Rock) return "💎";
if (playerChoice instanceof Paper) return "🧻";
if (playerChoice instanceof Scissors) return "✂️";
}
And the following is the same code in an object-oriented style:
class Rock {
toString() {
return "💎";
}
}
class Paper {
toString() {
return "📄";
}
}
class Scissors {
toString() {
return "✂️";
}
}
As it turns out, there’s a refactoring technique from the catalog of refactorings to go from the first version to the second. What is it?
Refactoring Beyond Techniques
5 points
As discussed in lecture, our implementation of the beats()
function in Version 2 was mechanical: we just rearranged code from Version 1 and it ended up like this:
function beats(thisPlayerChoice, otherPlayerChoice) {
if (thisPlayerChoice instanceof Rock)
return otherPlayerChoice instanceof Scissors;
if (thisPlayerChoice instanceof Paper)
return otherPlayerChoice instanceof Rock;
if (thisPlayerChoice instanceof Scissors)
return otherPlayerChoice instanceof Paper;
}
But code in a functional style doesn’t have to be this confusing mess of if
s and return
s. Refactor this function such that all the if
s are gone and there’s only one return
. The behavior of the function must remain the same (otherwise it isn’t really a refactoring, is it?). As far as I call tell, there isn’t a technique for this in the catalog.
Unduck Typing
10 points
Translate the code we discussed in the part of the lecture about Duck Typing to Java. Keep the definition of randomChoice()
in a functional style.
Unmonkey Patching
15 points
In lecture we monkey patched JavaScript’s Array
s to include a sample()
method. Java’s List
s also don’t have such method:
import java.util.List;
public class Main {
public static void main(String[] args) {
var choices = List.of("💎", "📄", "✂️");
var rock = choices.get(0); // 👍 Works
var player1Choice = choices.sample(); // ⚠️ Doesn’t exist
}
}
Luckily, for any feature that our language doesn’t have, there’s a design pattern to work around it.
What’s that design pattern? (It may or many have been covered previously in the course; consult the catalog if necessary.)
Complete the code below, only changing the parts that are indicated:
import java.util.List;
// Below is my implementation of the ___ design pattern:
// ___ Implementation goes here ____
public class Main {
public static void main(String[] args) {
var choices = List.of("💎", "📄", "✂️");
var choicesExtendedWithSampleMethod = ___ choices ___; // Use the design pattern here.
var rock = choicesExtendedWithSampleMethod.get(0); // 👍 Works
var player1Choice = choicesExtendedWithSampleMethod.sample(); // 👍 Works
}
}
Mixins
15 points
I wish I could convert my rocks both to JSON and to XML:
class Rock {
toString() {
return "💎";
}
}
class JsonableRock extends Rock {
toJson() {
return `{ "rock": "${this}" }`;
}
}
class XmlableRock extends Rock {
toXml() {
return `<rock>${this}</rock>`;
}
}
// ⚠️ The following doesn’t work because JavaScript
// (or Java, for that matter) doesn’t support multiple inheritance.
class JsonableAndXmlableRock extends JsonableRock, XmlableRock {}
const jsonableAndXmlableRock = new JsonableAndXmlableRock();
console.log(jsonableAndXmlableRock.toJson());
console.log(jsonableAndXmlableRock.toXml());
-
Help me turn
JsonableRock
into a mixin calledjsonableRockMixin()
and turnXmlableRock
into a mixin calledxmlableRockMixin()
. Then show how to define theJsonableAndXmlableRock
class. Don’t change the definitions of theRock
class and thejsonableAndXmlableRock
variable, and don’t change theconsole.log()
lines. -
What if we renamed both
toJson()
andtoXml()
toserialize()
? Which implementation would be called when we calljsonableAndXmlableRock.serialize()
? How can we change the definition ofJsonableAndXmlableRock
to make the other implementation be called?
this
Makes Sense
25 points
I was playing with the Rock–Paper–Scissors game and I came up with the following component (for your convenience, I pushed the code to the this-makes-sense
branch in the TODOOSE repository):
class Rock extends React.Component {
toString() {
return "💎";
}
handleClick() {
alert(`You clicked ${this}`);
}
render() {
return (
<button
onClick={() => {
this.handleClick();
}}
>
{this.toString()}
</button>
);
}
}
The function passed to onClick
seemed silly to me: it just calls this.handleClick
, but this.handleClick
is already a function. I wanted to cut the intermediary and pass this.handleClick
to onClick
directly, like this:
class Rock extends React.Component {
toString() {
return "💎";
}
handleClick() {
alert(`You clicked ${this}`);
}
render() {
return <button onClick={this.handleClick}>{this.toString()}</button>;
}
}
But that didn’t work! When I clicked on the button, it said “You clicked undefined”.
I looked around and found an incantation that fixed the issue: this.handleClick = this.handleClick.bind(this)
. Here’s how the code turned out:
class Rock extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
toString() {
return "💎";
}
handleClick() {
alert(`You clicked ${this}`);
}
render() {
return <button onClick={this.handleClick}>{this.toString()}</button>;
}
}
But I’m not sure I understand what’s going on:
-
Why did I see “You clicked undefined” before I introduced that incantation?
-
How does the incantation work, and why does it fix the issue?
Some links to help you with this question:
-
The documentation for the
bind()
method. As it turns out this behavior has nothing to do with React in particular—it’s about JavaScript in general! -
A blog post that pretty much answers this question. But we want an explanation in your own words.
-
In TODOOSE, to keep things simple, we sidestepped this issue by using code that looks like the first version written in this question.
Object-Oriented vs. Functional Programming in React
25 points
Read the remainder section on object-oriented programming, the section on function programming, and for fun the section on other paradigms. Reflect on the questions you find there. Ask follow-up questions on the forum 🔒 and during office hours.
Now let’s critique the design of React. Go over the Main Concepts (§ 1–12). Some concepts in React are in an object-oriented style, while others are in a functional style. For example, it uses objects (object-oriented), but it favors immutability and avoids side-effects (functional). Write about which parts of the design are object-oriented and which parts are functional, and why. Also, say why do you think these aspects are well designed or not. You don’t need to be exhaustive and talk about everything covered in Main Concepts, just what you find worth discussing.
Departing Note
“Oh my god, your assignments are so vague!”
Exactly! Vague requirements: that’s the life of a software engineer! Lucky for you, this is the last assignment written by me 😉 (The next and final assignment will be written by our Head CA.)
The key to success is to start working early, talk to your colleagues, go to office hours, ask questions on the forum, show the staff your partial answers to check if you’re headed on the right direction, and so forth.
Ask questions such as: What’s the target audience of this explanation? What can I expect my readers to already know? Is this idea better explained with an example (hint: it always is!)? And so forth.
Thanks for sticking around and I hope you have as much fun answering these assignments as I had coming up with them.
Submission
⚠️ Your assignment is submitted only when you submit the form below.
If you run into problems, send an email to assignment-submission@jhu-oose.com. Include the information about the submission: your GitHub Identifier and the Commit Identifier. Don’t include any information about the feedback—it’s anonymous.