SlideShare a Scribd company logo
1 of 25
Effective Java                 (Second Edition)


CHAPTER 4: Classes and Interfaces


              presented by
            Chandan Benjaram
Agenda
Item 13: Minimize the accessibility of classes and members

Item 14: In public classes, use accessor methods, not public fields

Item 15: Minimize mutability

Item 16: Favor composition over inheritance

Item 17: Design and document for inheritance or else prohibit it

Item 18: Prefer interfaces to abstract classes

Item 19: Use interfaces only to define types

Item 20: Prefer class hierarchies to tagged classes

Item 21: Use function objects to represent strategies

Item 22: Favor static member classes over non-static
Item-13: Minimize the accessibility of classes and
                    members
   A well designed API should hide all of its implementation details(a.k.a,
   internals) and thus component inter-communication should happen
   through a well declared API standards (protocols). Thus in general, it
   should encourage highest possible cohesion and loose coupling, if any!

Point-I: Make each class member as inaccessible as possible
  How you do it?
     ➡use package private/public on top-outer classes
     ➡use access modifiers for members (private, package private,
     protected, public)

  Leaks?
    ➡security can be leaked if class implements ‘Serializable’

  Fix:
    ➡use ‘transient’ keyword
Point-II: Instance fields should never be public
  Problem:
     //Potential security hole!
     public static final Type[] VALUES = { ... };

  Fix:
      private static final Type[] PRIVATE_VALUES = { ... };
      public static final List VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));



Point-III: Public classes should not contain any public fields with the exception of
immutable public static final fields
Item-14: Public classes should encourage use of
   accessors/mutators instead of public fields
  ➡if a class is accessible outside its package, provide accessors
  ➡incase of package private/private nested classes, it is OK to expose
  fields through ‘public’ access modifiers
Item-15: Minimize mutability
What is immutable class?
 ➡its a, very simple to write, class whose instance can not be
 modified once initialized
 ➡maintains a single state across all calls, thus thread safe by
 default

How to make a class immutable?
  ➡avoid mutators (use functional approach instead!)
  ➡make it non-extendable
  ➡make all fields final
  ➡make all fields private
  ➡ensure exclusive access to any mutators, if any
   Ex: Use defensive copying techniques, readObject, etc.

Note: beware of nested classes! (possible security hole)
Advantages of immutable classes:
  ➡each object belongs to a single state avoiding any complex state
  transformations
  ➡by default, they are thread-safe. thus no synchronization needed
  ➡effective pooling, caching can be performed with the aid of
  different techniques and patterns
    Ex: Factory pattern.

Suggestion:
 ➡never provide a copy constructor/clone methods (String.copy()
 violates)

Disadvantages:
   ➡each distinct value object requires its own object increasing
   memory footprint and GC demand
   ➡problem becomes more worse when working with complicated
   multistage operations on large objects
Solution:
 ➡memory footprint and GC demand problem can be limited by
 sharing class self internals.
      Ex: BigInteger (signum-magnitude)
       public BigInteger negate()
          Returns a BigInteger whose value is (-this).
 ➡nicely designed public companion classes can handle multistage
 operations problem very smoothly
   Ex: StringBuilder for immutable class, String

finally:
 ➡classes should be immutable unless there is a precise reason to
 make mutable
 ➡make every field as final unless there is a precise reason to avoid
 ➡fully initialize object with all its required invariants either using
 constructor/static factories but not with any public helpers
   Hint: Builder pattern can save your life!
Item-16: Favor Composition over Inheritance
But, why?
  ➡violates encapsulation
  ➡parent private fields can not be accessible if needed!

Solution:
 ➡Use Composition pattern + Forwarding Methods, which may be seen
 as Decorator pattern (loosely speaking!)
but wait, there is a problem:
 ➡it may cause wrapped object blind in viewing wrapper object. thus
 Callback frameworks fails to function as expected. A ‘SELF problem’.
