デザインモードノートの15(解釈器モード)

10036 ワード

インタプリタモード
解釈器モードは言語を定義し、その言語を定義する解釈器であり、解釈器は定義された文法に従ってこの言語を使用者が理解できる言語に「翻訳」することができる.
広く言えば、Javaは定義された言語であり、JVMは「解釈器」であり、コンピュータは最終的な使用者である.Javaコードを書きますが、コンピュータは0101のマシン言語しか認識していません.JVMはJavaコードを0101のマシン言語と解釈してコンピュータが理解して実行できるようにします.
私たちはやはり私たちの実験室の例でこのモデルを説明します.
 
最近、私たちの実験室の獣人工場は社長の指示をもらいました.
class LaoZong {
    private String order = "MN1n2";

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }
    
}

class ShouRenFactory {
    public void readOrder() {
        LaoZong lz = new LaoZong();
        System.out.println(lz.getOrder());
    }
}

public class Interpreter {
    public static void main(String[] args) {
        new ShouRenFactory().readOrder();
    }
}

 そこで獣人工場がオーナーから指示を受けたのが「MN 1 n 2」.何をするのか全く分からないので、社長秘書に説明しなければなりません.
class ShouRenFactory {
    public void readOrder() {
        LaoZong lz = new LaoZong();
        MiShu ms = new MiShu();
        
        System.out.println(ms.translate(lz.getOrder()));
    }
}

class MiShu {
    public String translate(String order) {
        //Black Box
        String realWord = "     1    2 ";
        return realWord;
    } 
}

今私达の獣人工场はついに老総の命令を知っています:“男の獣人の1人の女の獣人の2人を生产します”、しかし秘书はどのように老総の命令を知っていて、もし獣人工场も秘书の解析の过程を知っているならば、それでは毎回すべて秘书に说明するように面倒をかける必要はありません.結局秘書は獣人工場ではなく社長が使っています.
秘書の解析方法を教えてください.
秘書はまず各字幕や配列がどのようなタイプの命令なのかを判断し、それから異なる解釈方法で異なるタイプを説明し、例えば「M」は命令類であり、「Nn」は製品名類であり、数字は数量類であると言った.
そこで獣人工場は秘書の方法によって自分の解析方式を実現した.
public class Interpreter {
    public static void main(String[] args) {
        new ShouRenFactory().readOrder();
    }
}

class ShouRenFactory {
    private String translate(String order) {
        String realOrder = "";
        
        //     
        List<Expression> expressions = new ArrayList<Expression>();
        expressions.add(new CommandExpression());
        expressions.add(new ProductExpression());
        expressions.add(new NumberExpression());
        
        //         
        String[] codes = order.split("");
        for (String code :codes) {
            for (Expression expression : expressions) {
                if (expression.matches(code)) {
                    realOrder += expression.excute(code);
                    break;
                }
            }
        }
        
        return realOrder;
    }
    public void readOrder() {
        LaoZong lz = new LaoZong();

        System.out.println(translate(lz.getOrder()));
    }
}

abstract class Expression {
    protected HashMap<String, String> map = new HashMap<String, String>();

    private Set<String> getMarkers() {
        return map.keySet();
    }

    public boolean matches(String code) {
        return getMarkers().contains(code);
    }

    abstract public String excute(String code);
}

class CommandExpression extends Expression {

    public CommandExpression() {
        map.put("M", "  ");
        map.put("D", "  ");
        map.put("E", "  ");
    }

    @Override
    public String excute(String code) {
        return map.get(code);
    }
}

class ProductExpression extends Expression {

    public ProductExpression() {
        map.put("N", "   ");
        map.put("n", "   ");
    }

    @Override
    public String excute(String code) {
        return map.get(code);
    }
}

class NumberExpression extends Expression {

    public NumberExpression() {
    }

    @Override
    public boolean matches(String code) {
        return code.matches("[0-9]");
    }
    
    @Override
    public String excute(String code) {
        return code + " ";
    }
}

これにより,ある解析器を簡単に追加または削除できる簡単な解析器モードを実現した.
 
 
解析器モードは、理解しやすいが適用しにくいモードである.「特定のタイプの問題が発生する頻度が十分に高い」場合を除き、このモードは推奨されません.文法が特に複雑な場合、多くのクラスが発生するため、メンテナンスには困難です.総じて文法が簡単で発生頻度が高い場合に使用します.