In Item-1 of Effective Java, Mr. Bloch emphasize why and how it is important to use Static Factory methods instead of constructors.
Here is goofy and wasteful way to get Boolean instances
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public Boolean getFalse(){ | |
return new Boolean(false); | |
} | |
public Boolean getTrue(){ | |
return new Boolean(true); | |
} |
Here is shiny and frugally way to get immutable Boolean instance with static factory method
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static Boolean valueOf(boolean b){ | |
return b ? Boolean.TRUE : Boolean.FALSE; | |
} |
Lets go over advantages of using static factory methods
1.) Unlike constructors, the have names. If parameters to a constructor do not describe object being returned, a static factory with well choosen name is easier to use and resulting client code easier to read.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public BigInteger(int, int, Random){} | |
//which returns a BigInteger that is probably prime | |
//would have been better expressed as a static factory method | |
public static BigInteger probablePrime(int, int, Random){} |
Another example is multiple constructors with same signature as I met in stackoverflow.
Two constructors with same signature doing different things.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Arquivo { | |
private File diretorio = null ; | |
public Arquivo(File dir){ | |
this.diretorio = dir; | |
} | |
public Arquivo(String dir){ | |
this( new File(dir) ); | |
} | |
public Arquivo(String fileName){ | |
this( new File("./src/Data/"+fileName) ); | |
} | |
} |
Can be managed by using static factory methods.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Arquivo { | |
private File diretorio = null ; | |
private Arquivo(File dir){ | |
this.diretorio = dir; | |
} | |
public static Arquivo newInstanceByFile(File dir){ | |
return new Arquivo(dir); | |
} | |
public static Arquivo newInstanceByFilePath(String path){ | |
return new Arquivo(new File(path) ); | |
} | |
public static Arquivo newInstanceByFileName(String name){ | |
return new Arquivo(new File("./src/Data/"+fileName)); | |
} | |
} |
2.) Unlike constructors, they are not required to create a new object each time they're invoked. This is demonstrated as in boolean example above and important to use system resources frugally by avoiding unnecessary instance creation.
3.) A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type. Mr Bloch exemplifies this advantage with Service Provider Framework pattern.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface Provider { | |
Service newService(); | |
} | |
public interface Service { | |
// Service-specific methods go here | |
} | |
public class Services { | |
private Services() {} // Prevents instantiation (Item 4) | |
// Maps service names to services | |
private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>(); | |
public static final String DEFAULT_PROVIDER_NAME = "<def>"; | |
// Provider registration API | |
public static void registerDefaultProvider(Provider p) { | |
registerProvider(DEFAULT_PROVIDER_NAME, p); | |
} | |
public static void registerProvider(String name, Provider p) { | |
providers.put(name, p); | |
} | |
// Service access API | |
public static Service newInstance() { | |
return newInstance(DEFAULT_PROVIDER_NAME); | |
} | |
public static Service newInstance(String name) { | |
Provider p = providers.get(name); | |
if (p == null) | |
throw new IllegalArgumentException( | |
"No provider registered with name: " + name); | |
return p.newService(); | |
} | |
} |
Finally, he give a list of some common method names to statis factory methods.
- valueOf
- of
- getInstance
- newInstance
- getType
- newType
1 comment:
شركة المثالية للتنظيف
شركة تنظيف خزانات
شركة صيانة مسابح
شركة مكافحة النمل الابيض
Post a Comment