public interface Human {
public void sayHelloWorld(String name);
}
class Chinese implements Human {
public void sayHelloWorld(String name) {
String helloWorld = "你好," + name;
System.out.println(helloWorld);
}
}
class American implements Human {
public void sayHelloWorld(String name) {
String helloWorld = "Hello," + name;
System.out.println(helloWorld);
}
}
public class Main {
public static void main(String[] args) {
/******** 一般写法,Main类与Chinese类和American类之间的强耦合 ***********/
// Chinese和American,当类和方法修改时,此处的类和方法也需要修改
Chinese chinese = new Chinese();
chinese.sayHelloWorld("张三");
American american = new American();
american.sayHelloWorld("Jack");
}
}
class HumanFactory {
public Human getHuman(String type) {
if ("chinese".equals(type)) {
return new Chinese();
} else {
return new American();
}
}
}
public class Main {
public static void main(String[] args) {
/******** 工厂方法, Main类与类Chinese和American不再耦合,仅仅和其接口Human耦合 ***********/
// 修改时还需要修改在Main类中修改这些字符串
// Chinese和American,当类和方法修改时,只有方法需要修改
HumanFactory humanFactory = new HumanFactory();
Human human1 = humanFactory.getHuman("chinese");
human1.sayHelloWorld("张三");
Human human2 = humanFactory.getHuman("american");
human2.sayHelloWorld("Jack");
}
}
依赖注入
package IOC;
public class UserBean {
private String userName = "xxxx";
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
package IOC;
public class BeanFactory {
public Object getBean(String beanName) throws Exception{
Class<?> cls = Class.forName(beanName);
Object bean = cls.newInstance();
return bean;
}
}
package IOC;
public class Main {
public static void main(String[] args) throws Exception {
BeanFactory beanFactory = new BeanFactory();
UserBean userBean = (UserBean)beanFactory.getBean("IOC.UserBean");
System.out.println(userBean.getUserName());
}
}
package IOC;
public class Book {
public String getBookName(){
return "XXX";
}
}
package IOC;
public class Student {
private String name;
private int age;
private Book book;
public Student(String name,int age,Book book){
this.name = name;
this.age = age;
this.book = book;
}
public String getStudentInfo(){
return "name:"+name+",age:"+age;
}
public String getBookName(){
return book.getBookName();
}
}
package IOC;
import java.lang.reflect.Constructor;
public class Factory {
public Object getInstance(String className,Class[]param,Object[]initargs)throws Exception{
Class<?>cls = Class.forName(className);
//根据参数个数及类型确定返回哪个构造器
Constructor<?> constructor = cls.getConstructor(param);
//利用构造器实例化
Object object = constructor.newInstance(initargs);
return object;
}
}
package IOC;
public class Main {
public static void main(String[] args) throws Exception {
Factory factory = new Factory();
Class [] param = new Class[]{String.class,int.class,Book.class};
Book book = new Book();
Object [] initargs = new Object[]{"张三",25,book};
Student student = (Student)factory.getInstance("IOC.Student", param, initargs);
System.out.println(student.getStudentInfo());
System.out.println(student.getBookName());
}
}
package IOC;
public class Book {
public String getBookName(){
return "XXX";
}
}
package IOC;
public class Student {
private String name;
private int age;
private Book book;
public void setNameAndAge(String name,int age){
this.name = name;
this.age = age;
}
public void setBook(Book book){
this.book = book;
}
public String getStudentInfo(){
return "name:"+name+",age:"+age;
}
public String getBookName(){
return book.getBookName();
}
}
package IOC;
import java.lang.reflect.Method;
public class Factory {
public Object getInstance(String className,String[]methodNames,Class[][]params,Object[][]initargs)throws Exception{
Class<?>cls = Class.forName(className);
Object object = cls.newInstance();
if(methodNames==null)
return object;
int size = methodNames.length;
for(int i = 0;i<size;i++){
Method method = cls.getMethod(methodNames[i],params[i]);
method.invoke(object, initargs[i]);
}
return object;
}
}
package IOC;
public class Main {
public static void main(String[] args) throws Exception {
Factory factory = new Factory();
String[]methodNames = new String[]{"setNameAndAge","setBook"};
Class[][]params = new Class[][]{new Class[]{String.class,int.class},new Class[]{Book.class}};
Book book = new Book();
Object[][]initargs = new Object[][]{new Object []{"李四",30},new Object[]{book}};
Student student = (Student)factory.getInstance("IOC.Student", methodNames,params, initargs);
System.out.println(student.getStudentInfo());
System.out.println(student.getBookName());
}
}
package IOC;
public class Student {
private String name;
private Integer agexxx;
public String getName() {
return "student:"+name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAgebb() {
return agexxx;
}
public void setAgeaa(Integer age) {
this.agexxx = age;
}
public void setAA(String aa){}
}
package IOC;
public class Teacher {
private String name;
private Integer age;
public String getName() {
return "teacher:"+name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
package IOC;
import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Factory {
private Map<String, Object> beanMap = new HashMap<String, Object>();
public void init(String fileName) throws Exception {
// 读取指定的配置文件
SAXReader reader = new SAXReader();
String realPathString = new File("").getCanonicalPath();
Document document = reader.read(new File(realPathString + "/src/") + fileName);
Element root = document.getRootElement();
Element foo;
// 遍历bean
for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
foo = (Element) i.next();
// 获取bean的属性id和class
Attribute id = foo.attribute("id");
Attribute cls = foo.attribute("class");
// 利用Java反射机制,通过class的名称获取Class对象
Class bean = Class.forName(cls.getText());
// 获取对应class的信息
java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
// 获取其属性描述(所有setXXX与getXXX方法)
java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
// 设置值的方法
Method mSet = null;
// 创建一个对象
Object obj = bean.newInstance();
System.out.println(pd.length);
for(int k = 0;k<pd.length;k++){
System.out.println(pd[k].getName());
}
// 遍历该bean的property属性
for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
Element foo2 = (Element) ite.next();
// 获取该property的name属性
Attribute name = foo2.attribute("name");
Object value = null;
// 获取该property的子元素value的值,注意,这里的value只能是一个,因为后面是根据属性名而不是方法名来设置属性
for (Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) {
Element node = (Element) ite1.next();
value = (Object)node.getText();
break;
}
for (int k = 0; k < pd.length; k++) {
if (pd[k].getName().equalsIgnoreCase(name.getText())) {
mSet = pd[k].getWriteMethod();
if(pd[k].getPropertyType()==Integer.class){
mSet.invoke(obj,Integer.parseInt(value.toString()));
}
else{
mSet.invoke(obj,value);
}
}
}
}
// 将对象放入beanMap中,其中key为id值,value为对象
beanMap.put(id.getText(), obj);
}
}
// 通过bean的id获取bean的对象.
public Object getBean(String beanName) {
Object obj = beanMap.get(beanName);
return obj;
}
}
package IOC;
public class Main {
public static void main(String[] args) throws Exception {
//当类和方法修改时,代码完全不用修改,只需要修改xml文件即可,彻底实现了解耦
Factory factory = new Factory();
factory.init("/myConfig.xml");
Student student = (Student) factory.getBean("student");
System.out.println(student.getName()+":"+student.getAgebb());
Teacher teacher = (Teacher) factory.getBean("teacher");
System.out.println(teacher.getName()+":"+teacher.getAge());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="student" class="IOC.Student">
<property name="name">
<value>张三</value>
</property>
<property name="ageaa">
<value>25</value>
</property>
</bean>
<bean id="teacher" class="IOC.Teacher">
<property name="name">
<value>李老师</value>
</property>
<property name="age">
<value>45</value>
</property>
</bean>
</beans>
获取setXXX或getXXX的set或get后面的名字,如:setMyAge()则返回myAge,然后再通过与配置文件比较,确定pd[k]对应的方法是否合适用来设置属性值,比如,Student类中的setAA()方法对应的pd[i].getName()返回aA,而配置文件没有aA,所以该方法不会被使用,而setAgeaa()方法对应的pd[j].getName()返回ageaa,配置文件有这么一项,所以该方法被选中使用来设置ageaa的value25。
pd[k].getWriteMethod():比如pd[k].getName()等于agexxx,pd[k].getWriteMethod()则得到setAgexxx()方法(如果有的话), pd[k].getReadMethod()则可得到getAgexxx()方法(如果有的话),比如,设置age的方法为setAgeA1(),获
取age的方法为getAgeA2(),那么ageA1与ageA2对应两个不同的pd[m]和pd[n]:
pd[m].getName()返回ageA1,pd[m].getWriteMethod()返回方法setAgeA1(),但pd[m].getReadMethod()返回null(因为没有方法getAgeA1()),同理,pd[n].getName()返回ageA2,pd[n].getReadMethod()返回方法getAgeA2(),但pd[n].getWriteMethod()返回null(因为没有方法setAgeA2())。
pd[k].getPropertyType():
返回setXXX()的参数类型,也即getXXX()的返回值类型
package IOC;
public class Student {
private String name;
private String addr;
private Integer age;
public void setStudent(String name,String addr,Integer age){
this.name = name;
this.addr = addr;
this.age = age;
}
public String getStudent(){
return "Student name:"+name+",address:"+addr+",age:"+age;
}
}
package IOC;
public class Teacher {
private String name;
private String addr;
private Integer age;
public void setTeacher(String name,String addr,Integer age){
this.name = name;
this.addr = addr;
this.age = age;
}
public String getTeacher(){
return "Teacher name:"+name+",address:"+addr+",age:"+age;
}
}
package IOC;
import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Factory {
private Map<String, Object> beanMap = new HashMap<String, Object>();
public void init(String fileName) throws Exception {
// 读取指定的配置文件
SAXReader reader = new SAXReader();
String realPathString = new File("").getCanonicalPath();
Document document = reader.read(new File(realPathString + "/src/") + fileName);
Element root = document.getRootElement();
Element foo;
// 遍历bean
for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
foo = (Element) i.next();
// 获取bean的属性id和class
Attribute id = foo.attribute("id");
Attribute cls = foo.attribute("class");
// 利用Java反射机制,通过class的名称获取Class对象
Class bean = Class.forName(cls.getText());
// 获取对应class的信息
java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
// 获取其属性描述(所有setXXX与getXXX方法)
java.beans.MethodDescriptor md[] = info.getMethodDescriptors();
// 设置值的方法
Method mSet = null;
// 创建一个对象
Object obj = bean.newInstance();
// 遍历该bean的property属性
for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
Element foo2 = (Element) ite.next();
// 获取该property的name属性
Attribute name = foo2.attribute("name");
Vector<String>vector = new Vector<String>();
// 获取该property的子元素value的值,注意,这里的value只能是一个,因为后面是根据属性名而不是方法名来设置属性
for (Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) {
Element node = (Element) ite1.next();
vector.add(node.getText());
}
for (int k = 0; k < md.length; k++) {
if (md[k].getName().equalsIgnoreCase(name.getText())) {
mSet = md[k].getMethod();
Class<?>[] pClasses = mSet.getParameterTypes();
Object[] value = new Object[vector.size()];
for(int pi = 0;pi<vector.size();pi++){
if(pClasses[pi]==Integer.class){
value[pi] = Integer.parseInt(vector.elementAt(pi));
}else{
value[pi] = vector.elementAt(pi);
}
}
mSet.invoke(obj,value);
}
}
}
// 将对象放入beanMap中,其中key为id值,value为对象
beanMap.put(id.getText(), obj);
}
}
// 通过bean的id获取bean的对象.
public Object getBean(String beanName) {
Object obj = beanMap.get(beanName);
return obj;
}
}
package IOC;
public class Main {
public static void main(String[] args) throws Exception {
//当类和方法修改时,代码完全不用修改,只需要修改xml文件即可,彻底实现了解耦
Factory factory = new Factory();
factory.init("/myConfig.xml");
Student student = (Student) factory.getBean("student");
System.out.println(student.getStudent());
Teacher teacher = (Teacher) factory.getBean("teacher");
System.out.println(teacher.getTeacher());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="student" class="IOC.Student">
<property name="setStudent">
<value>张三</value>
<value>广东</value>
<value>25</value>
</property>
</bean>
<bean id="teacher" class="IOC.Teacher">
<property name="setTeacher">
<value>李老师</value>
<value>北京</value>
<value>45</value>
</property>
</bean>
</beans>
package IOC;
public class Student {
private String name;
private String addr;
private Integer age;
public Student(String name,String addr,Integer age){
this.name = name;
this.addr = addr;
this.age = age;
}
public String getStudent(){
return "Student name:"+name+",address:"+addr+",age:"+age;
}
}
package IOC;
public class Teacher {
private String name;
private String addr;
private Integer age;
public Teacher(String name,String addr,Integer age){
this.name = name;
this.addr = addr;
this.age = age;
}
public String getTeacher(){
return "Teacher name:"+name+",address:"+addr+",age:"+age;
}
}
public class Factory {
private Map<String, Object> beanMap = new HashMap<String, Object>();
public void init(String fileName) throws Exception {
// 读取指定的配置文件
SAXReader reader = new SAXReader();
String realPathString = new File("").getCanonicalPath();
Document document = reader.read(new File(realPathString + "/src/") + fileName);
Element root = document.getRootElement();
Element foo;
// 遍历bean
for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
foo = (Element) i.next();
// 获取bean的属性id和class
Attribute id = foo.attribute("id");
Attribute cls = foo.attribute("class");
// 利用Java反射机制,通过class的名称获取Class对象
Class bean = Class.forName(cls.getText());
Object obj = null;
// 遍历该bean的property属性
for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
Element foo2 = (Element) ite.next();
Vector<String>valueVector = new Vector<String>();
Vector<Class<?>>paramVector = new Vector<Class<?>>();
for (Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) {
Element node = (Element) ite1.next();
valueVector.add(node.getText());
paramVector.add(Class.forName(node.attribute("type").getText()));
}
int size = valueVector.size();
Class<?>[]param = new Class<?>[size];
Object[] value = new Object[size];
for(int vi = 0;vi<size;vi++){
param[vi] = paramVector.elementAt(vi);
if(paramVector.elementAt(vi)==Integer.class)
value[vi] = Integer.parseInt(valueVector.elementAt(vi));
else
value[vi] = valueVector.elementAt(vi);
}
Constructor constructor = bean.getConstructor(param);
// 创建一个对象
obj = constructor.newInstance(value);
}
// 将对象放入beanMap中,其中key为id值,value为对象
beanMap.put(id.getText(), obj);
}
}
// 通过bean的id获取bean的对象.
public Object getBean(String beanName) {
Object obj = beanMap.get(beanName);
return obj;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="student" class="IOC.Student">
<property>
<value type="java.lang.String">张三</value>
<value type="java.lang.String">天津</value>
<value type="java.lang.Integer">18</value>
</property>
</bean>
<bean id="teacher" class="IOC.Teacher">
<property>
<value type="java.lang.String">李老师</value>
<value type="java.lang.String">上海</value>
<value type="java.lang.Integer">35</value>
</property>
</bean>
</beans>