[オブジェクト向けプログラミング入門]機能と責任の分離
きのうぶんかい
誰が機能を提供しますか?
-切断された各機能を正しく割り当てます.
サブ機能の使用
public class ChangePasswordService {
public Result changePassword(String id, String oldPw, String newPw) {
Member mem = memeberRepository.findOne(id);
if(mem == null){
return Result.NO_MEMBER;
}
try {
mem.changePassword(oldPw, newPw);
return Result.SUCCESS;
} catch(BadPasswordException ex){
return Result.BAD_PASSWORD;
}
}
}
上記のコードから見ると、MemebeRepository
とMember
はそれぞれの機能を提供している.大類、大法
いくつかの責任配分/分離方法
アレイの適用
ぶんりけいさんきのう
上記の計算部分を新しいクラスに分割する実装方法
れんどうぶんり
条件分岐は抽象的である
注意:明確な意図のある名前を使用する
ロールの分離とテスト
ただし,右側のように切り離すと,PointCalculatorのみが単独でテストできる.
分離練習
分離練習1
public class CashClient {
private SecretKeySpec keySpec;
private IvParamterSpec ivSpec;
private Res post(Req req){
String reqBody = toJson(req);
Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
String encReqBody = new String(Base64.getEncoder().encode(chipher.doFinal(reqBody)));
ResponseEntity<String> responseEntity = restTemplate.postForEntity(api, encReqBody, String.class);
String encRespBody = responseEntity.getBody();
Cipher cipher2 = Cipher.getInstance(DEFAULT_TRANSFORM);
cipher2.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
String respBody = new String(chipher2.doFinal(Base64.getDecoder().decode(encRespBody)));
return jsonToObj(respBody);
}
}
上記コードでは、Cipherにより暗号化と復号化(計算機能)を分離することができる.分離は以下の通りです.
public class CashClient {
private Cryptor cryptor;
private Res post(Req req){
String reqBody = toJson(req);
String encReqBody = cryptor.encrypt(reqBody);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(api, encReqBody, String.class);
String encRespBody = responseEntity.getBody();
String respBody = cryptor.decrypt(encRespBody);
return jsonToObj(respBody);
}
}
public class Cryptor {
private SecretKeySpec keySpec;
private IvParamterSpec ivSpec;
public String encrypt(String plain){
Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
return new String(Base64.getEncoder().encode(chipher.doFinal(reqBody)));
}
public String decrypt(String encrypted){
Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORM);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
return new String(chipher.doFinal(Base64.getDecoder().decode(encRespBody)));
}
}
分離練習2
public class Rental {
private Movie movie;
private int daysRented;
public int getFrequentRenterPoints(){
if(movie.getPriceCode() == Movie.NEW_RELEASE && daysRented > 1 ){
return 2;
}
return 1;
}
}
public class Movie {
public static int REGULAR = 0;
public static int NEW_RELEASE = 1;
private int priceCode;
public int getPriceCode(){
return priceCode;
}
}
抽象的に上記コードの条件分岐を以下のように分離する.public class Rental {
private Movie movie;
private int daysRented;
public int getFrequentRenterPoints(){
return movie.getFrequentRenterPoints(daysRented);
}
}
public abstract class Movie {
public abstract int FrequentRenterPoints(int daysRented);
}
public class NewRelaseMovie extends Movie {
public int FrequentRenterPoints(int daysRented){
return daysRented > 1 ? 2 : 1;
}
}
public class RegularMovie extends Movie {
public int FrequentRenterPoints(int daysRented){
return 1;
}
}
以上のようにMovieをサブクラスとして抽象化して分離する.分離練習3
-ユーザーが電子メール、名前、パスワードを入力します.
-すべて必須
-パスワードが次のルールを満たしていない場合は、再入力してください.
-ルール1、ルール2、ルール3...
-同じEメールで登録されているメンバーがいる場合は、再入力してください.
-電子メール認証用にメールを送信
-暗号化タグを使用して検証
-会員登録済み
実際に、機能を別々に設計すると、以下のようになります.
Reference
この問題について([オブジェクト向けプログラミング入門]機能と責任の分離), 我々は、より多くの情報をここで見つけました https://velog.io/@kshired/객체-지향-프로그래밍-입문-기능과-책임-분리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol