23种设计模式(2)-工厂模式

定义

        工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

        工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

 

工厂模式根据抽象程度的不同分为三种:

简单工厂模式(也叫静态工厂模式)

工厂方法模式(也叫多形性工厂)

抽象工厂模式(也叫工具箱)

 

简单工厂模式

        实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

举例如下:(我们举一个发送邮件和短信的例子)

首先,创建二者的共同接口:

public interface Sender {  
    public void Send();  
}  

其次,创建实现类:

public class MailSender implements Sender {
	@Override
	public void Send() {
		System.out.println("this is mailsender!");  
		
	}
}
public class SmsSender implements Sender {

	@Override
	public void Send() {
		System.out.println("this is sms sender!"); 
	}

}

最后,建工厂类:

public class SenderFactory {
	
   public Sender produce(String type) {  
        if ("mail".equals(type)) {  
            return new MailSender();  
        } else if ("sms".equals(type)) {  
            return new SmsSender();  
        } else {  
            System.out.println("请输入正确的类型!");  
            return null;  
        }  
    } 
    public static void main(String[] args) {
		SenderFactory factory = new SenderFactory();
		Sender produce = factory.produce("mail");
		produce.Send();
    }
}

工厂方法模式

        工厂方法是粒度很小的设计模式,因为模式的表现只是一个抽象的方法。 提前定义用于创建对象的接口,让子类决定实例化具体的某一个类,即在工厂和产品中间增加接口,工厂不再负责产品的创建,由接口针对不同条件返回具体的类实例,由具体类实例去实现。

首先,创建二者的共同接口:

public interface Sender {  
    public void Send();  
}  

其次,创建实现类:

public class MailSender implements Sender {
	@Override
	public void Send() {
		System.out.println("this is mailsender!");  
		
	}
}
public class SmsSender implements Sender {

	@Override
	public void Send() {
		System.out.println("this is sms sender!"); 
	}

}

最后,建工厂类:这里使用静态方法工厂  可以不用实例化工厂类

public class SenderFactory {

     public static Sender produceMail(){  

         return new MailSender();  
     }  
       
     public static Sender produceSms(){  
         return new SmsSender();  
     }  
     
     public static void main(String[] args) {
    	 SenderFactory.produceMail().Send();
    	 SenderFactory.produceSms().Send();
     }
}

抽象工厂模式

        工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。因为抽象工厂不太好理解,我们先看看图,然后就和代码,就比较容易理解。

 

 抽象的产品类

public interface Sender {  
    public void Send();  
} 

定义实际的产品类,总共定义两个

public class MailSender implements Sender {

	@Override
	public void Send() {
		System.out.println("this is mailsender!");  
	}
	
}

 

public class SmsSender implements Sender {

	@Override
	public void Send() {
		System.out.println("this is sms sender!"); 
	}

}

 

定义抽象的工厂接口

public interface IFactory {
   public Sender produce();
}

具体的工厂子类,分别为每个具体的产品类创建不同的工厂子类

public class SendMailFactory implements IFactory {  
      
    @Override  
    public Sender produce(){  
        return new MailSender();  
    }  
} 

 

public class SendSmsFactory implements IFactory{
	@Override
	public Sender produce() {
		return new SmsSender();
	}
}

简单的测试类,来验证不同的工厂能够产生不同的产品对象

 

public class Test {  
	  
    public static void main(String[] args) {  
        IFactory provider = null;
        //mail
        provider = new SendMailFactory();  
        Sender sender = provider.produce();  
        sender.Send();  
        //sms
        provider = new SendSmsFactory();
        Sender sender2 = provider.produce();
        sender2.Send();
    }  
} 

 

工厂模式的优点:

        1、一个调用者想创建一个对象,只要知道其名称就可以了,降低了耦合度。

        2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。使得代码结构更加清晰。

        3、屏蔽产品的具体实现,调用者只关心产品的接口。

 

工厂模式的缺点:

        每次增加一个产品时,都需要增加一个具体类和对象实现工厂(这里可以使用反射机制来避免),使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。所以对于简单对象来说,使用工厂模式反而增加了复杂度。

 

工厂模式的适用场景:

        1,  一个对象拥有很多子类。

        2,  创建某个对象时需要进行许多额外的操作。

        3,  系统后期需要经常扩展,它把对象实例化的任务交由实现类完成,扩展性好。

 

关于Java中的工厂模式的一些常见问题:

        利用父类的向下转型(使用父类类型的引用指向子类的对象)是可以达到类似于工厂模式的效果的,那为什么还要用工厂模式呢?

        把指向子类对象的父类引用赋给子类引用叫做向下转型,如:

 

Class Student extends Person     
Person s = new Student();    
s = (Student)person ;

 

        使用向下转型在客户端实例化子类的时候,严重依赖具体的子类的名字。当我们需要更改子类的构造方法的时候,比如增加一个参数,或者更改了子类的类名,所有的new出来的子类都需要跟着更改。   

        但如果我们使用工厂模式,我们仅仅需要在工厂中修改一下new的代码,其余项目中用到此实例的都会跟着改,而不需要我们手动去操作。

 

总结:

        无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。究竟用哪种设计模式更适合,这要根据具体的业务需求来决定。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值