JADT入门,第2部分

用 Java 字典和辞典 API 使 Java 用户可以使用您的单词参考

在本系列文章的 第 1 部分中,您学到了 JADT 的一些基础知识,JADT 提供了透明地以 Java 为中心的访问字典或非结构化单词以及它 们的有关信息的方法。JADT 的主要目标是为字典提供者提供一个可以依据的标准技术,以便他们支持 Java 平台。第 1 部分从开发人员的 角度介绍了 JADT。在本文中,我要给出实现的细节,重点从字典开发商的角度考虑。我会带您了解 JADT 以及 JADT 的体系结构的细节, 并提供 JADT 中包含的所有类和接口的信息。

在 JADT 示例驱动程序实现的帮助下,我将讨论驱动程序必需的接口实现。之后,您将对 JADT 驱动程序和提供驱动程序的方法有了一 个整体的印象。

JADT 体系结构

JADT 体系结构为任何类型的后端数据提供了基于驱动程序的访问。字典提供者实现驱动程序端接口,为字典提供一个访问点,任何使用 这个字典的程序,将使用字典服务的用户端接口。结果就是,您可以方便地把 JADT 体系结构与各种开发商和第三方驱动程序集成在一起。

Driver 实现与 JADT 保持分离:

JADT 开发商的角色

如果您想用 JADT 公开您的字典或辞典,那么只需提供 JADT 的实现即可。JADT 驱动程序位于开发商数据和 Java 程序员之间,允许开 发商在不完全公开他们的数据和数据格式的情况下,对外提供服务。反过来。Java 程序员也不必深入某个开发商专用的数据和数据格式, 就可以使用开发商的数据。

JADT 驱动程序开发商可以使用 JADT 接口,并根据它们自己的习惯实现这些接口。一旦驱动程序就绪,可以访问您的数据,那么就可以 在您的站点启用它了。到这个站点的链接,可以作为 JADT 访问页面中的一个线程来使用。

JADT 用一致的方式在所有数据辞典上工作,这一点很重要,所以实现所有符合 JADT 所设标准的 JADT 接口和方法,是开发商的责任。 JADT 的 JADT Javadocs 和接口定义文档非常清楚地公开了接口和方法的目标。

JADT 实现近观

JADT 定义了多组接口和类。有些接口是辅助性的,有些是可选的,这取决于您的驱动程序所要支持的功能。如果要完整地支持 JADT, 那么就必须按照 Javadocs 中所定义的规范,实现所有接口。在这一节里,我将给出所有这些接口和类实现的细节。

完整的 JADT 接口和类集,如图 2 中的类图所示:

图 2. JADT 类图

下面我要介绍各种类和接口。

JADTDriverFacToryManager

JADTDriverFacTory 对象的基本控制类是 com.ibm.jadt.JADTDriverFacToryManager ,这个类就像用户和可用的驱动程序工厂之间的连 接。可以用它取得 Driver 的实例,然后再用实例得到某个驱动程序实现的一个或多个 JADT 服务。

在 JADTDriverFacTory 载入之后,由 JADTDriver 提供者负责注册 JADTDriverFacTory ,所以 JADT 用户还可以在任何时候,通过调 用 Class.forName(Driver_facTory_class); ,显式地装入 JADTDriver 。

驱动程序工厂类的名称应当随 JADTDriverFacToryName 一起交给用户,用户使用这个类的静态方法 getJADTDriverFacTory(String facToryName) ,就可以得到 getJADTDriverFacTory 。您可以调用静态 registerJADTDriverFacTory (JADTDriverFacTory facTory) 方法 来注册它。

JADT 带有下列接口,必须实现这些接口:

com.ibm.jadt. JADTDriverFacTorycom.ibm.jadt.JADTDriver

JADTDriverFacTory

com.ibm.jadt.JADTDriverFacTory 工厂接口用于建立驱动程序实例,应当由驱动程序的实现者注册到工厂控制器。由于 JADT 是基于驱 动程序的产品,所以 JADTDriver 的构造应当一直通过工厂。所有驱动程序实现者都应当实现这个接口。在 DriverFacTory 类的静态块里 ,工厂应当用 FacToryManager 注册,如清单 1 所示:

