SlideShare a Scribd company logo
1 of 64
Download to read offline
Developing Useful APIs
Dmitry Buzdin
October 2013, Riga
Dmitry Buzdin
buzdin@gmail.com
@buzdin
www.buzdin.lv
What is API?
API is the code you	

use every day
How many Jars do you 	

have in your classpath?
from 20 to100 jars?
Each
library has
its own API
!
and personality
Moreover, you create
new reusable APIs
inside your project
may be even in a separate module
APIs are written by
developers for
developers
Everything is Open
Source today!
Frameworks are
turning into micro-
frameworks
I have to
learn 100
APIs?
!
Is it possible
at all?
Option I:
lock yourself in a
dungeon
The best code in the world is 	

the one I wrote yesterday!
Option II:
learn to ride APIs
Are all APIs different?
Let’s try to
understand...
What is a Good API
• Easy to read	

• Easy to use	

• Hard to misuse	

• Easy to extend
How to Achieve That?
• Lets take a look at some:	

• module/package level approaches	

• class level patterns	

• method/code level idioms
Imagine building API for
the next 10 years and
1000s of people
Module Level
Dependency Management
• Put less transitive dependencies	

• Do you really need that commons-lang?	

• Do you remember about Guava
incompatibilities
Extreme example: OrientDB - zero dependencies!
Packaging
com.acme.lib
PublicAPI.java
impl
PublicInterface.java
spi CustomListener.java
Internal.java
Util.java
PublicBean.java
Stuff you
want to be
reused
Extension
API
Licensing
http://choosealicense.com/
Class Level
Lets build an API for a reusable gadget
Gadget gadget = new Gadget(name, id, options);!
// Gadget is connected at this point
public Gadget(name, id, options) {!
this.name = name;!
this.id = id;!
this.options = options;!
connect(); // could throw an exception!
}
Gadgets should always be connected
Can not create an instance
for testing
Create Gadget by static method or factory class
public Gadget(name, id, options) {!
this.name = name;!
this.id = id;!
this.options = options; !
}!
!
public static Gadget newGadget(name, id, options) {!
Gadget gadget = new Gadget(name, id, options);!
gadget.connect();!
return gadget;!
}!
!
public class GadgetFactory {!
public Gadget newGadget(name, id, options) {!
Gadget gadget = new Gadget(name, id, options);!
gadget.connect();!
return gadget;!
} !
}
public static Gadget newGadget(name, id, options) {!
Gadget gadget = new DefaultGadget(name, id, options);!
gadget.connect();!
return gadget;!
}!
!
public interface Gadget {!
void connect();!
}!
!
public class DefaultGadget implements Gadget {!
public void connect() {!
}!
}
Hide your gadget behind interface
Because you could change the implementation	

Details are well hidden
public static Gadget newGadget(name, id, options) {!
Gadget gadget = new DefaultGadget(name, id, options);!
gadget.connect();!
return gadget;!
}!
!
public interface Gadget {!
void connect();!
}!
!
public final class DefaultGadget implements Gadget {!
DefaultGadget() {!
}!
public void connect() {!
}!
}
Make it final with package-level constructor
Disallow
unsanctioned
modification of
your code
Open Closed Principle
"software entities (classes, modules, functions, etc.) !
should be open for extension, but closed for modification"
public final class DefaultGadget implements Gadget {!
public void setStrategy(BehaviorStrategy s) {!
// changes the behavior of this Gadget;!
}!
}
Allowing
sanctioned
modifications
Gadget gadget = Gadgets.newGadget(name, id, options);!
// Gadget is connected at this point!
!
!
// Similar APIs!
Files.createFile(...); // JDK 7!
Lists.newArrayList(...); // Guava
Resulting code
Method Overloading
Gadget gadget = Gadgets.newGadget(name, id, options);!
Gadget gadget = Gadgets.newGadget(id, options);!
Gadget gadget = Gadgets.newGadget(name, options);!
Gadget gadget = Gadgets.newGadget(id, enabled);!
Gadget gadget = Gadgets.newGadget(id, name, enabled);!
What if different parameter
combinations should be supported?
public class GadgetBuilder() {!
!
// ...!
Long id;!
String name;!
!
GadgetBuilder withId(Long id) {!
this.id = id;!
return this;!
}!
!
GadgetBuilder withName(String name) {!
this.name = name;!
return this;!
}!
!
Gadget build() {!
Gadget gadget = new GadgetImpl();!
gadget.setId(id);!
gadget.setName(name);!
gadget.setOptions(options);!
gadget.setEnabled(enabled)!
}!
}
Covering all
possibilities
// Quartz Trigger Builder Example!
trigger = newTrigger()!
.withIdentity("trigger3", "group1")!
.withSchedule(cronSchedule("0 0/2 8-17 * * ?"))!
.forJob("myJob", "group1")!
.build();
// Constructing stuff using builder!
Gadget gadget = new GadgetBuilder()!
.withId(1)!
.withName(“ok”)!
.withOptions(options)!
.build();
Much better now!
Lets build a
Gadget Service
Gadget Service
public final class GadgetService {!
!
private static final GadgetService instance = new GadgetService();!
!
public static void getInstance() {!
return instance;!
}!
!
public void saveGadget(Gadget gadget) {!
...!
}!
}
Static fields may produce memory leaks	

