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();
            }
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值