When to prefer inheritance then?
 ➡if you can precisely establish a ‘is-a’ relationship between sub-class
 and super-class then go for it!
      JDK violators- Properties (is-not-a HashTable), Stack (is-not-a
      Vector), etc.

Finally:
  ➡read API docs thoroughly for any flaws, violations, limitations, etc.,
  before implementing an interface
Item-17: Design and document for Inheritance or
                 else prohibit it
  ➡class must document its self-use of override-able methods
  ➡parent private fields can not be accessible if needed!
  ➡a class designed for inheritance must be reviewed thoroughly. once
  shipped, it would be impossible to make changes without breaking
  own clients
  ➡constructors must not invoke override-able methods

  Example:
  a super class
a subclass




 Finally:
   ➡incase of no options other than self-use of override-able methods,
   use self specific code to private helpers
Item-18: Prefer interfaces to abstract classes
 ➡as   java permits only single inheritance, a abstract class type
 definition is more constrained vs an interface definition
 ➡abstract class hierarchies may cause ‘combinatorial explosion’
 ➡on the other hand, interfaces are ideal for mixins. thus adds more
 type definitions to primary type
 ➡existing classes can be easily retrofitted to implement new
 interface
 ➡design your interface with outmost case. once it is shipped & used,
 it can not be possible to change method signature or add more
 without breaking its clients
 ➡preferably, provide a ‘skeletal implementation’(abstract interface) of
 your interface to go along with it
 Ex: AbstractMap<K,V>, AbstractList<E>, etc. (many)
Item 19: Use interfaces only to define types
 ➡interfaces should be only used to define                         mixin type
 ➡avoid designing constant interfaces
Why?
  -> you are entering into a client commitment
  -> pollutes inheritance hierarchy for namespaces

  // DONT DO THIS
  // CONSTANT INTERFACE
  package edu.ej.ch14;
  public interface Interface1{
  	    static String NAME_PREFIX = "_";
  }

  //CLASS IMPLEMENTING INTERFACE
  public class Class1 implements Interface1 {
  	    @Override
  	    public String toString() {
  	    	    return NAME_PREFIX + Class1.class.getName();
  	    }
  }

  // A TEST HELPER
  class Tester1 {
  	    public static void main(String[] args) {
  	    	    Class1 clazz1 = new Class1();
  	    	    System.out.printf("Class1#toString: %1$s", clazz1.toString());
  	    }
  }

  // OUT PUT
  Class1#toString: _edu.ej.ch14.Class1
Contd...
JDK violators?
   java.io.ObjectStreamConstants

What   to do with constants?
  ->   use enum type constants
  ->   use helper constant classes
  ->   you can use ‘static import’ to avoid name qualifications

JDK followers?
   java.lang.Integer, java.lang.Double, etc.
Item 20: Prefer class hierarchies to tagged
                  classes
➡they   provide a multi datatype benefit
Contd...
➡kinda verbose, error-prone, inefficient, and may violate inheritance
➡limits the use of type detectors (‘instanceof’/‘isassignablefrom’)
➡a simple fix can be replacing tagged class with class hierarchy as:
// Class hierarchy replacement for a tagged class
abstract class Figure {
	    abstract double area();
}

class Circle extends Figure {
	    final double radius;

	   Circle(double radius) {
	   	    this.radius = radius;
	   }

	   double area() {
	   	    return Math.PI * (radius * radius);
	   }
}

class Rectangle extends Figure {
	    final double length;
	    final double width;

	   Rectangle(double length, double width) {
	   	    this.length = length;
	   	    this.width = width;
	   }

	   double area() {
	   	    return length * width;
	   }
}
Item 21: Use function objects to represent
                strategies
➡function  object: an object which performs actions on other
objects using self methods
➡primarily used to implement Strategy Pattern
 Strategy Pattern (GOF def):
    Define a family of algorithms, encapsulate each one, and make them interchangeable.
    [The] Strategy [pattern] lets the algorithm vary independently from clients that use
    it.
➡help   to interchangeably operate generically
Contd...
➡how     we do it?
package edu.ej.ch14.item20;

import java.io.Serializable;

// DEFINE AN INTERFACE
public interface CustomComparator<T> {
	    int compare(T arg0, T arg1);
}

class Helper{
     // STRING TYPE IMPLEMENTATION
	    private static class StringComparator implements CustomComparator<String> {
	    	    @Override
	    	    public int compare(String arg0, String arg1) {
	    	    	    // comparing lexicographically
	    	    	    return arg0.compareTo(arg1);
	    	    }
	    }

    // BYTE TYPE IMPLEMENTATION
	   private static class ByteComparator implements CustomComparator<Byte>, Serializable {
	   	    @Override
	   	    public int compare(Byte arg0, Byte arg1) {
	   	    	    return arg0.compareTo(arg1);
	   	    }
	   }

	   // CACHED IMPLEMENTATIONS WRAPPED AS INTERFACE TYPE
	   public static final CustomComparator<String> STRING_COMP= new StringComparator();
	   public static final CustomComparator<Byte> BYTE_COMP= new ByteComparator();
	
}
Contd...
              ➡tester
class Tester {
	    public static void main(String[] args) {
	    	    System.out.printf("STRING result: %1$d %nBYTE result: %2$d", Helper.STRING_COMP.compare("x", "x"),
	    	    	    	    Helper.BYTE_COMP.compare(Byte.valueOf("1"), Byte.valueOf("3")));
	    }
}

// OUTPUT
STRING result: 0
BYTE result: -2 (OBSERVER THIS)




               ➡how I did?
                ➡defined an interface for strategy (comparing)
                ➡created 2 separate concrete strategy implementations
                   (StringComparator, ByteComparator)
                   ➡I could have done anonymous implementation, but it limits my
                   mixin types
                   ➡encapsulated strategy implementations and exported as helper
                   constants to strategy type.
Item 22: Favor static member classes over non-
                     static
  ➡There    are 4 types of nested classes:
   1) static member classes
   2) non-static member classes
   3) anonymous classes
   4) local classes

   What are they for?
   1) static member classes:
    ➡a static class that’s declared inside other class(enclosing class)
    ➡has access to enclosing class’s members
    ➡obeys general contract as static members
    ➡generally used as public helpers (recall POJO Builder pattern!)

   2) non-static member classes:
      -> each instance is associated with enclosing instance
      -> a non-modifiable association to enclosing class is established
      when member classes is created
      -> you can create instance of member class in 2 ways, a) calling
      constructor of member class from enclosing class instance
      member b)outerInstance.new InnerClass(...)
Contd...
2) non-static member classes (contd...):
   -> commonly used as Adaptors for enclosing class
    Ex: java.util.Map.values()
   -> member class instance always requires an enclosing class
   instance
   -> it forces you to allocate enclosing class instance even if you
   do not need it!
   -> always prefer static member classes incase you do not have
   to access instance members!

3) anonymous classes:
   -> has no name
   -> declared and instantiated at point of use
   -> limits your type checking capabilities
   -> clients can not invoke any functions
   -> can not support multiple types
   -> generally used to create function objects, process objects,
   within static factories
   Ex: new Comparator(compare()...omitted)
Contd...
4) local classes:
    -> same as local variables in terms of place and rules
    -> ideally, should be kept under fewer lines
    -> creates instances that are tied to enclosing class
have fun

More Related Content

What's hot

Top 20 c# interview Question and answers
Top 20 c# interview Question and answersTop 20 c# interview Question and answers
Top 20 c# interview Question and answersw3asp dotnet
 
Chapter 9 Interface
Chapter 9 InterfaceChapter 9 Interface
Chapter 9 InterfaceOUM SAOKOSAL
 
Object oriented concepts & programming (2620003)
Object oriented concepts & programming (2620003)Object oriented concepts & programming (2620003)
Object oriented concepts & programming (2620003)nirajmandaliya
 
