从单例模式说起
单例模式的主要特点就是一个类的对象只能够由这个类本身产生所以它的构造器必须私有化。如果更加严格的话比如说这个类只能够产生一个特定的对象这样的话我们将会new一个静态的成员变量出来以下为代码:
package simplefactory; import java.util.ArrayList; import java.util.List; public class Car implements Moveable{ private static Car car = new Car(); public Car() {} public static Car getInstance() { return car;//这样的话无论如何都是调用的同一个car实现了真正的单例模式 } public void run() { System.out.println("嘀嘀开车去东北。。。。。"); } }
如果将上面的代码中的静态成员变量Car改成是一个装有Car的容器(比如说List)这样的设计也就成了多例。大家可以类比线程池的概念线程池里就是维护的一个容器容器里面装有数据库的链接。代码如下:
package simplefactory; import java.util.ArrayList; import java.util.List; public class Car implements Moveable{ private static List<Car> cars = new ArrayList<Car>();//这里面放了很多的车这也就是线程池的实现原理 public Car() {} public static List getCars() { return cars; } public void run() { System.out.println("嘀嘀开车去东北。。。。。"); } }
简单工厂
简单工厂的特点就是如果要用到某个类的实例的时候并不是new一个该类的对象出来而是将调用目标工厂类的方法new出我们想要的实例,示意图如下(以生产交通工具为例):
简单工厂的意义
看起来并没有什么卵用但是就像get和set方法一样与单独new一个对象出来它发生了本质的改变。我们可以在getVehicle方法中加入我们的控制,这一点是最关键的。
抽象工厂(一键换装的设计模式)
抽象工厂的应用比较广泛,它主要是能够灵活的替换一系列产品比如说更换主题一件换装。下面的就举一个例子可以灵活地实现甲系列产品到乙系列产品的更换,示例图如下所示:
模拟Spring的Bean工厂
Spring框架中的IOC控制反转使用的就是工厂模式,IOC本身的意思就是就是将new一个对象的控制权交给了Bean工厂。Bean产生一个对象的流程如下:
①首先我们本身要有自己JavaBean(我们想要产生的对象所属的类)
②我们将要产生的类配置到xml配置文件中。
③我们的Bean工厂要解析配置文件,将所有的要产生的Bean读取出来然后通过Java的反射机制将类实例化。
④将实例化的对象与其对应的id值存放到一个Map集合中。我们就可以通过这个Map容器拿到我们想要的对象。
模拟代码如下(需要导入dom4j的jar包)
JavaBean
package springfactory; import java.util.ArrayList; import java.util.List; public class Car implements Moveable{ private static Car car = new Car(); public Car() {} public void run() { System.out.println("嘀嘀开车去东北。。。。。"); } }
Bean的接口
package springfactory; public interface Moveable { void run(); }
Bean工厂的实现类
package springfactory; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; public class ClassPathXmlApplicationContext implements BeanFactory{ Map<String,Object> map = new HashMap<String,Object>(); //它要做的事情就是将xml中的内容读出来并且将读出来的一系列的Bean放到Map集合中 public ClassPathXmlApplicationContext(String filename) throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read(new File(filename)); Element root = document.getRootElement(); List<Element> beans = root.elements("bean");//拿到了第一个bean节点 产生对应关系的是map集合而不是我们就能够获取到,这个map集合就是bean工厂 for(Element bean : beans) { String name = bean.attribute("id").getValue(); String classname = bean.attribute("class").getValue(); Object o = Class.forName(classname).newInstance(); map.put(name, o); } } @Override public Object getBean(String id) { return map.get(id); } public static void main(String[] args) { try { new ClassPathXmlApplicationContext("src/applicationContext.xml"); } catch (Exception e) { e.printStackTrace(); } } }
Bean工厂接口
package springfactory; public interface BeanFactory { Object getBean(String id); }
applicationContext.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="v" class="springfactory.Broom" /> </beans>
Test测试类
package springfactory; import java.io.IOException; import java.util.Properties; public class Test { public static void main(String[] args) throws Exception { String id = "v"; BeanFactory context = new ClassPathXmlApplicationContext("src/applicationContext.xml"); Moveable o = (Moveable) context.getBean(id); o.run(); } }