关于FactoryBean的个人理解

有基本学生类结构:

 1 package top.dreamcenter.test.bean;
 2  
 3 import java.text.SimpleDateFormat;
 4 import java.util.Calendar;
 5  
 6 public class Student {
 7     private int age;
 8     private Calendar birth;
 9      
10     public Student() {}
11     public Student(int age, Calendar birth) {
12     super();
13         this.age = age;
14         this.birth = birth;
15     }
16     public int getAge() {
17         return age;
18     }
19     public void setAge(int age) {
20         this.age = age;
21     }
22     public Calendar getBirth() {
23         return birth;
24     }
25     public void setBirth(Calendar birth) {
26         this.birth = birth;
27     }
28      
29     private String shortBirthString() {
30         if (birth == null) return "NULL";
31         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
32         return sdf.format(birth.getTime());
33     }
34      
35     @Override
36     public String toString() {
37         return getClass().getSimpleName()
38             + ":{\n\tage:" + age + ",\n\tbirth:\"" + shortBirthString() + "\"\n}";
39     }
40 }
查看学生类定义

 

基本方式创建类对象并初始化:

 1 package top.dreamcenter.test.core;
 2  
 3 import java.util.Calendar;
 4  
 5 import top.dreamcenter.test.bean.Student;
 6  
 7 public class Core {
 8     public static void main(String[] args) {
 9         Calendar now = Calendar.getInstance();
10         int age = 0;
11          
12         Calendar temp1 = Calendar.getInstance();
13         temp1.set(2000, 12 - 1, 12);
14         age  = now.get(Calendar.YEAR)-temp1.get(Calendar.YEAR);
15         Student zhangSan = new Student(age, temp1);
16          
17         Calendar temp2 = Calendar.getInstance();
18         temp2.set(2001, 3 - 1, 5);
19         age  = now.get(Calendar.YEAR)-temp2.get(Calendar.YEAR);
20         Student liSi = new Student(age,temp2);
21          
22         System.out.println(zhangSan);
23         System.out.println(liSi);
24     }
25 }

 

问题发现1:对象的初始化于主体中过于过于复杂

解决措施1:将对象的创建与初始化在对象自己内部暴露出来

public static Student getStudent(int year, int month, int date) {
    Calendar now = Calendar.getInstance();
    Calendar temp = Calendar.getInstance();
    temp.set(year, month - 1, date);
    int age  = now.get(Calendar.YEAR)-temp.get(Calendar.YEAR);
    Student student = new Student(age, temp);
    return student;
}
 
此时,main函数只要简短的两句即可创建:
 
Student zhangSan = Student.getStudent(2000, 12, 12);
Student liSi = Student.getStudent(2001, 3, 5);

 

问题发现2:如果在初始化时要求添加多个监听器,假如用解决措施1将会导致bean类实现了过多的接口

解决措施2:使用FactoryBean模式创建对象

// 基本学生类结构:
 1 package top.dreamcenter.test.bean;
 2  
 3 import java.text.SimpleDateFormat;
 4 import java.util.Calendar;
 5  
 6 public class Student implements Cloneable{
 7     private int age;
 8     private Calendar birth;
 9     private String name;
10      
11     public Student() {}
12     public Student(String name, int age, Calendar birth) {
13         this.age = age;
14         this.birth = birth;
15         this.name = name;
16     }
17      
18     protected String getName() {
19         return name;
20     }
21      
22     public int getAge() {
23         return age;
24     }
25     public void setAge(int age) {
26         this.age = age;
27     }
28     public Calendar getBirth() {
29         return birth;
30     }
31     public void setBirth(Calendar birth) {
32         this.birth = birth;
33     }
34      
35     public String shortBirthString() {
36         if (birth == null) return "NULL";
37         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
38         return sdf.format(birth.getTime());
39     }
40      
41     @Override
42     protected Object clone() throws CloneNotSupportedException {
43         Student student = (Student)super.clone();
44         student.birth = (Calendar)birth.clone();
45         return student;
46     }
47     @Override
48     public String toString() {
49         return name + ":{\n\tage:" + age + ",\n\tbirth:\"" + shortBirthString() + "\"\n}";
50     }
51 }
查看学生类定义

