Designing
Auto Generated Codes
17 Nov 2015 Roppongi.aar #2
@kikuchy
• Hiroshi Kikuchi (@kikuchy)
• Belonging to , inc , Working on , inc (mixi group)
• Making Dating App for Android
• Strict review OJISAN
Who am I
APT made our work
reduced!!
So, you use APT,
and be happy!!
\\٩( 'ω' )‫و‬ ////
… I was going to talk about
like that, but
Oh, you are already using
APT.
fin.
\(^o^)/
So, I ll talk about
Designing
Auto Generated Codes
What is the best way to use
Generated Code in our project?
Please consider and discuss.
The Problem
Make Us Wakeful
Case 1 (/2)
If you make an awesome library
hiding generated codes…
// Fields
@ExecuteSomething
String foo;
// Executor class “ThisClass$$Executor” is
generated.
// My library loads executor class automatically!
AwesomeLibrary.execute(this);
Alice changes Naming Rule
of Generated Class.
ex) (ClassName)$$Executor -> (ClassName)$$Doer
proguard-rules.pro ????
< Hey, I obfuscated your code!
Proguard
@ Production Build
Case 2 (/2)
If you make awesome proguard-safe library…
// Fields
@ExecuteSomething
String foo;
// Executor class “ThisClassExecutor” is
generated.
// There are no reflection, no
ClassNotFoundException!!
new ThisClassExecutor().execute(this);
Bob often asks you
What s the name of Generated Classes and methods and constructor arguments and
interfaces will use in Generated Code blablabla…
Why ask me repeatedly ?
Why I have to remember
invisible codes?
Bob
<
https://www.flickr.com/photos/greeblie/2190709020/
 / / / /    / |  /    `、 i  !  |i   i  ,  l
  / / //   /   | /       | |  |  l !  i  |  |
`/ー- 、 / /    | /       | l   |  l l  !  !  i
/ ,,,,- ニ=x- 、_   !/       |i  _, +十'イ  i  !  !
''" / :;;r jヽ ` ̄  リ      ,, -=、 レ | / /  :|
 /:::::;;;;;;;:`::::::l          / :;;r ヽヽ   |/| /   :!
 |::::::::;;;;;;;;:::::::l             l:::;;;;;` ::| l  //    :!
  '、:_ ''''  ノ          l  '''' ノ |  /    :|
::::::::..  ̄               ` ー '   ,'      :|
::::::::::::            ,    ..::::::::::::..l  .:|   :|
::::::::::                :::::::::::::::::::|  :|   :| Mmmm…
                    ::::::::::::::: l .:|  l  :|
                         /  :| :l  :|
                      , '   :::| :|  :|
` 、     ⊂ニ==ー‐-     , イ    ::::| :|  :|
hiding generated codes
no reflection
vs
Butter Knife pattern
Dagger2 pattern
vs
Compare patterns
Butter Knife pattern
(hiding generated codes)
Dagger2 pattern

(no reflection)
How to load generated
codes
Library dose everything Developers have to import
Proguard configuration is needed not needed
Developers have to learn only usage of library
+ generated class naming
rules
Type-Safe No Yes
Which we should adopt?
case by case
My Recommend:
Dagger2 pattern
Don’t forget
proguard conf?
Start
↓
Like beautiful
API?
Is not solidity
app necessary?
→ →
Yes
No↓
“Dagger2” pattern
→
No
Yes
↓ No↓
“Dagger2” pattern “Dagger2” pattern
“Butter
Knife”
pattern
Yes
No proguard,
and save the team
https://www.flickr.com/photos/katrinasagemuller/3751402009/
Appendix 1:
Auto code generation patterns
• Java Annotated Source Codes
• Using APT.
• ex) Dagger2, ButterKinfe, JsonPullParser, etc…
• Externals
• Gradle Task (depends on compileJava task)
• ex ) R.java, genum (← I m developing now!!!!!!!!!!!)
Source of Source Codes
Generated Class Depends on…
• Only Interface
• MyOwnInterface instance = new GeneratedClass();
• ex) Dagger2, (Retrofit)
• Library Classes
• LibrarySuppliedBase instance = new GeneratedClass();
• ex) Shillelagh, etc…
• Nope ¦¦ Unknown
• (Generated classes are hidden.)
• ex) ButterKnife, IntentBuilder, DeepLinkDispatch
Appendix 2:
Episode
POJO
↓
Map<String, String>
https://www.flickr.com/photos/yoshimov/10256644/
public class UserSearchRequest {
public EnumSet<UserKind> kind;
public String freeWord;
public int ageMax;
…
}
@ToQueryMap
public class UserSearchRequest {
@QueryParam(name = “kind”,
adapter = UserKindAdapter.class)
public EnumSet<UserKind> kind;
@QueryParam(name = “free_word”,
adapter = StringAdapter.class)
public String freeWord;
@QueryParam(name = “age_max”,
adapter = IntAdapter.class)
public int ageMax;
…
public final class UserSearchRequestSerializer {
public Map<String, String>
serialize(UserSearchRequest request) {
Map<String, String> map = new Map<>();
map.put(“kind”,
userKindAdapter.adapt(request.kind));
map.put(“free_word”,
stringAdapter.adapt(request.freeWord));
map.put(“age_max”,
intAdapter.adapt(request.ageMax));
…
return map;
}
GENERATED
Yheaaaaaaaa
\\٩( 'ω' )‫و‬ ////
Thank you for listening!
Question?
@kikuchy

Designing Auto Generated Codes