Creating and destroying objects
Creating and destroying objectsCreating and destroying objects
Creating and destroying objectsSandeep Chawla
 
Module 10 : creating and destroying objects
Module 10 : creating and destroying objectsModule 10 : creating and destroying objects
Module 10 : creating and destroying objectsPrem Kumar Badri
 
Interface java
Interface java Interface java
Interface java atiafyrose
 
Strategy and Template Pattern
Strategy and Template PatternStrategy and Template Pattern
Strategy and Template PatternJonathan Simon
 
Corejavainterviewquestions.doc
Corejavainterviewquestions.docCorejavainterviewquestions.doc
Corejavainterviewquestions.docJoyce Thomas
 
Effective Java - Chapter 4: Classes and Interfaces
Effective Java - Chapter 4: Classes and InterfacesEffective Java - Chapter 4: Classes and Interfaces
Effective Java - Chapter 4: Classes and Interfacesİbrahim Kürce
 
Vb ch 3-object-oriented_fundamentals_in_vb.net
Vb ch 3-object-oriented_fundamentals_in_vb.netVb ch 3-object-oriented_fundamentals_in_vb.net
Vb ch 3-object-oriented_fundamentals_in_vb.netbantamlak dejene
 
C++ classes tutorials
C++ classes tutorialsC++ classes tutorials
C++ classes tutorialsakreyi
 
Type Annotations in Java 8
Type Annotations in Java 8 Type Annotations in Java 8
Type Annotations in Java 8 FinLingua, Inc.
 

What's hot (20)

Top 20 c# interview Question and answers
Top 20 c# interview Question and answersTop 20 c# interview Question and answers
Top 20 c# interview Question and answers
 
Chapter 9 Interface
Chapter 9 InterfaceChapter 9 Interface
Chapter 9 Interface
 
C# interview quesions
C# interview quesionsC# interview quesions
C# interview quesions
 
Object oriented concepts & programming (2620003)
Object oriented concepts & programming (2620003)Object oriented concepts & programming (2620003)
Object oriented concepts & programming (2620003)
 
C# interview questions
C# interview questionsC# interview questions
C# interview questions
 
Creating and destroying objects
Creating and destroying objectsCreating and destroying objects
Creating and destroying objects
 
Module 10 : creating and destroying objects
Module 10 : creating and destroying objectsModule 10 : creating and destroying objects
Module 10 : creating and destroying objects
 
Interface java
Interface java Interface java
Interface java
 
Kotlin in action
Kotlin in actionKotlin in action
Kotlin in action
 
Strategy and Template Pattern
Strategy and Template PatternStrategy and Template Pattern
Strategy and Template Pattern
 
Corejavainterviewquestions.doc
Corejavainterviewquestions.docCorejavainterviewquestions.doc
Corejavainterviewquestions.doc
 
Effective Java - Chapter 4: Classes and Interfaces
Effective Java - Chapter 4: Classes and InterfacesEffective Java - Chapter 4: Classes and Interfaces
Effective Java - Chapter 4: Classes and Interfaces
 
Vb ch 3-object-oriented_fundamentals_in_vb.net
Vb ch 3-object-oriented_fundamentals_in_vb.netVb ch 3-object-oriented_fundamentals_in_vb.net
Vb ch 3-object-oriented_fundamentals_in_vb.net
 
10 strategy pattern
10 strategy pattern10 strategy pattern
10 strategy pattern
 
C++ classes tutorials
C++ classes tutorialsC++ classes tutorials
C++ classes tutorials
 
Pocket java
Pocket javaPocket java
Pocket java
 
Type Annotations in Java 8
Type Annotations in Java 8 Type Annotations in Java 8
Type Annotations in Java 8
 
Introduction to JAVA
Introduction to JAVAIntroduction to JAVA
Introduction to JAVA
 
