ポリシー・モード・インタフェースと抽象クラスの簡単な実装

14973 ワード

前にコードを書いたときに同じclassで内部インタフェースでいろいろな業務操作を実現している例を見て、珍しくて自分で書いてみました
自作自作は1つの買春賭博のシーンを導いた:仮に買春賭博の4つの操作をする時、すべて先にお金を稼いで、それから注文して、それから享受して、それから決済しなければなりません.お金を稼ぐという操作を除いて、飲み食いと賭博そのものとは独立して、共通性があり、点、品、結の3つの動作は異なるシーンで大きな違いがあるので、それぞれ異なる実現が必要です.
まず最も土の方法で実現する
public class CommonApproach {
    public void eat() {
        earn();
        orderForEat();
        enjoyForEat();
        checkoutForEat();
    }

    public void drink() {
        earn();
        orderForDrink();
        enjoyForDrink();
        checkoutForDrink();
    }

    public void prostitute() {
        earn();
        orderForProstitute();
        enjoyForProstitute();
        checkoutForProstitute();
    }

    public void gamble() {
        earn();
        orderForGamble();
        enjoyForGamble();
        checkoutForGamble();
    }

    private void earn() {
    }

    private void orderForEat() {
    }

    private void enjoyForEat() {
    }

    private void checkoutForEat() {
    }

    private void orderForDrink() {
    }

    private void enjoyForDrink() {
    }

    private void checkoutForDrink() {
    }

    private void orderForProstitute() {
    }

    private void enjoyForProstitute() {
    }

    private void checkoutForProstitute() {
    }

    private void orderForGamble() {
    }

    private void enjoyForGamble() {
    }

    private void checkoutForGamble() {
    }
}

明らかに煩わしくて、コードを書くことができないのは見ても面倒だと思います.では、abstractクラスの継承で実現してみましょう.ここではclassで完成することを要求しているので、プライベートな内部クラスでやってみましょう.
public class AbstractApproach {

    private DoEDPG behaviour;

    public void eat() {
        behaviour = new DoEDPG() {
            @Override
            protected void order() {
                JoePrint.print("order food");
            }

            @Override
            protected void enjoy() {
                JoePrint.print("enjoy the food");
            }

            @Override
            protected void checkout() {
                JoePrint.print("pay for the food");
            }
        };
        behaviour.earn();
        behaviour.order();
        behaviour.enjoy();
        behaviour.checkout();
    }

    public void drink() {
        behaviour = new DoEDPG() {
            @Override
            protected void order() {
                JoePrint.print("order drink");
            }

            @Override
            protected void enjoy() {
                JoePrint.print("enjoy liquid");
            }

            @Override
            protected void checkout() {
                JoePrint.print("pay for the liquid");
            }
        };
        behaviour.earn();
        behaviour.order();
        behaviour.enjoy();
        behaviour.checkout();
    }

    public void prostitute() {
        behaviour = new DoEDPG() {
            @Override
            protected void order() {
                JoePrint.print("order someone or several");
            }

            @Override
            protected void enjoy() {
                JoePrint.print("enjoy with him/her/them");
            }

            @Override
            protected void checkout() {
                JoePrint.print("pay for him/her/them");
            }
        };
        behaviour.earn();
        behaviour.order();
        behaviour.enjoy();
        behaviour.checkout();
    }

    public void gamble() {
        behaviour = new DoEDPG() {
            @Override
            protected void order() {
                JoePrint.print("order token");
            }

            @Override
            protected void enjoy() {
                JoePrint.print("gamble");
            }

            @Override
            protected void checkout() {
                JoePrint.print("checkout");
            }
        };
        behaviour.earn();
        behaviour.order();
        behaviour.enjoy();
        behaviour.checkout();
    }

    private abstract class DoEDPG {

        protected void earn() {
            JoePrint.print("earn money");
        }

        abstract protected void order();

        abstract protected void enjoy();

        abstract protected void checkout();
    }
}

そしてインタフェースで実現するのも、同じclassの内部で実現する最も簡潔な方法だと思います.
public class InterfaceApproach {

    public void eat() {
        doEDPG(new IDo() {
            @Override
            public void order() {
                JoePrint.print("order food");
            }

            @Override
            public void enjoy() {
                JoePrint.print("enjoy the food");
            }

            @Override
            public void checkout() {
                JoePrint.print("pay for the food");
            }
        });
    }

    public void drink() {
        doEDPG(new IDo() {
            @Override
            public void order() {
                JoePrint.print("order drink");
            }

            @Override
            public void enjoy() {
                JoePrint.print("enjoy liquid");
            }

            @Override
            public void checkout() {
                JoePrint.print("pay for the liquid");
            }
        });
    }

    public void prostitute() {
        doEDPG(new IDo() {
            @Override
            public void order() {
                JoePrint.print("order someone or several");
            }

            @Override
            public void enjoy() {
                JoePrint.print("enjoy with him/her/them");
            }

            @Override
            public void checkout() {
                JoePrint.print("pay for him/her/them");
            }
        });
    }

    public void gamble() {
        doEDPG(new IDo() {
            @Override
            public void order() {
                JoePrint.print("order token");
            }

            @Override
            public void enjoy() {
                JoePrint.print("gamble");
            }

            @Override
            public void checkout() {
                JoePrint.print("checkout");
            }
        });
    }

    private void doEDPG(IDo iDo) {
        earn();
        iDo.order();
        iDo.enjoy();
        iDo.checkout();
    }

    private void earn() {
        JoePrint.print("earn money");
    }

    private interface IDo {

        void order();

        void enjoy();

        void checkout();
    }

}

もちろんここで議論するシーンは狭くて、インタフェースと抽象的な方法の策略のモードの下での優劣の長さについて、後での仕事の中で引き続き体得する必要があります