一 .说一说
在简单工厂之中,我们的最终演化的过程中,有一个很烦的问题就是当增加产品的时候,我们的枚举类会不断的修改.
虽然修改在一定程度上我们能保证不出问题,但这依然不够优雅.
二 .工厂演进
提供一个生产枪的工厂接口.
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"); }
通过上面的例子,我们现在应该能理解工厂方法模式了.
工厂方法模式创建的对象一般都是给内部使用的,目的是为了复用其它的代码,比如登录登录时可以记录日志啊等操作.
从这一点上讲,和简单工厂根本不是一个方向上的模式.
我看了一些资料,觉的那些资料上应该是片面的理解了这个模式.
最终我是按照淹没设计模式的方向去理解这个模式的.