Java interview questions
Java interview questionsJava interview questions
Java interview questions
 
C++
C++C++
C++
 

Viewers also liked

Effective java 摘選條目分享 3 - concurrency
Effective java   摘選條目分享 3 - concurrencyEffective java   摘選條目分享 3 - concurrency
Effective java 摘選條目分享 3 - concurrencyKane Shih
 
Effective Java - Still Effective After All These Years
Effective Java - Still Effective After All These YearsEffective Java - Still Effective After All These Years
Effective Java - Still Effective After All These YearsMarakana Inc.
 
Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrencyfeng lee
 
Effective Java - Chapter 2: Creating and Destroying Objects
Effective Java - Chapter 2: Creating and Destroying ObjectsEffective Java - Chapter 2: Creating and Destroying Objects
Effective Java - Chapter 2: Creating and Destroying Objectsİbrahim Kürce
 
Effective java
Effective javaEffective java
Effective javaEmprovise
 
The Go Programing Language 1
The Go Programing Language 1The Go Programing Language 1
The Go Programing Language 1İbrahim Kürce
 

Viewers also liked (7)

Effective java 摘選條目分享 3 - concurrency
Effective java   摘選條目分享 3 - concurrencyEffective java   摘選條目分享 3 - concurrency
Effective java 摘選條目分享 3 - concurrency
 
Effective Java
Effective JavaEffective Java
Effective Java
 
Effective Java - Still Effective After All These Years
Effective Java - Still Effective After All These YearsEffective Java - Still Effective After All These Years
Effective Java - Still Effective After All These Years
 
Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrency
 
Effective Java - Chapter 2: Creating and Destroying Objects
Effective Java - Chapter 2: Creating and Destroying ObjectsEffective Java - Chapter 2: Creating and Destroying Objects
Effective Java - Chapter 2: Creating and Destroying Objects
 
Effective java
Effective javaEffective java
Effective java
 
The Go Programing Language 1
The Go Programing Language 1The Go Programing Language 1
The Go Programing Language 1
 

Similar to Effective Java Chapter 4 Key Design Principles

Structural pattern 3
Structural pattern 3Structural pattern 3
Structural pattern 3Naga Muruga
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)David McCarter
 
CSharp presentation and software developement
CSharp presentation and software developementCSharp presentation and software developement
CSharp presentation and software developementfrwebhelp
 
Framework Design Guidelines For Brussels Users Group
Framework Design Guidelines For Brussels Users GroupFramework Design Guidelines For Brussels Users Group
Framework Design Guidelines For Brussels Users Groupbrada
 
Lecture 5 interface.pdf
Lecture  5 interface.pdfLecture  5 interface.pdf
Lecture 5 interface.pdfAdilAijaz3
 
Android coding standard
Android coding standard Android coding standard
Android coding standard Rakesh Jha
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
C questions
C questionsC questions
C questionsparm112
 
Android coding guide lines
Android coding guide linesAndroid coding guide lines
Android coding guide lineslokeshG38
 
Design Patterns - Part 1 of 2
Design Patterns - Part 1 of 2Design Patterns - Part 1 of 2
Design Patterns - Part 1 of 2Savio Sebastian
 
21UCAC31 Java Programming.pdf(MTNC)(BCA)
21UCAC31 Java Programming.pdf(MTNC)(BCA)21UCAC31 Java Programming.pdf(MTNC)(BCA)
21UCAC31 Java Programming.pdf(MTNC)(BCA)ssuser7f90ae
 
Unit3 packages &amp; interfaces
Unit3 packages &amp; interfacesUnit3 packages &amp; interfaces
Unit3 packages &amp; interfacesKalai Selvi
 

Similar to Effective Java Chapter 4 Key Design Principles (20)

Classes & Interfaces
Classes & InterfacesClasses & Interfaces
Classes & Interfaces
 
Structural pattern 3
Structural pattern 3Structural pattern 3
Structural pattern 3
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)
 