Difficult to test code using that
Gadget Service
public class GadgetServiceImpl implements GadgetService {!
!
// To be called by factory method/class!
public GadgetServiceImpl() {}!
!
public void saveGadget(Gadget gadget) {!
...!
}!
!
}!
!
!
public class MyClass {!
@Inject!
GadgetService service;!
}
Everyone is using
Dependency
Injection now
You do not know which 	

Dependency Injection
framework 	

developers will use!
Spring, Guice, CDI, Dagger, PicoContainer etc.
Abstract DI
public interface BeanRegistry {!
!
  void register(Class<?> type);!
!
  <T> T getBean(Class<T> type);!
!
  <T> Collection<T> getBeans(Class<T> type);!
!
}
https://github.com/DozerMapper/dozer/blob/master/core/src/main/java/org/dozer/inject/
DozerBeanContainer.java
Provide DI Bindings
• Write bindings for other frameworks	

• Your beans are accessible	

• Ready for the next big thing
public class SpringBeanRegistry implements BeanRegistry {!
public SpringBeanRegistry(ApplicationContext context) {!
//..!
}!
}
Make your api Extensible
interface Plugin {!
void init(Context context);!
}
How to allow
people to
contribute
extensions?
Service Provider Interface
http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
ServiceLoader<Plugin> pluginLoader = ServiceLoader.load(Plugin.class);!
for (Plugin plugin : pluginLoader) {!
plugin.init(context);!
}
META-INF/services/lv.jug.api.Plugin
lv.jug.api.plugin1.Plugin
lv.jug.api.plugin2.Plugin!
lv.jug.api.plugin3.Plugin
class MyExtensionPlugin implements Plugin {!
@Override!
void init(Context context) {!
System.out.println(“Hello”);!
}!
}
SPI Benefits
• No static initialization	

• Automatic lookup in all Jars	

• Everything is initialized in one place
Annotation Scanning
• Mark extensions with custom annotations	

• Use bytecode scanning library
@Extension
final TypeReporter reporter = new TypeReporter() {!
!
@Override!
public Class<? extends Annotation>[] annotations() {!
return new Class[]{Extension.class};!
}!
!
@Override!
public void reportTypeAnnotation(Class<? extends Annotation> annotation, String className) {!
// do something!
}!
!
};!
final AnnotationDetector cf = new AnnotationDetector(reporter);!
cf.detect();
@Extension!
class MyExtensionPlugin implements Plugin {!
@Override!
void init(Context context) {!
System.out.println(“Hello”);!
}!
}
Finds all
annotated
classess
https://github.com/rmuller/infomas-asl
Annotation Benefits
• Instantiating and using via reflection	

• Easy API to explain	

• Quite fast
Method Level
List<String> myList = new ArrayList<>();!
updateList(myList);!
return myList;
void updateList(List<String> items) {!
for (Iterator<String> iterator=items.iterator();
iterator.hasNext();) {!
String item = iterator.next() {!
if (item.startsWith(“//”)) {!
iterator.remove();!
}!
}!
}
Modifying mutable parameters
List<Item> myList = new ArrayList<>();!
List<Item> updatedList = updateItems(myList);!
return updatedList;
List<String> updateList(final List<String> items) {!
List<String> result = new ArrayList<>();!
for (String item : items) {!
if (!item.startsWith(“//”)) {!
result.add(item);!
}!
}!
return result;!
}
Considering all
method
arguments as
immutable
try {!
downloadPhoto(id, path);!
} catch(ConnectionNotAvailable | PhotoNotFound e) {!
System.out.println(“WAT!?”);!
}
void downloadPhoto(String id, Path path) !
throws ConnectionNotAvailable, PhotoNotFound {!
...!
}
Have to handle all exceptions
downloadPhoto(id, path);
void downloadPhoto(String id, Path path) {!
...!
}
Rely on Runtime
Exceptions
void uploadPhoto(byte[] photo, String name, String type) {!
...!
}
What if photo is too big?	

What types are supported? RTFM?
void uploadPhoto(InputStream photo,!
String name, !
PhotoType type) {!
...!
}!
!
public enum PhotoType {!
JPEG, PNG!
}
Pass binaries as
InputStreams
Create enum for
parameters
PhotoService photoService = ...!
photoService.openTransaction();!
try {!
photoService.uploadPhoto(...);!
photoService.changeAttributes(...);!
} catch (Exception e) {!
photoService.rollbackTransaction();!
} finally {!
photoService.commitTransaction();!
}
Just boring...
PhotoService photoService = ...!
photoService.doInTransaction(new Execution() {!
public void work(Context context) {!
context.uploadPhoto(...);!
context.changeAttributes(...);!
}!
});!
!
public void doInTransaction(Execution execution) {!
Context context = openTransactionContext();!
try {!
execution.work(context);!
} catch (Exception e) {!
context.rollback();!
} finally {!
context.commit();!
}!
}
Writing it once
PhotoService photoService = ...!
photoService.doInTransaction(context -> {!
context.uploadPhoto(...);!
context.changeAttributes(...);!
});
Java 8
public Object someServiceMethod() {!
return transactionTemplate.execute(new TransactionCallback() {!
!
// the code in this method executes in a transactional context!
public Object doInTransaction(TransactionStatus status) {!
updateOperation1();!
return resultOfUpdateOperation2();!
}!
});!
}
Same approach in Spring Framework
I learned something
today!
All APIs operate on
single set of
rules & patterns
APIs have
fashion too
Java API	

from 1998
Java API	

from 2013
You have to follow
fashion trends to ride
APIs
• Treat all reusable classes you write as API	

• Use minimum API principle	

• Learn by example from open source
projects
Recommended Books
Developing Useful APIs

More Related Content

What's hot

ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentationipolevoy
 
Testing Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchTesting Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchMats Bryntse
 
Javascript and Jquery Best practices
Javascript and Jquery Best practicesJavascript and Jquery Best practices
Javascript and Jquery Best practicesSultan Khan
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Ran Mizrahi
 
Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Jaroslaw Palka
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsRan Mizrahi
 
Secrets of JavaScript Libraries
Secrets of JavaScript LibrariesSecrets of JavaScript Libraries
Secrets of JavaScript Librariesjeresig
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java DevelopersYakov Fain
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScriptYakov Fain
 
JavaOne TS-5098 Groovy SwingBuilder
JavaOne TS-5098 Groovy SwingBuilderJavaOne TS-5098 Groovy SwingBuilder
JavaOne TS-5098 Groovy SwingBuilderAndres Almiray
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012Anton Arhipov
 
JavaScript Misunderstood
JavaScript MisunderstoodJavaScript Misunderstood
JavaScript MisunderstoodBhavya Siddappa
 
Unit and functional testing with Siesta
Unit and functional testing with SiestaUnit and functional testing with Siesta
Unit and functional testing with SiestaGrgur Grisogono
 
Intro to JavaScript Testing
Intro to JavaScript TestingIntro to JavaScript Testing
Intro to JavaScript TestingRan Mizrahi
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Codescidept
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016Codemotion
 
walkmod - JUG talk
walkmod - JUG talkwalkmod - JUG talk
walkmod - JUG talkwalkmod
 
Speed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSocketsSpeed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSocketsYakov Fain
 

What's hot (20)

ActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group PresentationActiveWeb: Chicago Java User Group Presentation
ActiveWeb: Chicago Java User Group Presentation
 
Testing Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchTesting Ext JS and Sencha Touch
Testing Ext JS and Sencha Touch
 
Javascript and Jquery Best practices
Javascript and Jquery Best practicesJavascript and Jquery Best practices
Javascript and Jquery Best practices
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
 
Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design Patterns
 
Secrets of JavaScript Libraries
Secrets of JavaScript LibrariesSecrets of JavaScript Libraries
Secrets of JavaScript Libraries
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
 
JavaOne TS-5098 Groovy SwingBuilder
JavaOne TS-5098 Groovy SwingBuilderJavaOne TS-5098 Groovy SwingBuilder
JavaOne TS-5098 Groovy SwingBuilder
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012Mastering Java Bytecode With ASM - 33rd degree, 2012
Mastering Java Bytecode With ASM - 33rd degree, 2012
 
JavaScript Misunderstood
JavaScript MisunderstoodJavaScript Misunderstood
JavaScript Misunderstood
 
Unit and functional testing with Siesta
Unit and functional testing with SiestaUnit and functional testing with Siesta
Unit and functional testing with Siesta
 
Intro to JavaScript Testing
Intro to JavaScript TestingIntro to JavaScript Testing
Intro to JavaScript Testing
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
JavaScript in 2016
JavaScript in 2016JavaScript in 2016
JavaScript in 2016
 
walkmod - JUG talk
walkmod - JUG talkwalkmod - JUG talk
walkmod - JUG talk
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
Speed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSocketsSpeed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSockets
 

Similar to Developing Useful APIs

From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)Jose Manuel Pereira Garcia
 
Android Bootstrap
Android BootstrapAndroid Bootstrap
Android Bootstrapdonnfelker
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!DataArt
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James NelsonGWTcon
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsHassan Abid
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolboxShem Magnezi
 
Sword fighting with Dagger GDG-NYC Jan 2016
 Sword fighting with Dagger GDG-NYC Jan 2016 Sword fighting with Dagger GDG-NYC Jan 2016
Sword fighting with Dagger GDG-NYC Jan 2016Mike Nakhimovich
 
OpenSocial Intro
OpenSocial IntroOpenSocial Intro
OpenSocial IntroPamela Fox
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングscalaconfjp
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Ngoc Dao
 
Testable JavaScript: Application Architecture
Testable JavaScript:  Application ArchitectureTestable JavaScript:  Application Architecture
Testable JavaScript: Application ArchitectureMark Trostler
 
Introduction to Griffon
Introduction to GriffonIntroduction to Griffon
Introduction to GriffonJames Williams
 

Similar to Developing Useful APIs (20)

From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
Android Bootstrap
Android BootstrapAndroid Bootstrap
Android Bootstrap
 
"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues"Javascript" por Tiago Rodrigues
"Javascript" por Tiago Rodrigues
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!
 
Javascript Design Patterns
Javascript Design PatternsJavascript Design Patterns
Javascript Design Patterns
 
jQuery introduction
jQuery introductionjQuery introduction
jQuery introduction
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
 
End-to-end testing with geb
End-to-end testing with gebEnd-to-end testing with geb
End-to-end testing with geb
 
Building Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture ComponentsBuilding Modern Apps using Android Architecture Components
Building Modern Apps using Android Architecture Components
 
Android dev toolbox
Android dev toolboxAndroid dev toolbox
Android dev toolbox
 
Sword fighting with Dagger GDG-NYC Jan 2016
 Sword fighting with Dagger GDG-NYC Jan 2016 Sword fighting with Dagger GDG-NYC Jan 2016
Sword fighting with Dagger GDG-NYC Jan 2016
 
OpenSocial Intro
OpenSocial IntroOpenSocial Intro
OpenSocial Intro
 
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディングXitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
 
Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014Xitrum @ Scala Matsuri Tokyo 2014
Xitrum @ Scala Matsuri Tokyo 2014
 
Testable JavaScript: Application Architecture
Testable JavaScript:  Application ArchitectureTestable JavaScript:  Application Architecture
Testable JavaScript: Application Architecture
 
ParisJS #10 : RequireJS
ParisJS #10 : RequireJSParisJS #10 : RequireJS
ParisJS #10 : RequireJS
 
Extend sdk
Extend sdkExtend sdk
Extend sdk
 
Introduction to Griffon
Introduction to GriffonIntroduction to Griffon
Introduction to Griffon
 
Mini curso Android
Mini curso AndroidMini curso Android
Mini curso Android
 
Annotation processing tool
Annotation processing toolAnnotation processing tool
Annotation processing tool
 

More from Dmitry Buzdin

How Payment Cards Really Work?
How Payment Cards Really Work?How Payment Cards Really Work?
How Payment Cards Really Work?Dmitry Buzdin
 
Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?Dmitry Buzdin
 
How to grow your own Microservice?
How to grow your own Microservice?How to grow your own Microservice?
How to grow your own Microservice?Dmitry Buzdin
 
How to Build Your Own Test Automation Framework?
How to Build Your Own Test Automation Framework?How to Build Your Own Test Automation Framework?
How to Build Your Own Test Automation Framework?Dmitry Buzdin
 
Delivery Pipeline for Windows Machines
Delivery Pipeline for Windows MachinesDelivery Pipeline for Windows Machines
Delivery Pipeline for Windows MachinesDmitry Buzdin
 
Big Data Processing Using Hadoop Infrastructure
Big Data Processing Using Hadoop InfrastructureBig Data Processing Using Hadoop Infrastructure
Big Data Processing Using Hadoop InfrastructureDmitry Buzdin
 
Архитектура Ленты на Одноклассниках
Архитектура Ленты на ОдноклассникахАрхитектура Ленты на Одноклассниках
Архитектура Ленты на ОдноклассникахDmitry Buzdin
 
Riding Redis @ask.fm
Riding Redis @ask.fmRiding Redis @ask.fm
Riding Redis @ask.fmDmitry Buzdin
 
Rubylight JUG Contest Results Part II
Rubylight JUG Contest Results Part IIRubylight JUG Contest Results Part II
Rubylight JUG Contest Results Part IIDmitry Buzdin
 
Rubylight Pattern-Matching Solutions
Rubylight Pattern-Matching SolutionsRubylight Pattern-Matching Solutions
Rubylight Pattern-Matching SolutionsDmitry Buzdin
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Poor Man's Functional Programming
Poor Man's Functional ProgrammingPoor Man's Functional Programming
Poor Man's Functional ProgrammingDmitry Buzdin
 
Rubylight programming contest
Rubylight programming contestRubylight programming contest
Rubylight programming contestDmitry Buzdin
 
Continuous Delivery
Continuous Delivery Continuous Delivery
Continuous Delivery Dmitry Buzdin
 
Introduction to DevOps
Introduction to DevOpsIntroduction to DevOps
Introduction to DevOpsDmitry Buzdin
 
Thread Dump Analysis
Thread Dump AnalysisThread Dump Analysis
Thread Dump AnalysisDmitry Buzdin
 
Pragmatic Java Test Automation
Pragmatic Java Test AutomationPragmatic Java Test Automation
Pragmatic Java Test AutomationDmitry Buzdin
 

More from Dmitry Buzdin (20)

How Payment Cards Really Work?
How Payment Cards Really Work?How Payment Cards Really Work?
How Payment Cards Really Work?
 
Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?Как построить свой фреймворк для автотестов?
Как построить свой фреймворк для автотестов?
 
How to grow your own Microservice?
How to grow your own Microservice?How to grow your own Microservice?
How to grow your own Microservice?
 
How to Build Your Own Test Automation Framework?
How to Build Your Own Test Automation Framework?How to Build Your Own Test Automation Framework?
How to Build Your Own Test Automation Framework?
 
Delivery Pipeline for Windows Machines
Delivery Pipeline for Windows MachinesDelivery Pipeline for Windows Machines
Delivery Pipeline for Windows Machines
 
Big Data Processing Using Hadoop Infrastructure
Big Data Processing Using Hadoop InfrastructureBig Data Processing Using Hadoop Infrastructure
Big Data Processing Using Hadoop Infrastructure
 
JOOQ and Flyway
JOOQ and FlywayJOOQ and Flyway
JOOQ and Flyway
 
Whats New in Java 8
Whats New in Java 8Whats New in Java 8
Whats New in Java 8
 
Архитектура Ленты на Одноклассниках
Архитектура Ленты на ОдноклассникахАрхитектура Ленты на Одноклассниках
Архитектура Ленты на Одноклассниках
 
Riding Redis @ask.fm
Riding Redis @ask.fmRiding Redis @ask.fm
Riding Redis @ask.fm
 
Rubylight JUG Contest Results Part II
Rubylight JUG Contest Results Part IIRubylight JUG Contest Results Part II
Rubylight JUG Contest Results Part II
 
Rubylight Pattern-Matching Solutions
Rubylight Pattern-Matching SolutionsRubylight Pattern-Matching Solutions
Rubylight Pattern-Matching Solutions
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Poor Man's Functional Programming
Poor Man's Functional ProgrammingPoor Man's Functional Programming
Poor Man's Functional Programming
 
Rubylight programming contest
Rubylight programming contestRubylight programming contest
Rubylight programming contest
 
Continuous Delivery
Continuous Delivery Continuous Delivery
Continuous Delivery
 
Introduction to DevOps
Introduction to DevOpsIntroduction to DevOps
Introduction to DevOps
 
Thread Dump Analysis
Thread Dump AnalysisThread Dump Analysis
Thread Dump Analysis
 
Pragmatic Java Test Automation
Pragmatic Java Test AutomationPragmatic Java Test Automation
Pragmatic Java Test Automation
 
Mlocjs buzdin
Mlocjs buzdinMlocjs buzdin
Mlocjs buzdin
 

Recently uploaded

Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 

Recently uploaded (20)

Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 

Developing Useful APIs

  • 1. Developing Useful APIs Dmitry Buzdin October 2013, Riga
  • 4. API is the code you use every day
  • 5. How many Jars do you have in your classpath? from 20 to100 jars?
  • 6. Each library has its own API ! and personality
  • 7. Moreover, you create new reusable APIs inside your project may be even in a separate module
  • 8. APIs are written by developers for developers
  • 10. Frameworks are turning into micro- frameworks
  • 11. I have to learn 100 APIs? ! Is it possible at all?
  • 12. Option I: lock yourself in a dungeon
  • 13. The best code in the world is the one I wrote yesterday!
  • 14. Option II: learn to ride APIs
  • 15. Are all APIs different?
  • 17. What is a Good API • Easy to read • Easy to use • Hard to misuse • Easy to extend
  • 18. How to Achieve That? • Lets take a look at some: • module/package level approaches • class level patterns • method/code level idioms
  • 19. Imagine building API for the next 10 years and 1000s of people
  • 21. Dependency Management • Put less transitive dependencies • Do you really need that commons-lang? • Do you remember about Guava incompatibilities Extreme example: OrientDB - zero dependencies!
  • 25. Lets build an API for a reusable gadget
  • 26. Gadget gadget = new Gadget(name, id, options);! // Gadget is connected at this point public Gadget(name, id, options) {! this.name = name;! this.id = id;! this.options = options;! connect(); // could throw an exception! } Gadgets should always be connected Can not create an instance for testing
  • 27. Create Gadget by static method or factory class public Gadget(name, id, options) {! this.name = name;! this.id = id;! this.options = options; ! }! ! public static Gadget newGadget(name, id, options) {! Gadget gadget = new Gadget(name, id, options);! gadget.connect();! return gadget;! }! ! public class GadgetFactory {! public Gadget newGadget(name, id, options) {! Gadget gadget = new Gadget(name, id, options);! gadget.connect();! return gadget;! } ! }
  • 28. public static Gadget newGadget(name, id, options) {! Gadget gadget = new DefaultGadget(name, id, options);! gadget.connect();! return gadget;! }! ! public interface Gadget {! void connect();! }! ! public class DefaultGadget implements Gadget {! public void connect() {! }! } Hide your gadget behind interface Because you could change the implementation Details are well hidden
  • 29. public static Gadget newGadget(name, id, options) {! Gadget gadget = new DefaultGadget(name, id, options);! gadget.connect();! return gadget;! }! ! public interface Gadget {! void connect();! }! ! public final class DefaultGadget implements Gadget {! DefaultGadget() {! }! public void connect() {! }! } Make it final with package-level constructor Disallow unsanctioned modification of your code
  • 30. Open Closed Principle "software entities (classes, modules, functions, etc.) ! should be open for extension, but closed for modification" public final class DefaultGadget implements Gadget {! public void setStrategy(BehaviorStrategy s) {! // changes the behavior of this Gadget;! }! } Allowing sanctioned modifications
  • 31. Gadget gadget = Gadgets.newGadget(name, id, options);! // Gadget is connected at this point! ! ! // Similar APIs! Files.createFile(...); // JDK 7! Lists.newArrayList(...); // Guava Resulting code
  • 32. Method Overloading Gadget gadget = Gadgets.newGadget(name, id, options);! Gadget gadget = Gadgets.newGadget(id, options);! Gadget gadget = Gadgets.newGadget(name, options);! Gadget gadget = Gadgets.newGadget(id, enabled);! Gadget gadget = Gadgets.newGadget(id, name, enabled);! What if different parameter combinations should be supported?
  • 33. public class GadgetBuilder() {! ! // ...! Long id;! String name;! ! GadgetBuilder withId(Long id) {! this.id = id;! return this;! }! ! GadgetBuilder withName(String name) {! this.name = name;! return this;! }! ! Gadget build() {! Gadget gadget = new GadgetImpl();! gadget.setId(id);! gadget.setName(name);! gadget.setOptions(options);! gadget.setEnabled(enabled)! }! } Covering all possibilities
  • 34. // Quartz Trigger Builder Example! trigger = newTrigger()! .withIdentity("trigger3", "group1")! .withSchedule(cronSchedule("0 0/2 8-17 * * ?"))! .forJob("myJob", "group1")! .build(); // Constructing stuff using builder! Gadget gadget = new GadgetBuilder()! .withId(1)! .withName(“ok”)! .withOptions(options)! .build(); Much better now!
  • 36. Gadget Service public final class GadgetService {! ! private static final GadgetService instance = new GadgetService();! ! public static void getInstance() {! return instance;! }! ! public void saveGadget(Gadget gadget) {! ...! }! } Static fields may produce memory leaks Difficult to test code using that
  • 37. Gadget Service public class GadgetServiceImpl implements GadgetService {! ! // To be called by factory method/class! public GadgetServiceImpl() {}! ! public void saveGadget(Gadget gadget) {! ...! }! ! }! ! ! public class MyClass {! @Inject! GadgetService service;! } Everyone is using Dependency Injection now
  • 38. You do not know which Dependency Injection framework developers will use! Spring, Guice, CDI, Dagger, PicoContainer etc.
  • 39. Abstract DI public interface BeanRegistry {! !   void register(Class<?> type);! !   <T> T getBean(Class<T> type);! !   <T> Collection<T> getBeans(Class<T> type);! ! } https://github.com/DozerMapper/dozer/blob/master/core/src/main/java/org/dozer/inject/ DozerBeanContainer.java
  • 40. Provide DI Bindings • Write bindings for other frameworks • Your beans are accessible • Ready for the next big thing public class SpringBeanRegistry implements BeanRegistry {! public SpringBeanRegistry(ApplicationContext context) {! //..! }! }
  • 41. Make your api Extensible interface Plugin {! void init(Context context);! } How to allow people to contribute extensions?
  • 42. Service Provider Interface http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html ServiceLoader<Plugin> pluginLoader = ServiceLoader.load(Plugin.class);! for (Plugin plugin : pluginLoader) {! plugin.init(context);! } META-INF/services/lv.jug.api.Plugin lv.jug.api.plugin1.Plugin lv.jug.api.plugin2.Plugin! lv.jug.api.plugin3.Plugin class MyExtensionPlugin implements Plugin {! @Override! void init(Context context) {! System.out.println(“Hello”);! }! }
  • 43. SPI Benefits • No static initialization • Automatic lookup in all Jars • Everything is initialized in one place
  • 44. Annotation Scanning • Mark extensions with custom annotations • Use bytecode scanning library @Extension
  • 45. final TypeReporter reporter = new TypeReporter() {! ! @Override! public Class<? extends Annotation>[] annotations() {! return new Class[]{Extension.class};! }! ! @Override! public void reportTypeAnnotation(Class<? extends Annotation> annotation, String className) {! // do something! }! ! };! final AnnotationDetector cf = new AnnotationDetector(reporter);! cf.detect(); @Extension! class MyExtensionPlugin implements Plugin {! @Override! void init(Context context) {! System.out.println(“Hello”);! }! } Finds all annotated classess https://github.com/rmuller/infomas-asl
  • 46. Annotation Benefits • Instantiating and using via reflection • Easy API to explain • Quite fast
  • 48. List<String> myList = new ArrayList<>();! updateList(myList);! return myList; void updateList(List<String> items) {! for (Iterator<String> iterator=items.iterator(); iterator.hasNext();) {! String item = iterator.next() {! if (item.startsWith(“//”)) {! iterator.remove();! }! }! } Modifying mutable parameters
  • 49. List<Item> myList = new ArrayList<>();! List<Item> updatedList = updateItems(myList);! return updatedList; List<String> updateList(final List<String> items) {! List<String> result = new ArrayList<>();! for (String item : items) {! if (!item.startsWith(“//”)) {! result.add(item);! }! }! return result;! } Considering all method arguments as immutable
  • 50. try {! downloadPhoto(id, path);! } catch(ConnectionNotAvailable | PhotoNotFound e) {! System.out.println(“WAT!?”);! } void downloadPhoto(String id, Path path) ! throws ConnectionNotAvailable, PhotoNotFound {! ...! } Have to handle all exceptions
  • 51. downloadPhoto(id, path); void downloadPhoto(String id, Path path) {! ...! } Rely on Runtime Exceptions
  • 52. void uploadPhoto(byte[] photo, String name, String type) {! ...! } What if photo is too big? What types are supported? RTFM?
  • 53. void uploadPhoto(InputStream photo,! String name, ! PhotoType type) {! ...! }! ! public enum PhotoType {! JPEG, PNG! } Pass binaries as InputStreams Create enum for parameters
  • 54. PhotoService photoService = ...! photoService.openTransaction();! try {! photoService.uploadPhoto(...);! photoService.changeAttributes(...);! } catch (Exception e) {! photoService.rollbackTransaction();! } finally {! photoService.commitTransaction();! } Just boring...
  • 55. PhotoService photoService = ...! photoService.doInTransaction(new Execution() {! public void work(Context context) {! context.uploadPhoto(...);! context.changeAttributes(...);! }! });! ! public void doInTransaction(Execution execution) {! Context context = openTransactionContext();! try {! execution.work(context);! } catch (Exception e) {! context.rollback();! } finally {! context.commit();! }! } Writing it once
  • 56. PhotoService photoService = ...! photoService.doInTransaction(context -> {! context.uploadPhoto(...);! context.changeAttributes(...);! }); Java 8
  • 57. public Object someServiceMethod() {! return transactionTemplate.execute(new TransactionCallback() {! ! // the code in this method executes in a transactional context! public Object doInTransaction(TransactionStatus status) {! updateOperation1();! return resultOfUpdateOperation2();! }! });! } Same approach in Spring Framework
  • 59. All APIs operate on single set of rules & patterns
  • 60. APIs have fashion too Java API from 1998 Java API from 2013
  • 61. You have to follow fashion trends to ride APIs
  • 62. • Treat all reusable classes you write as API • Use minimum API principle • Learn by example from open source projects