zoukankan      html  css  js  c++  java
  • 003 工厂方法模式

    一 .说一说

    在简单工厂之中,我们的最终演化的过程中,有一个很烦的问题就是当增加产品的时候,我们的枚举类会不断的修改.

    虽然修改在一定程度上我们能保证不出问题,但这依然不够优雅.


    二 .工厂演进

    提供一个生产枪的工厂接口.

    public interface GunFactory {
        Gun productGun();
    }

    子类:

    public class AK47GunFactory implements GunFactory {
        @Override
        public Gun productGun() {
            return new AK47();
        }
    }
    public class B11GunFactory implements GunFactory{
        @Override
        public Gun productGun() {
            return new B11();
        }
    }

    客户端:

    public static void main(String[] args) {
            Gun gun = new AK47GunFactory().productGun();
            gun.shot();
        }

    现在我们如果要扩展枪的话,就可以扩展工厂和对应的枪了.

    我们能够保证代码符合开闭原则的.


    问题的出现:

    每次出现新枪,客户端虽然代码不用变化,但是客户端在一定程度上需要知道自己需要什么样的枪工厂.

    我们来回忆一下使用工厂的好处,就是获得创建对象时细节的控制权.

    从这一点上讲,使用工厂比直接使用构造函数好.

    这就是我们使用工厂最直接的原因.[可以获得创建对象细节的权利].


    看下面的情景:

    我需要使用枪来打鸟.

    public abstract class  ShotBird {
        protected abstract Gun getGun() ;
        public void shotBird() {
            getGun().shot();
            System.out.println("鸟被打死了!!");
        }
    }

    现在我们需要使用ak47打鸟.

    public class Ak47ShotBird extends ShotBird {
        @Override
        protected Gun getGun() {
            return new AK47();
        }
    }

    客户端:

    public static void main(String[] args) {
            ShotBird shot = new Ak47ShotBird();
            shot.shotBird();
        }

    我们每次选用不同的枪来打鸟,只需要实现以下工厂方法就好了.有了枪,怎么打鸟的代码就可以复用了.

    这也就是说,我们除了创建枪的代码不能复用,其它的代码都能复用.


    工厂方法模式:

    定义定义创建对象的方法[对象--一般以接口的形式表示],让子类完成该方法.父类可以将其他代码进行复用.

    也就是说,工厂方法模式创建的对象一般不是给客户端使用的,是给父类的内部代码使用的.


    现在由一个情景:

    用户的登录过程:

    public abstract class Login {
        //获得一个匹配器
        protected abstract Matcher getMatcher();
        //实现登录
        public boolean login(String username , String password) {
            Matcher matcher = getMatcher();
            return matcher.check(username,password);
        }
    }

    现在登录的方式有很多,比如使用MD5加密之后再登录.

    //匹配器
    public interface Matcher {
        //通过账号和密码进行匹配
        Boolean check(String username, String password);
    }
    public class MD5Matcher implements Matcher {
        @Override
        public Boolean check(String username, String password) {
            System.out.println("通过账号"+username +"和密码"+password +"进行验证");
            //省略大量验证代码
            return Boolean.TRUE;
        }
    }

    实现一个MD5登录.

    public class MD5Login extends Login {
        @Override
        protected Matcher getMatcher() {
            return new MD5Matcher();
        }
    }

    客户端代码:

        public static void main(String[] args) {
            Login login = new MD5Login();
            login.login("trek", "123456");
        }

    通过上面的例子,我们现在应该能理解工厂方法模式了.

    工厂方法模式创建的对象一般都是给内部使用的,目的是为了复用其它的代码,比如登录登录时可以记录日志啊等操作.

    从这一点上讲,和简单工厂根本不是一个方向上的模式.

    我看了一些资料,觉的那些资料上应该是片面的理解了这个模式.

    最终我是按照淹没设计模式的方向去理解这个模式的.


  • 相关阅读:
    生活
    通俗易懂----尾递归
    。。。
    调用startActivityForResult,onActivityResult无响应的解决办法
    安卓官方ViewPager与android.support.design.widget.TabLayout双向交互联动切换 。
    1、面向对象以及winform的简单运用(开篇)
    15、C#基础整理(递归)
    14、C#基础整理(函数)
    13、C#基础整理(枚举)
    12、C#基础整理(结构体)
  • 原文地址:https://www.cnblogs.com/trekxu/p/8595051.html
Copyright © 2011-2022 走看看