Designing Better API
Designing Better APIDesigning Better API
Designing Better API
 
CSharp presentation and software developement
CSharp presentation and software developementCSharp presentation and software developement
CSharp presentation and software developement
 
Framework Design Guidelines For Brussels Users Group
Framework Design Guidelines For Brussels Users GroupFramework Design Guidelines For Brussels Users Group
Framework Design Guidelines For Brussels Users Group
 
Lecture 5 interface.pdf
Lecture  5 interface.pdfLecture  5 interface.pdf
Lecture 5 interface.pdf
 
Generics
GenericsGenerics
Generics
 
Android coding standard
Android coding standard Android coding standard
Android coding standard
 
C# Unit 2 notes
C# Unit 2 notesC# Unit 2 notes
C# Unit 2 notes
 
Software Design Patterns
Software Design PatternsSoftware Design Patterns
Software Design Patterns
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
C questions
C questionsC questions
C questions
 
Android coding guide lines
Android coding guide linesAndroid coding guide lines
Android coding guide lines
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
Object
ObjectObject
Object
 
Design Patterns - Part 1 of 2
Design Patterns - Part 1 of 2Design Patterns - Part 1 of 2
Design Patterns - Part 1 of 2
 
21UCAC31 Java Programming.pdf(MTNC)(BCA)
21UCAC31 Java Programming.pdf(MTNC)(BCA)21UCAC31 Java Programming.pdf(MTNC)(BCA)
21UCAC31 Java Programming.pdf(MTNC)(BCA)
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Unit3 packages &amp; interfaces
Unit3 packages &amp; interfacesUnit3 packages &amp; interfaces
Unit3 packages &amp; interfaces
 