清单 1. 注册工厂的静态方法

public class JADTSampleDriverFacTory implements JADTDriverFacTory{  private static JADTSampleDriverFacTory facTory;  private Properties props;  private JADTSampleDriver driver;  static {  try{   if(facTory==null)   facTory=new JADTSampleDriverFacTory();   JADTDriverFacToryManager.registerJADTDriverFacTory(facTory);   }  catch(Exception ex){   //handle exception  }  }}

除了向管理器注册工厂之外, JADTSampleDriverFacTory 类还必须实现 createJADTDriver() 方法。可以用 createJADTDriver() 方法 把载入和数据访问策略(或者其他任何类型的访问属性)分开。例如,清单 2 显示了您如何才能设置要初始化的工厂数量,这由 loading_strategy 属性决定:

清单 2. 载入策略示例

public JADTDriver createJADTDriver() throws JADTException{  if(this.getProperty("loading_strategy")!=null&&   this.getProperty("loading_strategy").equals("multiple")){  if(this.getProperty("JADTSampleDriverDir")==null)  return driver=new JADTSampleDriver();  else return driver=new JADTSampleDriver   (this.getProperty("JADTSampleDriverDir"));  }  return new JADTSampleDriver();  else  {  if(this.getProperty("JADTSampleDriverDir")!=null)  if(driver==null)   driver=new JADTTextDriver(this.getProperty("JADTSampleDriverDir"));  else   if(driver==null)   driver=new JADTSampleDriver();   return driver;  }  }

驱动程序使用的所有属性,都必须编制文档,并提供驱动程序使用指南。这个接口方法的其余部分是自解释的,所以可以很容易地实现 。

JADTDriver 接口

com.ibm.jadt.JADTDriver 接口是所有驱动程序都必须实现的主驱动程序接口。它是由 JADTDriverFacTory 建立的,是向您提供驱动程 序服务访问的类,服务包括字典、辞典、拼写检查器、单词表、翻译器、语法检测器,以及词变位器。

这个接口代表具体厂商的驱动程序。除此之外,相同的驱动程序厂商还可以为不同的语言提供服务。

JADTDriver 类必须实现基本的构造函数方法,构造函数方法可以用来指定属性,例如数据库、目录或者数据访问方法。还可以用构造函 数初始化数据库的基本连接。类的结构如清单 3 所示:

清单 3. JADTSampleDriver 基本示例代码

public class JADTSampleDriver implements JADTDriver{  private Properties props;  public JADTSampleDriver()  {  props=new Properties();  }  public JADTSampleDriver(String datapath)  {  props=new Properties();  setProperty("JADTSampleDriverDir",filepath);  }  /*  Rest all methods  */}

JADTDriver 类还提供了对各种服务的访问,所以这个类实现了所有类都使用的公共 get>Service< 方法。 例如, getDictionary() 方法看起来会像清单 4:

清单 4. 字典服务方法实现

public Dictionary getDictionary(String langFrom,String langTo) throws JADTException{  try{  if(getProperty("JADTSampleDriverDir")!=null){   return new SampleDictionary    (langFrom,langTo,getProperty("JADTSampleDriverDir"));  }  else return new SampleDictionary(langFrom,langTo);  }  catch(JADTException exp){  JADTException ex1=new JADTException   ("DictionaryFailure","Could not create dictionary");  ex1.setNextException(exp);  throw ex1;  }}

此外,清单 5 中显示的方法也必须用类似的风格实现:

清单 5. 其他服务方法列表

public WordBook getWordBook  (String lang)throws JADTException;public SpellChecker getSpellChecker  (String lang)throws JADTException;public WordLister getWordlister  (String lang)throws JADTException;public TranslaTor getTranslaTor  (String langFrom,String langTo)throws JADTException;public GrammarChecker getGrammarChecker  (String lang)throws JADTException;public Anagrammizer getAnagrammizer  (String lang)throws JADTException;

使用数据结构

JADT 还提供了另外一组类和接口,用于提供组织数据的一般性方法。因为所有服务都使用数据库结构,所以 JADT 用户知道数据结构是 非常重要的。在下一节中,我会回顾一下数据结构。

单词表接口

WordList 接口代表单词的列表。因为它就是单词的容器,所以它并不从后端资源提取数据。 WordList 一般用于传递、获取、设置单词 ,或者包含某些单词。

WordList 类的结构如清单 6 所示:

清单 6. SampleWordlist 实现

public class SampleWordList implements WordList{  private VecTor words;  private int currentPos=0;  public TextWordList()  {/*default construcTor*/}  public int size(){return words.size();}  public void addWord(Word word)  {  words.addElement(word);  }  public void addWords(VecTor vec)  {  words.addAll(vec);  }  public VecTor getAllWords()  {  return words;  }  public void Start()  {  currentPos=0;  }  public boolean hasMoreWords()  {  if(currentPos==words.size()) return false;  else return true;  }  public WordList findWithPrefix(String find)  {  /* implementation */  }  public WordList findWithSuffix(String find)  {  /* implementation */  }  public WordList findWithSubstring(String find)  {  /* implementation */  }}

单词接口

Word 接口是字符的组合,代表母语使用者能够识别的语言单元。 Word 接口包装了单词的有关信息。保存在 Word 接口中的信息包括: 拼写、类型、来源、发音和记录。

因为这个接口以真实格式表示单词,所以实现应当提供一个容器,容器带有必需的 get 和 set 方法。清单 7 显示的信息对于形成单词 是必需的:

清单 7. 示例单词属性

private String word;private String type;private DictionaryRecord meaning;private DictionaryRecord synonym;private DictionaryRecord antonym;private String pronunciation;public static final int MEANINGS=1;public static final int SYNONYMS=2;public static final int ANTONYMS=3;private String source=""; 

这些字段可以通过它们的 get 和 set 方法来访问。

JADT 服务

JADT 为各种服务对象定义了接口。在下一节中,我将逐一介绍当前 JADT 版本中包含的服务对象。

字典接口

Dictionary 接口代表参考书,参考书里包含按字母顺序排列的单词表。每个条目都包含释义、类型、发音、来源和用法。

Dictionary 的实现应当包含字典接口中的所有方法,但不包含构造函数,同时要用恰当的载入机制。载入机制可以是消极(lazy),一 次性(single shot),或者多重装入(multiple load) 策略,具体取决于属性,而且可以修正载入机制。

例如,构造函数应当从数据库或文件中一次性载入数据,然后把数据保存在字典实现存储库中,如清单 8 所示:

清单 8. SampleDictionary 类

public class SampleDictionary implements Dictionary{  private Hashtable words;  private String langFrom;  private String langTo;  public static final int LOADWHOLEONE=1;  public static final int LOADWHOLEMULTIPLE=2;  public static final int RUNTIME=3;  public static final int INDEXING=4;  private int technique;  public SampleDictionary(String strLangFrom,String strLangTo,   String dir,int method) throws JADTException{  /*  Load the data from sTorage unit, according to strategy defined.  */  }  /*  Rest all methods  */}

余下的方法只是 getMeaning() 方法的变体,负责从载入的数据中提取单个或多个单词的含义。清单 9 显示了一个例子:

清单 9. 示例 getMeaning 方法

public com.ibm.jadt.DictionaryRecord getMeaning(Word word){  if(words.containsKey(word.toString().toLowerCase()))  return ((Word)words.get(word.toString().toLowerCase())).getRecord(TextWord.MEANINGS);  else return null;}

辞典组件

WordBook 是一个服务组件,它提供所有相关单词的信息。这些单词可以根据用法、来源、发音等进行关联。JADT 的当前版本提供了实 现同义词、反义词、上位词、下位词、整体名词、部分名词的接口,我们在 第 1 部分中已经讨论过。

实现需要让方法可以访问所有这类数据,建立从数据源载入数据的必要机制,如清单 10 所示:

清单 10. 示例辞典实现

public class SampleWordBook implements WordBook{  private Hashtable wordsSyn;  /* private hashtable for rest all services data, this act like a reposiTory for data */  public SampleWordBook(){  /* loads required data into reposiTory*/  }  public DictionaryRecord getSynonyms(Word word) throws JADTException {  WordList syn=(WordList)wordsSyn.get(word.toString());  if(syn==null||syn.size()==0)  return null;  DictionaryRecord first=null;  DictionaryRecord curr=null;  Enumeration enum=syn.getAllWords().elements();  while (enum.hasMoreElements())   {   if(first==null)   {   curr=new DictionaryRecord();first=curr;   }   else   {   curr.setNextRecord(new DictionaryRecord());   curr=curr.getNextRecord();   }   curr.setWordName(((Word)enum.nextElement()).toString());  }  return first;  }  /*  Similarly implement rest all services methods  */}

其他服务

其余的服务我已经在第 1 部分详细介绍过。这里是一个快速回顾,包括附加的实现细节。

拼写检查器

SpellChecker 类用于捕获拼写错误的单词。这个类在执行方面没有什么新鲜东西。

它把数据保存在私有散列表中,并实现了其他方法。它还实现了检查拼写的算法。这个服务类与其他服务的实现方式一样。

单词表类

WordLister 可用于从后端资源取得单词。JADT WordLister 还提供了一个选项,可以查找符合某个规则(例如相似前缀、相似后缀和公 共子字符串)的所有单词。

WordLister 类把数据保存在私有散列表中,并实现了其他方法。它还实现了检查拼写的算法。这个服务类与其他服务的实现方式一样。

词变位器类

Anagrammizer 可以给出单词或短语的所有变位形式,对于文字游戏应用程序来说会非常有用。这个类还实现了得到单词的变位词的算法 。

语法检查器类

GrammarChecker 检查单词在句子中的排列,检查单词在特定上下文中的用法。它还实现了检查语法的算法。这个服务类与其他服务的实 现方式一样。

翻译器类

TranslaTor 类用于把单词或消息从一种语言转换成另一种语言。这个特性可以用在本地化和国际化实现上。利用这个特性,用一种语言 编写的资源绑定文件可以被转换成另外一种语言。

TranslaTor 实现了把单词和句子从一种语言翻译成另外一种语言的算法。这个服务类与其他服务的实现方式一样。

汇总

一旦您已经实现了所有的服务接口和驱动程序类,您就可以把所有类捆绑在一个包里。最后的包结构看起来类似于清单 11:

清单 11. JADTDriver 包结构

com/ibm/jadt  Anagrammizer  Dictionary  DictionaryRecord  GrammarChecker  JADTDriver  JADTDriverFacTory  JADTDriverFacToryManager  JADTException  SpellChecker  TranslaTor  Word  WordBook  WordList  WordListercom/ibm/jadtdrivers/SampleDriver  JADTSampleDriver  JADTSampleDriverFacTory  SampleWordcom/ibm/jadtdrivers/SampleDriver/anagrammizer  SampleAnagrammizercom/ibm/jadtdrivers/SampleDriver/dictionary  SampleDictionarycom/ibm/jadtdrivers/SampleDriver/spellchecker  SampleSpellCheckercom/ibm/jadtdrivers/SampleDriver/wordbook  SampleWordBookcom/ibm/jadtdrivers/SampleDriver/wordlist  SampleWordList  SampleWordLister

把这些文件捆绑成一个 JAR 文件,您就可以部署它了。

结束语

通过本系列文章,您对于 JADT 技术有了全面的了解。这篇文件介绍了基本的 JADT 结构,以及如何使用不同的 JADT 服务和组件建立 使用字典和其他与单词有关的特性的 Java 应用程序。

海内存知已,天涯若比邻。

JADT入门,第2部分

相关文章:

你感兴趣的文章:

标签云: