次のような二つのクラスを考えます。
public class WithAccessTokenSecurityContextFactory implements WithSecurityContextFactory<WithAccessToken> { @Override public SecurityContext createSecurityContext(final WithAccessToken annotation) { final SecurityContext context = SecurityContextHolder.createEmptyContext(); final GivenAccessToken accessToken = new GivenAccessToken(annotation); final AccessTokenEntity accessTokenEntity = accessToken.accessTokenEntity(); // ここから final Authentication authentication = new Authentication(accessTokenEntity); final OAuth2Authentication oauth2 = authentication.oauth2(); // ここまでを一つにまとめたい context.setAuthentication(oauth2); return context; } }
class GivenAccessToken { GivenAccessToken(final WithAccessToken accessToken) { // 省略 } AccessTokenEntity accessTokenEntity() { // 省略 } }
このように7行もあるメソッドは長すぎるし、利用するクラスが実装を知りすぎているので、一つにまとめて見通しを良くしたいところです。
1. メソッドの抽出
最初に WithAccessTokenSecurityContextFactory
の内部に private メソッドとして抽出します。
- コード内で「ここから」〜「ここまで」とした範囲を選択する
- Refactor > Extract > Method を選択する。あるいは
⌘
+⌥
+M
を押す
- ダイアログでメソッドの可視性、型、メソッド名、パラメーターを確認してメソッドの抽出を実行
抽出が完了したら次のような形になります。
public class WithAccessTokenSecurityContextFactory implements WithSecurityContextFactory<WithAccessToken> { @Override public SecurityContext createSecurityContext(final WithAccessToken annotation) { final SecurityContext context = SecurityContextHolder.createEmptyContext(); final GivenAccessToken accessToken = new GivenAccessToken(annotation); final OAuth2Authentication oauth2 = oauth2(accessToken); context.setAuthentication(oauth2); return context; } private OAuth2Authentication oauth2(final GivenAccessToken accessToken) { final AccessTokenEntity accessTokenEntity = accessToken.accessTokenEntity(); final Authentication authentication = new Authentication(accessTokenEntity); return authentication.oauth2(); } }
2. メソッドの別クラスへの移動
抽出したメソッドおよび抽出されたメソッドは短くなりますが、今のままだと WithAccessTokenSecurityContextFactory
が GivenAccessToken
や OAuth2Authentication
の内部実装を知りすぎています。このような操作は GivenAccessToken
が抑えておけばよい内容です。したがって、 oauth2
メソッドを GivenAccessToken
に移動します。
oauth2
メソッドにカーソルをあわせる- Refactor > Move を選択する。あるいは
F6
- ダイアログで移動先のクラスを選択して移動を実行
移動完了後は次のようになっている
public class WithAccessTokenSecurityContextFactory implements WithSecurityContextFactory<WithAccessToken> { @Override public SecurityContext createSecurityContext(final WithAccessToken annotation) { final SecurityContext context = SecurityContextHolder.createEmptyContext(); final GivenAccessToken accessToken = new GivenAccessToken(annotation); final OAuth2Authentication oauth2 = accessToken.oauth2(); context.setAuthentication(oauth2); return context; } }
class GivenAccessToken { GivenAccessToken(final WithAccessToken accessToken) { // 省略 } AccessTokenEntity accessTokenEntity() { // 省略 } private OAuth2Authentication oauth2() { final AccessTokenEntity accessTokenEntity = accessTokenEntity(); final Authentication authentication = new Authentication(accessTokenEntity); return authentication.oauth2(); } }
privateメソッドに一度抽出しているが、これを飛ばしてメソッド抽出+メソッドを別クラスへ移動することはできない(っぽい)