Java 理论与实践: 伪typedef反模式

2016-02-19 18:40 5 1 收藏

今天图老师小编要跟大家分享Java 理论与实践: 伪typedef反模式,精心挑选的过程简单易学,喜欢的朋友一起来学习吧!

【 tulaoshi.com - 编程语言 】


  将泛型添加到 Java 语言中增加了类型系统的复杂性,提高了许多变量和方法声明的冗长程度。因为没有提供 “typedef” 工具来定义类型的简短名称,所以有些开发人员转而把扩展当作 “穷人的 typedef”,结果收到了良好的效果。
  
  对于 Java 5.0 中新增的泛型工具,一个常见的抱怨就是,它使代码变得太冗长。原来用一行就够的变量声明不再存在了,与声明参数化类型有关的重复非常讨厌,非凡是还没有良好地支持自动补足的 IDE。例如,假如想声明一个 Map,它的键是 Socket,值是 FutureString,那么老方法就是:
  
  
Map socketOwner = new HashMap(); 

  比新方法紧凑得多:
  
  
 MapSocket, FutureString socketOwner= new HashMapSocket, FutureString();   

  当然,新方法内置了更多类型信息,减少了编程错误,提高了程序的可读性,但是确实带来了更多声明变量和方法签名方面的前期工作。类型参数在声明和初始化中的重复看起来尤其没有必要;Socket 和 FutureString 需要输入两次,这迫使我们违犯了 “DRY” 原则(不要重复自己)。
  
  合成类似于 typedef 的东西
  
  添加泛型给类型系统增加了一些复杂性。在 Java 5.0 之前,“type” 和 “class” 几乎是同义的,而参数化类型,非凡是那些绑定的通配类型,使子类型和子类的概念有了显著区别。类型 ArrayList?、ArrayList? extends Number 和 ArrayListInteger 是不同的类型,虽然它们是由同一个类 ArrayList 实现的。这些类型构成了一个层次结构;ArrayList? 是 ArrayList? extends Number 的超类型,而 ArrayList? extends Number 是 ArrayListInteger 的超类型。
  
  对于原来的简单类型系统,像 C 的 typedef 这样的特性没有意义。但是对于更复杂的类型系统,typedef 工具可能会提供一些好处。不知是好还是坏,总之在泛型加入的时候,typedef 没有加入 Java 语言。
  
  有些人用作 “穷人的 typedef” 的一个(坏的)做法是一个小小的扩展:创建一个类,扩展泛型类型,但是不添加功能,例如 SocketUserMap 类型,如清单 1 所示:
  
    清单 1. 伪 typedef 反模式 —— 不要这么做
  
  
 public class SocketUserMap extends HashMapSocketFutureString { } SocketUserMap socketOwner = new SocketUserMap(); 

  我将这个技巧称为伪 typedef 反模式,它实现了将 socketOwner 定义简化为一行的这一(有问题的)目标,但是有些副作用,最终成为重用和维护的障碍。(对于有明确的构造函数而不是无参构造函数的类来说,派生类也需要声明每个构造函数,因为构造函数没有被继续。)
  
  伪类型的问题
  
  在 C 中,用 typedef 定义一个新类型更像是宏,而不是类型声明。定义等价类型的 typedef,可以与原始类型自由地互换。清单 2 显示了一个定义回调函数的示例,其中在签名中使用了一个 typedef,但是调用者提供给回调的是一个等价类型,而编译器和运行时都可以接受它:
  
    清单 2. C 语言的 typedef 示例
  
 // Define a type called "callback" that is a function pointer typedef void (*Callback)(int); void doSomething(Callback callback) { } // This function conforms to the type defined by Callback void callbackFunction(int arg) { } // So a caller can pass the address of callbackFunction to doSomething void useCallback() {   doSomething(&callbackFunction);  } 

  扩展不是类型定义
  
  用 Java 语言编写的试图使用伪 typedef 的等价程序就会出现麻烦。清单 3 的 StringList 和 UserList 类型都扩展了一个公共超类,但是它们不是等价的类型。这意味着任何想调用 lookupAll 的代码都必须传递一个 StringList,而不能是 ListString 或 UserList。
  
    清单 3. 伪类型如何把客户限定在只能使用伪类型
  
 class StringList extends ArrayListString { } class UserList extends ArrayListString { } ... class SomeClass { public void validateUsers(UserList users) { ... } public UserList lookupAll(StringList names) { ... } 

来源:http://www.tulaoshi.com/n/20160219/1618591.html

延伸阅读
Java5增加了新的类库并发集java.util.concurrent,该类库为并发程序提供了丰富的API多线程编程在Java 5中更加容易,灵活。本文通过一个网络服务器模型,来实践Java5的多线程编程,该模型中使用了Java5中的线程池,阻塞队列,可重入锁等,还实践了Callable, Future等接口,并使用了Java 5的另外一个新特性泛型。 简介 本文将实现...
标签: Web开发
下面是完整的代码。 代码如下: package cn.searchphoto.util; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; import java.util.zip.GZIPInputStream; /** * 下载远程网站的图片,通过设置Referer反反盗链...
标签: PHP
上一节:《PHP设计模式介绍》第五章 注册模式 《PHP设计模式介绍》第六章 伪对象模式 面向对象的编程之所以丰富多彩,部分是由于对象间的相互联系与作用。一个单一的对象就能封装一个复杂的子系统,使那些很复杂的操作能够通过一些方法的调用而简化。(无所不在的数据库连接就是这样的一个对象实例。) 然而经常有这样的情况,对象...
标签: 电脑入门
1. 实验目 的理解shell程序的功能。 学会shell的使用。 建造一个简单的shell。 2. 实验内容 基本任务:编写一个简单的shell程序,实现以下基本的命令。 1) 浏览目录和文件的各种属性 ls -l? 2) 回显 echo、 3) 显示文件内容 cat、more、 4) 创建目录mkdir、 5) 删除目录rmdir、 6) 删...
首先,本文的目标读者是正在从事技术工作的架构师。为了避免浪费大家的才智,我会避免讲述一些陈腐的最佳实践,例如"日常构建(build daily)"、"测试一切(test everything)"和"经常集成( integrate often)。 任何具有称职架构师的项目都有分工明确的、定义良好的团队结构。他们还为进行编码检查、构建代码(每日或在需要时)、进行测试(...

经验教程

897

收藏

43
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部