工厂模式
工厂模式专门负责实例化有大量公共接口的类。工厂模式可以动态的决定将哪一个类实例化,而不必事先知道每次要实例化哪一个类。客户类和工厂类是分开的。消费者无论什么时候需要某种产品,需要做的只是向工厂提出请求即可。消费者无须修改就可以接纳新产品。当然也存在缺点,就是当产品修改时,工厂类也要做相应的修改。
工厂模式包含以下几种形态:
简单工厂(Simple Factory)模式
简单工厂模式的工厂类是根据提供给它的参数,返回的是几个可能产品中的一个类的实例,通常情况下,它返回的类都有一个公共的父类和公共的方法。
例子:发邮件和发短信
(1)首先创建两者的共同接口
public interface Sender {
public void send();
}
(2)其次创建实现类
public class MailSender implements Sender {
@Override
public void send() {
System.out.println("This is a MailSender");
}
}
public class MessageSender implements Sender {
@Override
public void send() {
System.out.println("This is a MessageSender");
}
}
(3)最后创建工厂类
public class SendFactory {
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("message".equals(type)) {
return new MessageSender();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
测试
public class test {
public static void main(String[] args) {
SendFactory sf = new SendFactory();
Sender sender = sf.produce("mail");
sender.send();
}
}
输出结果为:This is a MailSender
工厂方法(Factory Method)模式
工厂方法模式是类的创建模式,其用意是定义一个用于创建产品对象的工厂的接口。它属于简单工厂模式的进一步抽象和推广。多态的使用,使得工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。
工厂模式适合:凡是出现了大量的产品需要创建,并且具有相同的接口时,可以通过工厂方法模式进行创建。一般会使用静态方法模式。
例子:发送短信和发送邮件
只需将工厂类进行如下修改
public class SendFactory {
public static Sender Mail(){
return new MailSender();
}
public static Sender Message(){
return new MessageSender();
}
}
测试
public class test {
public static void main(String[] args) {
Sender mail = SendFactory.Mail();
mail.send();
}
}
输出结果为:This is a MailSender
工厂方法模式的优缺点:
优点
①良好的封装性,代码结构清晰。一个对象创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名就可以了,不用知道创建对象的艰辛过程,减少模块间的耦合。
②工厂模式的扩展性非常优秀,在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类。
③屏蔽产品类,产品类的实现如何变化,调用者都不需要关心,只需关心产品的接口,只要接口保持不变,
缺点
工厂方法有一个问题就是类的创建依赖工厂类,也就是说,如果要拓展程序,必须对工厂类进行修改,这违背了闭包原则。这就引申出了抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就行。
抽象工厂(Abstract Factory)模式
抽象工厂模式是所有形态的工厂模式中最为抽象和最具有一般性的一种形态。抽象工厂模式是指当有多个抽象角色时使用的一种工厂模式,抽象工厂模式可以向客户端提供一个接口,是客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
例子还是发送邮件和短信:
(1)首先创建两者的共同接口(同上)
(2)其次创建实现类(同上)
(3)创建工厂类的接口
public interface Provider {
public Sender product();
}
(4)两个工厂的实现类
public class SendMailFactory implements Provider{
@Override
public Sender product() {
return new MailSender();
}
}
public class SendMessageFactory implements Provider{
@Override
public Sender product() {
return new MessageSender();
}
}
测试
public class test {
public static void main(String[] args) {
Provider provide = new SendMailFactory();
Sender sender = provide.product();
sender.send();
}
}
其实这个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好!
参考博客
[1] Java开发中的23种设计模式详解(转)
http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html