今天学习的设计模式是工厂模式。那么为什么叫它工厂模式呢?工厂模式,顾名思义就是用一个工厂生产各种东西,工厂模式是如何体现的呢?
首先,工厂模式有简单的工厂模式和抽象工厂模式两种,我们先用一个发型的工厂来演示一下简单的工厂模式:
一个发型接口:工厂模式是面向接口编程的,这样可以更易于程序的扩展
package com.sunny.project; /** * 发型接口 * @author Administrator * */ public interface HairInterface { /** * 画一个发型 */ public void draw(); }
写两个发型实现这个接口:
package com.sunny.project; /** * 左偏分发型 * @author Administrator * */ public class LeftHair implements HairInterface { @Override public void draw() { // TODO Auto-generated method stub System.out.println("-----------------左偏分发型-------------------"); } } package com.sunny.project; /** * 右偏分发型 * @author Administrator * */ public class RightHair implements HairInterface { @Override public void draw() { // TODO Auto-generated method stub System.out.println("-----------------右偏分发型-------------------"); } }
假若我们不使用工厂模式,那么我们一般就是new这两个对象进行我们的操作,但是这样是很不利于我们程序的管理的,因为这些发型都是属于发型接口的实现,我们能不能通过一个总的类来对这系列的发型进行产生实例呢?这个时候就是工厂模式的应用了,我们写一个专门生产发型的工厂类:
package com.sunny.project; import java.util.Map; /** * 发型工厂 * @author Administrator * */ public class HairFactory { /** * 根据类型来创建对象 * @param key * @return */ public HairInterface getHair(String key){ if("left".equals(key)){ return new LeftHair(); }else if("right".equals(key)){ return new RightHair(); } return null; } /** * 根据类的名称来生产对象 * @param className * @return */ public HairInterface getHairByClass(String className){ try { HairInterface hair = (HairInterface) Class.forName(className).newInstance(); return hair; } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } /** * 根据类的名称来生产对象 * @param className * @return */ public HairInterface getHairByClassKey(String key){ try { Map<String, String> map = PropertiesReader.getInstance().getProperties(); HairInterface hair = (HairInterface) Class.forName(map.get(key)).newInstance(); return hair; } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
这里我们提供了不同的方法生产,在我们的java程序中,有很多类的实现其实我们不需要在意细节,只需要提供创建他们的方法就可以(最后一个使用配置文件读取的)
配置文件如下type.properties:
left=com.sunny.project.LeftHair right=com.sunny.project.RightHair in=com.sunny.project.InHair
这样,我们的发型就由这个工厂来生产,我们只需要关注我们需要什么就可以了,这是测试类:
package com.sunny.project; public class SunnyTest { public static void main(String[] args){ // HairInterface left = new LeftHair(); // left.draw(); HairFactory factory = new HairFactory(); HairInterface right = factory.getHair("right"); right.draw(); HairInterface left = factory.getHairByClass("com.sunny.project.LeftHair"); left.draw(); HairInterface hair = factory.getHairByClassKey("left"); hair.draw(); } }
这就是简单工厂模式。
那么抽象工厂模式呢?
其实,抽象工厂模式和简单工厂模式的区别在于,抽象工厂可以产生多个产品族,我们的简单工厂是一个工厂类,我们的抽象工厂是一个接口,抽象工厂的好处就是可以让我们的程序在不同的扩展中实现更多的产品族,以实现更好的扩展。
那么在什么情况下需要应用我们的工厂模式呢?
1.一个系统不应该被创建不同的产品时的细节组成和几个所依赖,系统应该和这些实例的创建区分开让我们关注业务。
2.这个系统至少有一个产品的系列
3.同一个产品的系列是被设置成在一起使用的
4.不同的产品以一系列的接口面貌出现,从而使系统不依赖于接口实现的细节。
在我们的经常使用的java框架中,我们的jdbc就是利用工厂模式,jdbc只提供一个生产数据操作对象的工厂,不同的数据库只需要实现jdbc的统一的数据接口操作,我们的客户端只使用jdbc提供的这个工厂来获取操作数据库的实例,从而实现统一和灵活的使用。
同样,我们spring中的beanfactory也是这样,所有javabean都通过一个工厂来产生,我们只需要用一个get加上他的键名就可以得到实例,非常的简单易用。
版权声明:本文为博主原创文章,未经博主允许不得转载。