Classes part ii
This presentation is the property of its rightful owner.
Sponsored Links
1 / 28

Classes (part II) PowerPoint PPT Presentation


  • 89 Views
  • Uploaded on
  • Presentation posted in: General

Classes (part II). Roadmap. Emulating overriding w/ state Delegation vs. Subclassing Binary Methods LSP Immutability Interfaces vs. Classes Law of Demeter: “Tell, don’t ask” Message chains Defensive copies Bad API Exception safety Origins of classes – nouns Problem vs. Program space

Download Presentation

Classes (part II)

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Classes part ii

Classes (part II)


Roadmap

Roadmap

  • Emulating overriding w/ state

  • Delegation vs. Subclassing

  • Binary Methods

  • LSP

  • Immutability

  • Interfaces vs. Classes

  • Law of Demeter: “Tell, don’t ask”

  • Message chains

  • Defensive copies

  • Bad API

  • Exception safety

  • Origins of classes – nouns

  • Problem vs. Program space

  • Origins of classes – Kent Beck

  • Fat vs. thin interfaces

  • Furniture - subclassing alternatives


Origins of classes

Origins of Classes

  • Grouping of data and logic

  • Rate of change

  • Parameter objects

  • Overall approach: start writing, discover the classes from the code

  • Source: “Implementation Patterns”, Kent Beck


Grouping of data and logic

Grouping of data and logic

Use a class to say, “This data goes together and this logic goes with it”

“Implementation Patterns”, Kent Beck


Grouping before

Grouping – Before

if (ClassReader.SIGNATURES && signature != 0) {

++attributeCount;

size += 8;

newUTF8("Signature");

}

if (sourceFile != 0) {

++attributeCount;

size += 8;

newUTF8("SourceFile");

}

...


Grouping after

Grouping – After

AttributeWriter aw = new AttributeWriter(...);

aw.put(ClassReader.SIGNATURES && signature != 0, 8,

"Signature");

aw.put(sourceFile != 0, 8, "SourceFile");

...


Rate of change

Rate of Change

Put logic or data that changes at the same rate together and separate logic or data that changes at different rates

“Implementation Patterns”, Kent Beck


Rate of change example

Rate of Change - Example

// Before

void setAmount(int value, String currency) {

this.value = value;

this.currency = currency;

}

// After

void setAmount(int value, String currency) {

this.value = new Money(value, currency);

}


Parameter object

Parameter Object

Consolidate frequently used long parameter lists into an object

“Implementation Patterns”, Kent Beck


Parameter object example

Parameter Object - Example

// Before

setOuterBounds(x, y, width, height);

setInneerBounds(x + 2, y + 2, width - 4, height - 4);

// After

setOuterBounds(bounds);

setInnerBounds(bounds.expand(-2));


Interfaces width

Interfaces: Width

  • Thin

    • Support minimal set of necessary services

  • Humane

    • Support common usage

  • Fat

    • Support every imaginable service

  • Textbook example:

    • Java’s List inteface has 25 methods

    • Ruby’s Array class has 78 methods

      Source: http://martinfowler.com/bliki/HumaneInterface.html


Humane interface

Humane Interface

public class HumaneList<T> {

public T get();

public void remove(int n);

public int size();

public void set(int index, T value);

public void add(T value);

public T first();

public T last();

public void sort();

public int indexOf(T value);

}


Thin interface

Thin Interface

public class ThinList<T> {

public T get();

public void remove(int n);

public int size();

public void set(int index, T value);

}

// Client code – add a value

list.set(list.size(), newValue);

// Client code – get last

List.get(list.size() – 1);


Thin interfaces encourage foreign methods

Thin Interfaces Encourage Foreign Methods

public class Lists {

public static<T> void add(List<T> list, T value) {

list.set(list.size(), value);

}

public static<T> T getLast(List<T> list, T value) {

list.get(list.size() – 1);

}

public static<T> void sort(...)

public static<T> int IndexOf (...)

...

}


Thin vs humane

Thin vs. Humane

  • Thin interfaces – pros:

    • Coherency

      • of implementing class

      • of the interface itself

    • Easier subclassing

    • Client code is less coupled

  • Humane Interface – cons:

    • Less client code


Thin humane final thoughts

Thin/Humane – Final Thoughts

  • A spectrum, not a binary issue

    • An interface can be slightly humane and very much thin

  • Inside project boundaries?

    • Start with thin, let it evolve

  • Unknown users?

    • Humane seems more useful

    • OTOH, more difficult to fight coupling


Furniture design 1

Furniture – Design #1


Furniture subclassing alternatives

Furniture – Subclassing Alternatives


Classes part ii

public class Rect {

public final int top;

public final int left;

public final int bottom;

public final int right;

public Rect(int top, int left, int bottom, int right) {

this.top = top;

this.left = left;

this.bottom = bottom;

this.right = right;

}

}

public class Point {

public final int x;

public final int y;

public Point(int x, int y) {

this.x = x;

this.y = y;

}

}


Classes part ii

public abstract class Furniture {

public abstract Rect getBoundingRect();

}

public class Table extends Furniture {

private int width;

private int height;

public Table(int width, int height) {

this.width = width;

this.height = height;

}

@Override public Rect getBoundingRect() {

return new Rect(0, 0, width, height);

}

}


Classes part ii

public class Lamp extends Furniture {

private int base;

private int height;

public Lamp(int base, int height) {

this.base = base;

this.height = height;

}

@Override

public Rect getBoundingRect() {

return new Rect(0, 0, base, height);

}

}


Furniture design 2

Furniture – Design #2


Classes part ii

public class Furniture {

final List<Point> points = new ArrayList<Point>();

protected void add(int x ,int y) {

points.add(new Point(x, y));

}

public Rect getBoundingRect(){

List<Integer> xs = new ArrayList<Integer>();

List<Integer> ys = new ArrayList<Integer>();

for(Point p : points) {

xs.add(p.x);

ys.add(p.y);

}

return new Rect(min(ys), min(xs), max(ys), max(xs));

}

}


Classes part ii

public class Furniture {

...

static int max(List<Integer> values) {

int result = Integer.MIN_VALUE;

for(int n : values)

result = Math.max(result, n);

return result;

}

static int min(List<Integer> values) {

int result = Integer.MAX_VALUE;

for(int n : values)

result = Math.min(result, n);

return result;

}

}


Classes part ii

public class Table extends Furniture {

public Table(int width, int height) {

add(0, 0);

add(width, 0);

add(width, height);

add(0, height);

}

}

public class Lamp extends Furniture {

public Lamp(int base, int height) {

add(0, 0);

add(base, 0);

add(base / 2, height);

}

}


Furniture design 3

Furniture – Design #3


Classes part ii

Public class Furniture {

... // Same code as design #2

public Furniture newTable(int width, int height) {

Furniture result = new Furniture();

result.add(0, 0);

result.add(width, 0);

result.add(width, height);

result.add(0, height);

return result;

}

public Furniture newLamp(int base, int height) {

Furniture result = new Furniture();

result.add(0, 0);

result.add(base, 0);

result.add(base / 2, height);

return result;

}

}


Summary

Summary

  • Design #1:

    • getBoundingRect() over-ridden

    • Subclasses do most of the work

    • Elegant if computations vary greatly across subclasses

  • Design #2, #3:

    • Superclass does most/all of the work

    • Variation among subclasses expressed by state

    • Elegant if computations can be generalized

      • Without too many special cases crippling it

    • More efficient as number of variants grows


  • Login