前面的工厂方法模式虽然清晰,但还是感觉有些繁琐,通常使用的还是抽象工厂模式。
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
3.1创建发送接口
/** * 发送接口 * Created by mrf on 2016/2/25. */ public interface Sender { public String send(); }
3.2创建两个实现类
/** * 邮件发送 * Created by mrf on 2016/2/25. */ public class MailSender implements Sender { @Override public String send() { System.out.println("This is emailSender!"); return "email"; } } /** * 短信发送 * Created by mrf on 2016/2/25. */ public class SmsSender implements Sender { @Override public String send() { System.out.println("This is SmsSender!!"); return "sms"; } }
3.3创建抽象工厂
/** * 抽象工厂模式 * 消息发送提供者 * Created by mrf on 2016/2/26. */ public interface Provider { public Sender produce(); }
3.4创建两个工厂实现类
/** * Created by mrf on 2016/2/26. */ public class MailSendFactory implements Provider { @Override public Sender produce() { return new MailSender(); } } /** * Created by mrf on 2016/2/26. */ public class SmsSendFactory implements Provider { @Override public Sender produce() { return new SmsSender(); } }
3.5测试
/** * Created by mrf on 2016/2/26. */ public class ProviderTest { private Provider provider; @Test public void testMailProduce() throws Exception { provider = new MailSendFactory(); Sender sender = provider.produce(); assertEquals("email", sender.send()); } @Test public void testSmsProduce() throws Exception { provider = new SmsSendFactory(); Sender sender = provider.produce(); assertEquals("sms", sender.send()); } }
分析:
其实这个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好!
这里主要利用的原则是:上转型对象。就是父类可以调用子类继承或重写的方法。provider接口可以调用实现了这个接口的类的对应的方法,如果实现类定义了其他方法则无法调用。这里涉及java的基础知识。下面再分析下上转型对象。
3.6上转型对象
3.6.1定义
A为基类(可以为接口),B为子类或实现类。A a;a = new B();a就是上转型对象。
3.6.2特点
- 上转型对象不能操作子类新增加的成员变量,不能使用子类新增的方法。即为较子类B失去一些属性和功能,这些属性和功能是新增的。
- 上转型对象可以操作子类继承或隐藏的成员变量,也可以使用子类继承的或重写的方法。即为上转型对象可以操纵父类原有的属性和功能,无论这些方法是否被重写。
- 上转型对象调用方法时,就是调用子类继承和重写过的方法。而不会是新增的方法,也不是父类原有的方法。
- 可以将对象的上转型对象再强制转换到一个子类对象,强制转换过的对象具有子类所有属性和功能。
3.6.3注意
- 接口定义的权限都是public的,因为继承体系权限不可以缩小
- 将子类或实现类赋值给基类,基类只能操作基类本身和子类重写的东西
本文转自Ryan.Miao博客园博客,原文链接:http://www.cnblogs.com/woshimrf/p/5219799.html,如需转载请自行联系原作者