Fraction oneHalf = new Fraction(1, 2);
Fraction twoThirds = new Fraction(2, 3);
Fraction sum = oneHalf.sum(twoThirds);
What do you think are the attributes of Fraction?
Two int's? A two-sized
array of int? A map?
List<String> data = new ArrayList<>();
Ship s = new Battleship();
Link cta = new EmailLink();
DateFormat formatter = new SimpleDateFormat();
public void foo(List<String> foo) {
// this method will work with any
// implementation of List, even
// if it hasn't been created
}
public List<String> foo() {
// this method will return a List
// but you shouldn't worry about which.
// In fact it can change in the future!
// But it'll always be a List
}
public class Foo {
// This attribute is a List
// but it's implementation can change
private List<String> data;
}
public class PersonService {
private PersonDAO dao;
public PersonService(final PersonDAO dao) {
// I can inject the implementation I need!
this.dao = dao;
}
}
public class ContactServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) {
String id = req.getParameter("id");
Contact contact = this.fetchFromDatabase(id);
String message = String.format("%s - %s", id, contact);
res.getWriter().println(message);
}
}
public class ContactServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res) {
String id = re.getParameter("id");
Contact contact = service.findById(id);
res.setAttribute("contact", contact);
RequestDispatcher dispatcher = getServletContext()
.getRequestDispatcher(CONTACT_VIEW);
dispatcher.forward(request, response);
}
}
public class Fraction {
private int numerator;
private int denominator;
public Fraction(int numerator, int denominator) {
final int GCF = gcf(numerator, denominator);
this.numerator = numerator / GCF;
this.denominator = denominator / GCF;
}
private static int gcf(int a, int b) {
return b == 0 ? a : gcf(b, a % b);
}
public int getNumerator() {
return numerator;
}
public int getDenominator() {
return denominator;
}
}
public class Fraction {
private int numerator;
private int denominator;
public Fraction(int numerator, int denominator) {
final int GCF =
ArithmeticOperations.gcf(numerator, denominator);
this.numerator = numerator / GCF;
this.denominator = denominator / GCF;
}
public int getNumerator() {
return numerator;
}
public int getDenominator() {
return denominator;
}
}
public class final ArithmeticOperations {
private ArithmeticOperations() {
throw new AssertionError("This class shouldn't be instantiated");
}
public static int gcf(int a, int b) {
return b == 0 ? a : gcf(b, a % b);
}
}
public class final FractionOperations {
private FractionOperations() {
throw new AssertionError("This class shouldn't be instantiated");
}
public static Fraction sum(Fraction this, Fraction that) {
final int LCM = ArithmeticOperations.lcm(this.getDenominator(), that.getDenominator());
final int numerator = LCM / this.getDenominator() * that.getNumerator()
+ LCM / that.getNumerator() * this.getNumerator();
return new Fraction(numerator, LCM);
}
}
public class Fraction {
// code
public Fraction sum(Fraction that) {
final int LCM = ArithmeticOperations.lcm(this.denominator, that.denominator);
final int numerator = LCM / this.denominator * that.numerator
+ LCM / that.denominator * this.numerator;
return new Fraction(numerator, LCM);
}
}
public class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double distance(Point p) {
return Math.sqrt(Math.pow(x - p.x, 2)
+ Math.pow(y - p.y, 2))
}
}
public class Vehicle {
// more code
private Point location;
// more code
public double distance(Vehicle v) {
// reuse of distance code from Point
return location.distance(v.location);
}
}
public Square implements Shape {
// code
public double getLength() {
return this.length;
}
}
public Circle implements Shape {
// code
public double getRadius() {
return this.radius;
}
}
public double sumOfAreas(List<Shape> shapes) {
double total = 0.0;
for (Shape s : shapes) {
if (s instanceof Square) {
Square sq = (Square) s;
total += sq.getLength() * sq.getLength();
} else if (s instanceof Circle) {
Circle c = (Circle) s;
total += c.getRadius() * c.getRadius() * Math.PI;
}
}
return total;
}
public interface Shape {
// code
double getArea();
}
public class Square implements Shape {
// code
public double getArea() {
return this.length * this.length;
}
}
public class Circle implements Shape {
// code
public double getArea() {
return this.radius * this.radius * Math.PI;
}
}
public double sumOfAreas(List<Shape> shapes) {
double total = 0.0;
for (Shape s : shapes) {
total += s.getArea();
}
return total;
}
public class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double distance(Point p) {
return Math.sqrt(Math.pow(x - p.x, 2)
+ Math.pow(y - p.y, 2))
}
}
public class Vehicle extends Point {
// Vehicle now has a distance() method
}
public class Rectangle {
private double a;
private double b;
public double getA() {
return a;
}
public void setA(double a) {
this.a = a;
}
public double getB() {
return b;
}
public void setB(double b) {
this.b = b;
}
}
public void foo(Rectangle r) {
r.setA(5.0);
r.setB(4.0);
r.getA(); // it's 5.0
}
public class Square extends Rectangle {
// Square has two attributes, but
// it should have only one right?
@Override
public void setA(double a) {
this.a = a;
this.b = a; // b and a should be equal
}
@Override
public void setB(double b) {
this.b = b;
this.a = b; // b and a should be equal
}
}
Square s = new Square();
foo(s);
* * *
public void foo(Rectangle r) {
r.setA(5.0);
r.setB(4.0); // a also set a to 4.0
r.getA(); // it's not longer 5.0!
}
public GridList(SlingHttpServletRequest request) {
ValueMap properties = request.getResource().adaptTo(ValueMap.class);
String leftLink = properties.get("leftlink", "");
String leftTitle = properties.get("lefttitle", "");
this.leftGridBlock = new GridBlockDialog(leftLink, leftTitle);
String rightLink = properties.get("rightlink", "");
String rightTitle = properties.get("righttitle", "");
this.rightGridBlock = new GridBlockDialog(rightLink, rightTitle);
}
public GridList(SlingHttpServletRequest request) {
ValueMap properties = request.getResource().adaptTo(ValueMap.class);
GridBlockDialog[] blocks = new GridBlockDialog[2];
String[] values = {"left", "right"};
for (int i = 0; i < blocks.length; ++i) {
String link = properties.get(values[i] + "link", "");
String title = properties.get(values[i] + "title", "");
String desc = properties.get(values[i] + "description", "");
blocks[i] = new GridBlockDialog(link, title, description);
}
this.leftGridBlock = blocks[0];
this.rightGridBlock = blocks[1];
}
Try to use arrays to
your advantage
public GridList(SlingHttpServletRequest request) {
ValueMap properties = request.getResource().adaptTo(ValueMap.class);
this.leftGridBlock = createDialog(properties, "left");
this.rightGridBlock = createDialog(properties, "right");
}
Or use functions