Effective Java Chapter 4 Key Design Principles

  • 1. Effective Java (Second Edition) CHAPTER 4: Classes and Interfaces presented by Chandan Benjaram
  • 2. Agenda Item 13: Minimize the accessibility of classes and members Item 14: In public classes, use accessor methods, not public fields Item 15: Minimize mutability Item 16: Favor composition over inheritance Item 17: Design and document for inheritance or else prohibit it Item 18: Prefer interfaces to abstract classes Item 19: Use interfaces only to define types Item 20: Prefer class hierarchies to tagged classes Item 21: Use function objects to represent strategies Item 22: Favor static member classes over non-static
  • 3. Item-13: Minimize the accessibility of classes and members A well designed API should hide all of its implementation details(a.k.a, internals) and thus component inter-communication should happen through a well declared API standards (protocols). Thus in general, it should encourage highest possible cohesion and loose coupling, if any! Point-I: Make each class member as inaccessible as possible How you do it? ➡use package private/public on top-outer classes ➡use access modifiers for members (private, package private, protected, public) Leaks? ➡security can be leaked if class implements ‘Serializable’ Fix: ➡use ‘transient’ keyword
  • 4. Point-II: Instance fields should never be public Problem: //Potential security hole! public static final Type[] VALUES = { ... }; Fix: private static final Type[] PRIVATE_VALUES = { ... }; public static final List VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES)); Point-III: Public classes should not contain any public fields with the exception of immutable public static final fields
  • 5. Item-14: Public classes should encourage use of accessors/mutators instead of public fields ➡if a class is accessible outside its package, provide accessors ➡incase of package private/private nested classes, it is OK to expose fields through ‘public’ access modifiers
  • 6. Item-15: Minimize mutability What is immutable class? ➡its a, very simple to write, class whose instance can not be modified once initialized ➡maintains a single state across all calls, thus thread safe by default How to make a class immutable? ➡avoid mutators (use functional approach instead!) ➡make it non-extendable ➡make all fields final ➡make all fields private ➡ensure exclusive access to any mutators, if any Ex: Use defensive copying techniques, readObject, etc. Note: beware of nested classes! (possible security hole)
  • 7. Advantages of immutable classes: ➡each object belongs to a single state avoiding any complex state transformations ➡by default, they are thread-safe. thus no synchronization needed ➡effective pooling, caching can be performed with the aid of different techniques and patterns Ex: Factory pattern. Suggestion: ➡never provide a copy constructor/clone methods (String.copy() violates) Disadvantages: ➡each distinct value object requires its own object increasing memory footprint and GC demand ➡problem becomes more worse when working with complicated multistage operations on large objects
  • 8. Solution: ➡memory footprint and GC demand problem can be limited by sharing class self internals. Ex: BigInteger (signum-magnitude) public BigInteger negate() Returns a BigInteger whose value is (-this). ➡nicely designed public companion classes can handle multistage operations problem very smoothly Ex: StringBuilder for immutable class, String finally: ➡classes should be immutable unless there is a precise reason to make mutable ➡make every field as final unless there is a precise reason to avoid ➡fully initialize object with all its required invariants either using constructor/static factories but not with any public helpers Hint: Builder pattern can save your life!
  • 9. Item-16: Favor Composition over Inheritance But, why? ➡violates encapsulation ➡parent private fields can not be accessible if needed! Solution: ➡Use Composition pattern + Forwarding Methods, which may be seen as Decorator pattern (loosely speaking!)
  • 10. but wait, there is a problem: ➡it may cause wrapped object blind in viewing wrapper object. thus Callback frameworks fails to function as expected. A ‘SELF problem’.
  • 11. When to prefer inheritance then? ➡if you can precisely establish a ‘is-a’ relationship between sub-class and super-class then go for it! JDK violators- Properties (is-not-a HashTable), Stack (is-not-a Vector), etc. Finally: ➡read API docs thoroughly for any flaws, violations, limitations, etc., before implementing an interface
  • 12. Item-17: Design and document for Inheritance or else prohibit it ➡class must document its self-use of override-able methods ➡parent private fields can not be accessible if needed! ➡a class designed for inheritance must be reviewed thoroughly. once shipped, it would be impossible to make changes without breaking own clients ➡constructors must not invoke override-able methods Example: a super class
  • 13. a subclass Finally: ➡incase of no options other than self-use of override-able methods, use self specific code to private helpers
  • 14. Item-18: Prefer interfaces to abstract classes ➡as java permits only single inheritance, a abstract class type definition is more constrained vs an interface definition ➡abstract class hierarchies may cause ‘combinatorial explosion’ ➡on the other hand, interfaces are ideal for mixins. thus adds more type definitions to primary type ➡existing classes can be easily retrofitted to implement new interface ➡design your interface with outmost case. once it is shipped & used, it can not be possible to change method signature or add more without breaking its clients ➡preferably, provide a ‘skeletal implementation’(abstract interface) of your interface to go along with it Ex: AbstractMap<K,V>, AbstractList<E>, etc. (many)
  • 15. Item 19: Use interfaces only to define types ➡interfaces should be only used to define mixin type ➡avoid designing constant interfaces Why? -> you are entering into a client commitment -> pollutes inheritance hierarchy for namespaces // DONT DO THIS // CONSTANT INTERFACE package edu.ej.ch14; public interface Interface1{ static String NAME_PREFIX = "_"; } //CLASS IMPLEMENTING INTERFACE public class Class1 implements Interface1 { @Override public String toString() { return NAME_PREFIX + Class1.class.getName(); } } // A TEST HELPER class Tester1 { public static void main(String[] args) { Class1 clazz1 = new Class1(); System.out.printf("Class1#toString: %1$s", clazz1.toString()); } } // OUT PUT Class1#toString: _edu.ej.ch14.Class1
  • 16. Contd... JDK violators? java.io.ObjectStreamConstants What to do with constants? -> use enum type constants -> use helper constant classes -> you can use ‘static import’ to avoid name qualifications JDK followers? java.lang.Integer, java.lang.Double, etc.
  • 17. Item 20: Prefer class hierarchies to tagged classes ➡they provide a multi datatype benefit
  • 18. Contd... ➡kinda verbose, error-prone, inefficient, and may violate inheritance ➡limits the use of type detectors (‘instanceof’/‘isassignablefrom’) ➡a simple fix can be replacing tagged class with class hierarchy as: // Class hierarchy replacement for a tagged class abstract class Figure { abstract double area(); } class Circle extends Figure { final double radius; Circle(double radius) { this.radius = radius; } double area() { return Math.PI * (radius * radius); } } class Rectangle extends Figure { final double length; final double width; Rectangle(double length, double width) { this.length = length; this.width = width; } double area() { return length * width; } }
  • 19. Item 21: Use function objects to represent strategies ➡function object: an object which performs actions on other objects using self methods ➡primarily used to implement Strategy Pattern Strategy Pattern (GOF def): Define a family of algorithms, encapsulate each one, and make them interchangeable. [The] Strategy [pattern] lets the algorithm vary independently from clients that use it. ➡help to interchangeably operate generically
  • 20. Contd... ➡how we do it? package edu.ej.ch14.item20; import java.io.Serializable; // DEFINE AN INTERFACE public interface CustomComparator<T> { int compare(T arg0, T arg1); } class Helper{ // STRING TYPE IMPLEMENTATION private static class StringComparator implements CustomComparator<String> { @Override public int compare(String arg0, String arg1) { // comparing lexicographically return arg0.compareTo(arg1); } } // BYTE TYPE IMPLEMENTATION private static class ByteComparator implements CustomComparator<Byte>, Serializable { @Override public int compare(Byte arg0, Byte arg1) { return arg0.compareTo(arg1); } } // CACHED IMPLEMENTATIONS WRAPPED AS INTERFACE TYPE public static final CustomComparator<String> STRING_COMP= new StringComparator(); public static final CustomComparator<Byte> BYTE_COMP= new ByteComparator(); }
  • 21. Contd... ➡tester class Tester { public static void main(String[] args) { System.out.printf("STRING result: %1$d %nBYTE result: %2$d", Helper.STRING_COMP.compare("x", "x"), Helper.BYTE_COMP.compare(Byte.valueOf("1"), Byte.valueOf("3"))); } } // OUTPUT STRING result: 0 BYTE result: -2 (OBSERVER THIS) ➡how I did? ➡defined an interface for strategy (comparing) ➡created 2 separate concrete strategy implementations (StringComparator, ByteComparator) ➡I could have done anonymous implementation, but it limits my mixin types ➡encapsulated strategy implementations and exported as helper constants to strategy type.
  • 22. Item 22: Favor static member classes over non- static ➡There are 4 types of nested classes: 1) static member classes 2) non-static member classes 3) anonymous classes 4) local classes What are they for? 1) static member classes: ➡a static class that’s declared inside other class(enclosing class) ➡has access to enclosing class’s members ➡obeys general contract as static members ➡generally used as public helpers (recall POJO Builder pattern!) 2) non-static member classes: -> each instance is associated with enclosing instance -> a non-modifiable association to enclosing class is established when member classes is created -> you can create instance of member class in 2 ways, a) calling constructor of member class from enclosing class instance member b)outerInstance.new InnerClass(...)
  • 23. Contd... 2) non-static member classes (contd...): -> commonly used as Adaptors for enclosing class Ex: java.util.Map.values() -> member class instance always requires an enclosing class instance -> it forces you to allocate enclosing class instance even if you do not need it! -> always prefer static member classes incase you do not have to access instance members! 3) anonymous classes: -> has no name -> declared and instantiated at point of use -> limits your type checking capabilities -> clients can not invoke any functions -> can not support multiple types -> generally used to create function objects, process objects, within static factories Ex: new Comparator(compare()...omitted)
  • 24. Contd... 4) local classes: -> same as local variables in terms of place and rules -> ideally, should be kept under fewer lines -> creates instances that are tied to enclosing class

Editor's Notes