リファクタリングの実例1:第4回

Advertisement

残っている問題点

現在残っている問題点を以下に示す。
  • Productクラスの変数の型を変更した場合、Product・クライアント両方のコードを修正しなければならない。
  • クライアントからProductクラスを使用する際、毎回エラーチェック処理を記述しなければならない。
  • 複数のクライアントで、クライアントごとに異なるエラー判定ロジックを採用したい場合に適しているように見えるが、ロジックが変更になると、同じエラーチェックを行っているすべてのクライアントコードを修正しなければならない。
前回のりファクタリングで2番目の問題を解決した。3番目の問題も解決できたかと思えたが、「複数のクライアントでロジックの異なるエラーチェック処理を使う可能性がある」という要求を満たせなくなってしまっている。

修正版コード

Product クラス(変更点は強調文字で示す)
public class Product{
    private String name;
    private String teika;
    private Checker checker;

    public Product(String name, String teika, Checker checker){
        this.name = name;
        this.teika = teika;
        this.checker = checker;
    }

    public String getName(){
        return this.name;
    }

    public String getTeika(){
        return this.teika;
    }

    public boolean isError(){
        return checker.check(this);
    }
}

クライアント(変更点は強調文字で示す)
/**
 * 製品を利用するクラス
 */
public class Main{
    public static void main(String[] args){

        // 製品の作成
        Checker checker = new NormalChecker();
        Product product = new Product("name", "1000", checker);

        // エラー判定
        if(product.isError()){
            System.out.println("この製品は内部にエラーを含んでいます。");
        }else{
            System.out.println("この製品にエラーはありません。");
        }
    }
}

インタフェース Checker
public interface Checker {
    public boolean check(Product product);
}

クラス NormalChecker
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class NormalChecker implements Checker{

    /** 渡された Product のチェックを行う */
    public boolean check(Product product){
        boolean result;

        Pattern pattern = null;
        Matcher matcher = null;

        pattern = Pattern.compile("[A-Za-z0-9]+");
        matcher = pattern.matcher(product.getName());
        result = !matcher.matches();

        pattern = Pattern.compile("[0-9]+");
        matcher = pattern.matcher(product.getTeika());
        result = result | !matcher.matches();

        return result;
    }
}

実際の効果

エラーチェックを行うクラスを新たに定義して、複数のエラー処理ロジックに対応できるようにした。これで特別なエラーチェックを行う必要が発生した際にも、インタフェースCheckerを実装したクラスを作成することにより、Productクラスの内容を修正する必要がなくなった。

Advertisement

ショートカット

634トップページ
このカテゴリのトップページに戻る
634ラボ

サイト検索

Google

Web サイト内

Y!ログール