  • 1.
    Designing Auto Generated Codes 17Nov 2015 Roppongi.aar #2 @kikuchy
  • 2.
    • Hiroshi Kikuchi(@kikuchy) • Belonging to , inc , Working on , inc (mixi group) • Making Dating App for Android • Strict review OJISAN Who am I
  • 3.
    APT made ourwork reduced!! So, you use APT, and be happy!! \\٩( 'ω' )‫و‬ ////
  • 4.
    … I wasgoing to talk about like that, but
  • 7.
    Oh, you arealready using APT.
  • 8.
  • 9.
  • 10.
    So, I lltalk about
  • 11.
  • 12.
    What is thebest way to use Generated Code in our project? Please consider and discuss.
  • 13.
  • 14.
  • 15.
    If you makean awesome library hiding generated codes… // Fields @ExecuteSomething String foo; // Executor class “ThisClass$$Executor” is generated. // My library loads executor class automatically! AwesomeLibrary.execute(this);
  • 16.
    Alice changes NamingRule of Generated Class. ex) (ClassName)$$Executor -> (ClassName)$$Doer
  • 17.
  • 18.
    < Hey, Iobfuscated your code! Proguard @ Production Build
  • 22.
  • 23.
    If you makeawesome proguard-safe library… // Fields @ExecuteSomething String foo; // Executor class “ThisClassExecutor” is generated. // There are no reflection, no ClassNotFoundException!! new ThisClassExecutor().execute(this);
  • 24.
    Bob often asksyou What s the name of Generated Classes and methods and constructor arguments and interfaces will use in Generated Code blablabla…
  • 25.
    Why ask merepeatedly ? Why I have to remember invisible codes? Bob < https://www.flickr.com/photos/greeblie/2190709020/
  • 26.
     / / / /   / |  /    `、 i  !  |i   i  ,  l   / / //   /   | /       | |  |  l !  i  |  | `/ー- 、 / /    | /       | l   |  l l  !  !  i / ,,,,- ニ=x- 、_   !/       |i  _, +十'イ  i  !  ! ''" / :;;r jヽ ` ̄  リ      ,, -=、 レ | / /  :|  /:::::;;;;;;;:`::::::l          / :;;r ヽヽ   |/| /   :!  |::::::::;;;;;;;;:::::::l             l:::;;;;;` ::| l  //    :!   '、:_ ''''  ノ          l  '''' ノ |  /    :| ::::::::..  ̄               ` ー '   ,'      :| ::::::::::::            ,    ..::::::::::::..l  .:|   :| ::::::::::                :::::::::::::::::::|  :|   :| Mmmm…                     ::::::::::::::: l .:|  l  :|                          /  :| :l  :|                       , '   :::| :|  :| ` 、     ⊂ニ==ー‐-     , イ    ::::| :|  :|
  • 27.
  • 28.
  • 29.
    Compare patterns Butter Knifepattern (hiding generated codes) Dagger2 pattern
 (no reflection) How to load generated codes Library dose everything Developers have to import Proguard configuration is needed not needed Developers have to learn only usage of library + generated class naming rules Type-Safe No Yes
  • 30.
  • 31.
  • 32.
  • 33.
    Don’t forget proguard conf? Start ↓ Likebeautiful API? Is not solidity app necessary? → → Yes No↓ “Dagger2” pattern → No Yes ↓ No↓ “Dagger2” pattern “Dagger2” pattern “Butter Knife” pattern Yes
  • 34.
  • 35.
  • 36.
    Appendix 1: Auto codegeneration patterns
  • 37.
    • Java AnnotatedSource Codes • Using APT. • ex) Dagger2, ButterKinfe, JsonPullParser, etc… • Externals • Gradle Task (depends on compileJava task) • ex ) R.java, genum (← I m developing now!!!!!!!!!!!) Source of Source Codes
  • 38.
    Generated Class Dependson… • Only Interface • MyOwnInterface instance = new GeneratedClass(); • ex) Dagger2, (Retrofit) • Library Classes • LibrarySuppliedBase instance = new GeneratedClass(); • ex) Shillelagh, etc… • Nope ¦¦ Unknown • (Generated classes are hidden.) • ex) ButterKnife, IntentBuilder, DeepLinkDispatch
  • 39.
  • 40.
  • 42.
  • 43.
    public class UserSearchRequest{ public EnumSet<UserKind> kind; public String freeWord; public int ageMax; … }
  • 44.
    @ToQueryMap public class UserSearchRequest{ @QueryParam(name = “kind”, adapter = UserKindAdapter.class) public EnumSet<UserKind> kind; @QueryParam(name = “free_word”, adapter = StringAdapter.class) public String freeWord; @QueryParam(name = “age_max”, adapter = IntAdapter.class) public int ageMax; …
  • 45.
    public final classUserSearchRequestSerializer { public Map<String, String> serialize(UserSearchRequest request) { Map<String, String> map = new Map<>(); map.put(“kind”, userKindAdapter.adapt(request.kind)); map.put(“free_word”, stringAdapter.adapt(request.freeWord)); map.put(“age_max”, intAdapter.adapt(request.ageMax)); … return map; } GENERATED
  • 46.
  • 47.
    Thank you forlistening!
  • 48.
  • 49.