分析のJavaデザインパターン(A)----異種容器は、被験体を提供するために、オブジェクト・クラスの任意の他のタイプを格納することができ

        最近のJava UIのデスクトップ項目を改造始め、私は揺動フレーム上の混沌とし​​た状況を作成するために、需要が明確でないため、このプロジェクトを発見し、ページコードの開発者は非常に最初に、このような問題に精通していない。できるようにするために、各クラスでご利用いただけますメインクラス()メソッド内のすべてのクラスを取得し提供し、メインクラスへの参照で渡された各クラスのコンストラクタには、対応するページ応答操作を実行するために、他のクラスへの参照を取得し、このアプローチは非常にのように見えますこのように、肥大化しました:

        ボタンは、フォームB、我々は、フォームAを開くには、メインページを開いた後にBのプロパティを変更するボタンのサポートを形成している。私たちは、クラスのget(のメインページでのみを使用することができます)、(設定サポートのフォームB)が表示されますBで行うことができるコンストラクタAおよびBで参照メインページを提供し、Bへの参照を保持するための方法は、プロジェクトのメインページの開発と、B.しかしながら、そのようなアプローチコールを呼び出しクラスのget(の数)と設定()あなたは、単にコンテナでは、コンテナに格納されたページオブジェクトにページを作成し、コンテナ、他のページを提供できる場合の方法は、あなたが想像できないことが、よりになります動作させるための追加のページ用のフォーム?

騒ぎ我々は、そのクラスであるページの異なる種類に大きく異なることがあり、我々は容器を提供する必要があり、作業を開始オブジェクトは次のとおりです。

 1 public class ClassContainerOne {
 2     private static Map<String, Object> container = new HashMap<>();
 3 
 4     public static void addClass(String name,Object value){
 5         container.put(name,value);
 6     }
 7     public static Object getClass(String name){
 8         return container.get(name);
 9     }
10 }

简单的封装一下我们就可以正常使用,这样的操作,我们只能依靠String来区分对象并且自己来完成强制类型转换:

 1 public class Test {
 2     public static void main(String[] args) {
 3         Teacher teacher = new Teacher("A老师");
 4         Student student = new Student("B学生");
 5         ClassContainerOne.addClass("teacher",teacher);
 6         ClassContainerOne.addClass("student",student);
 7         Teacher teacher1 = (Teacher) ClassContainerOne.getClass("teacher");
 8         Student student1 = (Student)ClassContainerOne.getClass("student");
 9         System.out.println(teacher1 + " " + student1);
10     }
11 }

我想大家都会想到一个问题,那就是这样的操作安全吗?显然是否定的,一旦我们强制转换错误,那系统就会崩溃,因此我们用泛型来修改完善我们的容器类:

 1 public class ClassContainerTwo {
 2     private static Map<Class<?>, Object> container = new HashMap<>();
 3 
 4     public static <T> void addClass(Class<T> valueType,T value) {
 5         container.put(valueType, value);
 6     }
 7 
 8     public static <T> T getClass(Class<T> valueType) {
 9         return valueType.cast(container.get(valueType));
10     }
11 }

我们转为使用其Class类型作为key值来对应我们的对象,确实可以做到对象获取时的万无一失:

 1 public class Test {
 2     public static void main(String[] args) {
 3         Teacher teacher = new Teacher("A老师");
 4         Student student = new Student("B学生");
 5         ClassContainerTwo.addClass(Teacher.class,teacher);
 6         ClassContainerTwo.addClass(Student.class,student);
 7         Teacher teacher1 = ClassContainerTwo.getClass(Teacher.class);
 8         Student student1 = ClassContainerTwo.getClass(Student.class);
 9         System.out.println(teacher1 + " " + student1);
10     }
11 }

 但是这样做的代价就是我们无法存放多个相同的对象,我们可以创建一个钩子类来衔接这个类容器和各个对象:

 1 public class Key<T> {
 2     private String name;
 3     private Class<T> valueType;
 4 
 5     public Key(String name, Class<T> valueType) {
 6         this.name = name;
 7         this.valueType = valueType;
 8     }
 9 
10     /**
11      * 同时重写equals()和hashCode(),避免加入类容器是和
12      * 从类容器中取出对象时实例化的key不是同一个对象,及类属性相同,但是地址不同
13      */
14     @Override
15     public boolean equals(Object o) {
16         if (this == o) return true;
17         if (o == null || getClass() != o.getClass()) return false;
18         Key<?> key = (Key<?>) o;
19         return Objects.equals(name, key.name) &&
20                 Objects.equals(valueType, key.valueType);
21     }
22 
23     @Override
24     public int hashCode() {
25         return Objects.hash(name, valueType);
26     }
27 
28     public Class<T> getValueType() {
29         return valueType;
30     }
31 }

然后继续完善我们的类容器:

 1 public class ClassContainerThree {
 2     private static Map<Key<?>,Object> container = new HashMap<>();
 3 
 4     public static <T> void addClass(Key<T> key,T value) {
 5         container.put(key, value);
 6     }
 7 
 8     public static <T> T getClass(Key<T> key) {
 9         return key.getValueType().cast(container.get(key));
10     }
11 }

这样的封装,虽然对于Key的实例化代码较长,但是很好的解决了我们的类容器存储和获取问题:

 1 public class Test {
 2     public static void main(String[] args) {
 3         Teacher teacher = new Teacher("A老师");
 4         Student student = new Student("B学生");
 5         ClassContainerThree.addClass(new Key<>("teacher",Teacher.class),teacher);
 6         ClassContainerThree.addClass(new Key<>("teacher",Student.class),student);
 7         Teacher teacher1 = ClassContainerThree.getClass(new Key<>("teacher",Teacher.class));
 8         Student student1 = ClassContainerThree.getClass(new Key<>("teacher",Student.class));
 9         System.out.println(teacher1 + " " + student1);
10     }
11 }

 

おすすめ

転載: www.cnblogs.com/skykuqi/p/11246765.html