14. Template Method模式代碼

    14. Template Method 本質:固定算法骨架
      14.1 實現應用系統的前臺和後臺的登錄控制
        public class LoginModel {
            private String loginId;
            private String password;
            public String getLoginId() {
                return loginId;
            }
            public void setLoginId(String loginId) {
                this.loginId = loginId;
            }
            public String getPassword() {
                return password;
            }
            public void setPassword(String password) {
                this.password = password;
            }
        }
        public abstract class LoginTemplate {
            public final boolean login(LoginModel lm) {
                LoginModel lmFromDb = this.findLoginUser(lm.getLoginId());
                if (lmFromDb != null) {
                    String encryptPwd = this.encryptPwd(lm.getPassword());
                    lm.setPassword(encryptPwd);
                    return this.match(lm, lmFromDb);
                }
                return false;
            }
            public boolean match(LoginModel lm, LoginModel lmFromDb) {
                if (lm.getLoginId().equals(lmFromDb.getLoginId()) && lm.getPassword().equals(lmFromDb.getPassword())) {
                    return true;
                }
                return false;
            }
            public String encryptPwd(String password) {
                return password;
            }
            public abstract LoginModel findLoginUser(String loginId);
        }
        public class NormalLogin extends LoginTemplate{
            @Override
            public LoginModel findLoginUser(String loginId) {
                LoginModel lm = new LoginModel();
                lm.setLoginId(loginId);
                lm.setPassword("normal");
                return lm;
            }
        }
        public class WorkerLogin extends LoginTemplate{
            @Override
            public LoginModel findLoginUser(String loginId) {
                LoginModel lm = new LoginModel();
                lm.setLoginId(loginId);
                lm.setPassword("worker");
                return lm;
            }
            public String encryptPwd(String pwd) {
                System.out.println("Encrypt using MD5");
                return pwd;
            }
        }
        public class TemplateClient {
            public static void main(String[] args) {
                LoginModel lm = new LoginModel();
                lm.setLoginId("admin");
                lm.setPassword("worker");
                LoginTemplate lt = new WorkerLogin();
                LoginTemplate lt2 = new NormalLogin();
                System.out.println("Login portal: " + lt2.login(lm));
                System.out.println("Login console: " + lt.login(lm));
            }
        }
        /**
         * 封裝進行登錄控制所需要的數據,在公共數據的基礎上,
         * 添加具體模塊需要的數據
         */
        public class NormalLoginModel extends LoginModel{
            /**
             * 密碼驗證問題
             */
            private String question;
            /**
             * 密碼驗證答案
             */
            private String answer;
            public String getQuestion() {
                return question;
            }
            public void setQuestion(String question) {
                this.question = question;
            }
            public String getAnswer() {
                return answer;
            }
            public void setAnswer(String answer) {
                this.answer = answer;
            }
        }
        /**
         * 普通用戶登錄控制加強版的邏輯處理
         */
        public class NormalLogin2 extends LoginTemplate{
            @Override
            public LoginModel findLoginUser(String loginId) {
                NormalLoginModel nlm = new NormalLoginModel();
                nlm.setLoginId(loginId);
                nlm.setPassword("normal");
                nlm.setQuestion("question");
                nlm.setAnswer("answer");
                return nlm;
            }
            public boolean match(LoginModel lm, LoginModel lmFromDb) {
                //這個方法需要覆蓋,因爲現在進行登錄控制的時候,
                //需要檢測4個值是否正確,而不僅僅是缺省的2個
                //先調用父類實現好的,檢測編號和密碼是否正確
                boolean isSuperMatch = super.match(lm, lmFromDb);
                if (isSuperMatch) {
                    //如果編號和密碼正確,繼續檢查問題和答案是否正確
                    //先把數據轉換成自己需要的數據
                    NormalLoginModel nlm = (NormalLoginModel)lm;
                    NormalLoginModel nlmFromDb = (NormalLoginModel)lmFromDb;
                    //檢查問題和答案是否正確
                    if (nlm.getQuestion().equals(nlmFromDb.getQuestion()) && nlm.getAnswer().equals(nlmFromDb.getAnswer())) {
                        return true;
                    }
                }
                return false;
            }
        }
        public class TemplateClient2 {
            public static void main(String[] args) {
                NormalLoginModel nlm = new NormalLoginModel();
                nlm.setLoginId("user");
                nlm.setPassword("normal");
                nlm.setQuestion("question");
                nlm.setAnswer("answer");
                LoginTemplate lt3 = new NormalLogin2();
                System.out.println("Login portal 2: " + lt3.login(nlm));
            }
        }
      14.2 重構時把相同的代碼抽取到父類中, 然後通過鉤子函數約束其行爲。
        public abstract class HummerModel {
            /*
              * 首先,這個模型要能夠被髮動起來,別管是手搖發動,還是電力發動,反正
              * 是要能夠發動起來,那這個實現要在實現類裏了
              */
            protected abstract void start();
            //能發動,那還要能停下來,那纔是真本事
            protected abstract void stop();
            //喇叭會出聲音,是滴滴叫,還是嗶嗶叫
            protected abstract void alarm();
            //引擎會轟隆隆的響,不響那是假的
            protected abstract void engineBoom();
            //那模型應該會跑吧,別管是人退的,還是電力驅動,總之要會跑
            final public void run() {
                //先發動汽車
                this.start();
                //引擎開始轟鳴
                this.engineBoom();
                //通過鉤子方法約束行爲:要讓它叫的就是就叫,喇嘛不想讓它響就不響
                if(this.isAlarm()){
                    this.alarm();
                }
                //到達目的地就停車
                this.stop();
            }
            //鉤子方法,默認喇叭是會響的
            protected  boolean isAlarm(){
                return true;
            }
        }
        public class HummerH1Model extends HummerModel {
            private boolean alarmFlag = true;  //是否要響喇叭
            @Override
            protected void alarm() {
                System.out.println("悍馬H1鳴笛...");
            }
            @Override
            protected void engineBoom() {
                System.out.println("悍馬H1引擎聲音是這樣在...");
            }
            @Override
            protected void start() {
                System.out.println("悍馬H1發動...");
            }
            @Override
            protected void stop() {
                System.out.println("悍馬H1停車...");
            }
            protected boolean isAlarm() {
                return this.alarmFlag;
            }
            //要不要響喇叭,是有客戶的來決定的
            public void setAlarm(boolean isAlarm){
                this.alarmFlag = isAlarm;
            }
        }
        public class HummerH2Model extends HummerModel {
            protected void alarm() {
                System.out.println("悍馬H2鳴笛...");
            }
            protected void engineBoom() {
                System.out.println("悍馬H2引擎聲音是這樣在...");
            }
            protected void start() {
                System.out.println("悍馬H2發動...");
            }
            protected void stop() {
                System.out.println("悍馬H2停車...");
            }
            //默認沒有喇叭的
            protected boolean isAlarm() {
                return false;
            }
        }
        public class Client {
            public static void main(String[] args) throws IOException {
                System.out.println("-------H1型號悍馬--------");
                System.out.println("H1型號的悍馬是否需要喇叭聲響?0-不需要   1-需要");
                String type=(new BufferedReader(new InputStreamReader(System.in))).readLine();
                HummerH1Model h1 = new HummerH1Model();
                if(type.equals("0")){
                    h1.setAlarm(false);
                }
                h1.run();
                System.out.println("\n-------H2型號悍馬--------");
                HummerH2Model h2 = new HummerH2Model();
                h2.run();
            }
        }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章