// 简易的信息改变监听器

package top.dreamcenter.test.core;
 
public interface InfoListener {
    void onInfoChanged();
    void closeListener();
}

 

// 工厂类创建
 1 package top.dreamcenter.test.bean;
 2  
 3 import java.util.Calendar;
 4 import java.util.HashSet;
 5 import java.util.Iterator;
 6 import java.util.Set;
 7  
 8 import top.dreamcenter.test.core.InfoListener;
 9  
10 public class StudentFactoryBean implements InfoListener{
11     private Student tempStudent;
12     private Set<MyThread> set;
13     private boolean isNotCheck;
14      
15     public StudentFactoryBean() {
16         set = new HashSet<MyThread>();
17     }
18      
19     public Student getStudent(String name, int year, int month, int date) {
20         Calendar now = Calendar.getInstance();
21         Calendar temp = Calendar.getInstance();
22         temp.set(year, month - 1, date);
23         int age  = now.get(Calendar.YEAR)-temp.get(Calendar.YEAR);
24          
25         tempStudent = new Student(name, age, temp);
26         onInfoChanged();
27         return tempStudent;
28     }
29      
30     private class MyThread extends Thread{
31         private Student myStudent;
32         private boolean check;
33         public MyThread() {
34             check = !isNotCheck;
35             myStudent = tempStudent;
36         }
37         public void run() {
38             try {
39                 Student before = (Student) myStudent.clone();
40                 while(check) {
41                     sleep(100);
42                     if (myStudent.getAge()!=before.getAge()
43                         ||!myStudent.shortBirthString().equals(before.shortBirthString())) {
44                         System.err.println(myStudent.getName() + " info changed!");
45                         before = (Student) myStudent.clone();
46                     }
47                 }
48             } catch (CloneNotSupportedException e) {
49                 e.printStackTrace();
50             } catch (InterruptedException e) {
51                 e.printStackTrace();
52             }
53         }
54     }
55      
56     @Override
57     public void onInfoChanged() {
58         MyThread myThread = new MyThread();
59         myThread.start();
60         set.add(myThread);
61     }
62      
63     @Override
64     public void closeListener() {
65         isNotCheck = false;
66         Iterator<MyThread> iterator = set.iterator();
67         while(iterator.hasNext()) {
68             iterator.next().check = false;
69         }
70     }
71 }
查看工厂类

 

// 测试示例
 1 package top.dreamcenter.test.core;
 2  
 3 import java.util.Calendar;
 4 import java.util.Scanner;
 5  
 6 import top.dreamcenter.test.bean.Student;
 7 import top.dreamcenter.test.bean.StudentFactoryBean;
 8  
 9 public class Core {
10 private static StudentFactoryBean sfb;
11     public static void main(String[] args) {
12         sfb = new StudentFactoryBean();
13          
14         Student zhangSan = sfb.getStudent("Zhang_San", 2000, 12, 12);
15         Student liSi = sfb.getStudent("Li_Si", 2001, 3, 5);
16 
17                         // 此时学生类都已经初始化好并且添加了信息变动监听器
18          
19         System.out.println("set age :");
20         while(true) {
21             Scanner scanner = new Scanner(System.in);
22             int age = scanner.nextInt();
23             if (age == 0) break;
24             else if (age < 0) zhangSan.setAge(-age);
25             else liSi.setAge(age);
26         }
27          
28         sfb.closeListener();
29         System.out.println(zhangSan);
30         System.out.println(liSi);
31     }
32 }

 

 

所以FactoryBean出现的目的是让复杂的初始化问题简化,

并且让Bean本身更加的短小精悍,

同时降低了Bean本身对其它类或者接口的依赖性。


---------------------------------------------------
禁止转载
posted @ 2021-06-29 09:26  时光潜流  阅读(53)  评论(0编辑  收藏  举报