浅析java设计模式(一)----异构容器,可以存储任何对象类型为其他类提供该对象...

        最近在着手重构一个java UI桌面项目,发现这个项目在一开始的时候由于需求不明确,以及开发人员对swing框架不熟悉等问题造成了页面代码混乱的情况:为了能够在各个类里都可以拿到其他类的引用去进行相应的页面响应操作,在每一个类的构造方法中都传入了主类的引用,在主类中提供了所有类的get()方法,这样的做法显得十分的臃肿,就像这样:

        打开主页面后会显示窗体B,窗体B的按钮支持我们打开窗体A,窗体A按钮支持修改B中属性.我们只能通过在主页面的类中使用get(),set()方法来持有A和B的引用,在A和B的构造方法中提供主页面的引用,从而才能做到在B中调用A,A中调用B.但是这样的做法随着项目的开展主页面的类中get()和set()方法的数量将多到你无法想象,那么是否可以提供一个容器,在创建页面时就将该页面对象存入该容器中,其他页面只需通过这个容器来获取其他页面窗体进行操作?

废话不多说我们开始干活,由于不同的页面类型即其类可能不同所以我们提供的容器需要是Object的:

 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 }

 

转载于:https://www.cnblogs.com/skykuqi/p/11246765.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个错误是因为在代码中使用了不兼容的类型。具体来说,代码中使用了FileOutputStream类型对象,但是期望的类型java.io.OutputStream。这是因为FileOutputStream是OutputStream的子类,所以可以将FileOutputStream对象赋值给OutputStream类型的变量。但是在这个错误中,可能是由于导入的包不正确或者代码中的类型声明有误导致的。要解决这个问题,可以检查代码中的导入语句,确保导入了正确的包。另外,还可以检查代码中的类型声明,确保变量的类型与期望的类型一致。如果问题仍然存在,可以提供更多的代码或错误信息以便更好地帮助解决问题。 #### 引用[.reference_title] - *1* *2* [java.io.Serializable浅析 | 学步园](https://blog.csdn.net/weixin_39900468/article/details/114457968)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [java.io.Serializable浅析](https://blog.csdn.net/weixin_32228501/article/details/114348643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值