登录

  • 登录
  • 忘记密码?点击找回

注册

  • 获取手机验证码 60
  • 注册

找回密码

  • 获取手机验证码60
  • 找回
毕业论文网 > 外文翻译 > 计算机类 > 物联网工程 > 正文

移动平台图像处理辅助教学外文翻译资料

 2022-10-16 04:10  

英语原文共 369 页,剩余内容已隐藏,支付完成后下载完整资料


本章关注创建和销毁对象:何时以及如何创建它们,以及如何避免创建它们时,如何确保及时销毁,以及如何管理对象销毁之前必须进行的各种清理动作。

第1条:考虑静态工厂方法代替构造器

对于类而言,让客户端获得本身的一个实例,最常用的方法是提供一个共有的构造器。还有一个方法,应该是每个程序员工具箱的一部分。类可以提供一个公共静态工厂方法,它只是一个返回类的实例的静态方法。这是来自Boolean(基本类型Boolean的包装类)的简单示例。这种方法将一个Boolean值原始值转换为一个Boolean对象引用:

public static Boolean valueOf(boolean b) {

return b ? Boolean.TRUE : Boolean.FALSE;

}

注意,静态工厂方法与设计模式(Gamma95,第107页)工厂方法模式是不一样的。本条目中的静态工厂方法并不直接等效于设计模式中的工厂方法。

一个类可以通过静态工厂方法提供它的客户端,而不是通过构造函数。提供一个静态工厂方法代替公共构造函数,这样做具有优势。

静态工厂方法对比构造函数的一个优点是,它们有名字。如果构造函数的参数本身没有确切地描述正被返回的对象,那么静态工厂精心挑选的名字更容易使用,生成的客户端代码更易于阅读。例如,构造函数BigInteger(int,int,Random)返回BigInteger可能是一个素数,如果更好表达为一个名为BigInteger.probablePrime的静态工厂方法,显然更清楚。(这个方法最终在1.4版本中添加)。

一个类只能有一个带有给定的签名的构造函数。程序员已经知道要克服这一限制,提供两个参数列表只在参数类型上具有不同顺序的构造函数。实际上这是并不是一个好主意。这样一个API,用户将永远无法记住该用哪个构造函数,最终将调用错误的构造函数。并且,人们阅读到使用了这些构造函数的代码时,如果没有参考类的文档,往往不知所云。

因为它们的名字,静态工厂方法不受上述的限制。在这种情况下,当一个类需要多个带有相同签名的构造函数时,就用静态工厂方法代替构造函数,并且慎重地选择名称以便突出它们之间的区别。

静态工厂方法的第二个优点是,与构造函数不同,他们不需要在每次调用时创建一个新的对象。这允许不可变类使用预先构建好的实例,或者缓存建造好的实例,给他们重复利用,避免创建不必要的重复对象。Boolean.value of(boolean)方法说明了这种技术:它从来没有创建一个对象。这种方法类似于Flyweight模式[Gamma95,p . 195]。它可以极大地改善性能如果等效对象请求通常,特别是如果他们是昂贵的。

静态工厂方法能够为重复的调用返回相同的对象,允许类保持严格控制实例存在。这样做是instance-controlled类。编写instance-controlled类有几个原因。实例控制允许一个类来保证它是一个Singleton或noninstantiable。同时,它允许一个不可变类保证不存在两个相同的实例:a.equals(b)当且仅当a= = b。如果一个类保证了这一点,那么客户可以用= =操作符,而不是等于(对象)方法,这可以改进性能。枚举类型提供这种保证。

静态工厂方法的第三个优点是,与构造函数不同的是,他们可以返回一个原返回类型的任何子类型的对象。这给了你极大的灵活性选择返回的对象的类。这种灵活性的一个应用程序是一个公共API可以返回对象,而不使他们的类变成共有的。隐藏实现类以这种方式会导致一个非常紧凑的API。这种技术有助于基于接口框架(18项),接口提供自然静态工厂方法的返回类型。考虑静态工厂方法代替构造函数,接口函数不能有静态方法,所以按照惯例,静态工厂方法的接口命名类型放在noninstantiable类中。

例如,Java Collections框架有32个方便的实现其收藏接口,提供无法改变的集合,集合同步等。几乎所有的这些实现出口通过在一个noninstantiable静态工厂方法类(java.util.Collections)中导出。返回的对象的类都时非公有的。

集合框架API比导出32个独立共有类要小得多了,每一个便利的实现都对应一个类。不仅仅是指API数量上的减少,也是概念上的减少。用户知道返回的对象有精确指定的API接口,所以没有必要读有关类的文档。此外,使用这样的静态工厂方法需要客户端引用返回的对象的接口,而不是它的实现类,这是一种好的做法。

共有的静态工厂方法返回的对象的类不仅可以是非共有的,而且该类可以根据每次调用而改变。只要是已声明返回类型的子类型都是允许的。返回的对象的类也可以从不同的版本增强软件的可维护性和性能。类java.util.EnumSet,在版本1.5中引入的,是没有公共构造函数,只有静态工厂方法。他们返回的两种实现,取决于底层的枚举类型的大小:如果有六十四个或更少的元素,和大多数enum类型一样,静态工厂返回RegularEnumSet实例,它是由一个long进行支持;如果枚举类型有六十五或更多的元素,工厂返回JumboEnumSet实例,由long数组进行支持。

这两个实现类的存在对客户端来说是不可见的。如果RegularEnumSet不再为小enum类型提供性能优势,就可能从将来的版本中将它删除,不会造成不良影响。同样的,将来的版本也可以添加一个第三或第四EnumSet实现,如果被证明是有益的性能。客户既不知道也不关心从工厂方法中得到的对象的类;他们只关心一些EnumSet的子类。

返回的对象的类的静态工厂方法时甚至不需要存在类包含的方法。这种灵活的静态工厂方法的基础服务提供者框架,比如API的Java数据库连接(JDBC)。服务提供者框架是一个系统的多个服务提供者实现一个服务,以及系统的实现提供给其客户,与它们的实现分离。

服务提供者框架的三个基本要素:一个服务接口,提供者实现;提供者注册API,系统使用注册的实现,允许客户访问,客户和服务访问API,它使用以获得服务的一个实例。服务访问的API通常允许但不要求客户端指定一些标准选择供应商。在缺乏这样的规范,API返回一个默认实现的实例。服务访问API是“灵活的静态工厂”,它构成了服务提供者框架的基础。

服务提供者框架的可选的第四部分:一个服务提供者接口,其中提供者实现创建服务实现的实例。如果缺乏服务提供者接口,实现通过类名注册,并通过反射方式进行实例化。在JDBC中,连接服务接口的一部分,DriverManager。DriverManager registerDriver是提供者注册API。getConnection是服务访问API,Driver是服务提供者接口。

服务提供者框架模式有着无数种变体。例如,服务访问API可以返回一个富裕的比需要的服务接口提供者,以使用适配器模式。这是一个简单的实现与服务提供者接口和一个默认的提供者:

// Service provider framework sketch

// Service interface

public interface Service {

... // Service-specific methods go here

}

// Service provider interface

public interface Provider {

Service newService();

}

// Noninstantiable class for service registration and access

public class Services {

private Services() { } // Prevents instantiation (Item 4)

// Maps service names to services

private static final Maplt;String, Providergt; providers =

new ConcurrentHashMaplt;String, Providergt;();

public static final String DEFAULT_PROVIDER_NAME = 'lt;defgt;';

// Provider registration API

public static void registerDefaultProvider(Provider p) {

registerProvider(DEFAULT_PROVIDER_NAME, p);

}

public static void registerProvider(String name, Provider p){

providers.put(name, p);

}

// Service access API

public static Service newInstance() {

return newInstance(DEFAULT_PROVIDER_NAME);

}

public static Service newInstance(String name) {

Provider p = providers.get(name);

if (p == null)

throw new IllegalArgumentException(

'No provider registered with name: ' name);

return p.newService();

}

}

第四个静态工厂方法的优点是,他们减少创建参数化类型实例的冗长。不幸的是,您必须指定类型参数,当你调用一个参数化的类的构造函数,即使他们从上下文是显而易见的。这通常需要你提供类型参数在接连两次:

Maplt;String, Listlt;Stringgt;gt; m =

new HashMaplt;String, Listlt;Stringgt;gt;();

该冗余规范很快变成了痛苦的长度和复杂性类型参数增加。但是有了静态工厂方法,,编译器可以帮你找出类型参数。这就是所谓的类型推断。例如,假设HashMap提供静态工厂:

public static lt;K, Vgt; HashMaplt;K, Vgt; newInstance() {

return new HashMaplt;K, Vgt;();

}

然后你可以以这种简洁的代码代替冗长的声明:

Maplt;String, Listlt;Stringgt;gt; m = HashMap.newInstance();

总有一天,java可能在调用构造函数以及方法调用中执行这种类型的推理,但到1.6版本为止暂时还无法做到。

不幸的是,到1.6版本为止,标准的集合实现HashMap没有工厂方法,但是你可以把这些方法在自己的实用程序类中。更重要的是,您可以把这样的静态工厂放在自己的参数化的类中。

静态工厂方法的主要缺点是,没有公共的或受保护的类构造函数,不能从它派生出子类。这同样适用于非公开公共静态工厂返回的类。例如,任何子类方便集合框架的实现是不可能的。可以说这是因祸得福,因为它鼓励程序员使用组合而不是继承。

静态工厂方法的第二个缺点是,它们从其他静态方法不易区分。他们不站在API文档的方式构造函数,所以很难找出如何实例化一个类,它提供了静态工厂方法代替构造函数。Javadoc工具可能有一天关注静态工厂方法。与此同时,你可以通过关注减少这种不利静态工厂类或接口的评论,和通过遵循共同的命名约定。这里有一些静态工厂方法的共同名字:

bull;valueOf-Returns实例,松散来说,相同的值作为参数。这样的静态工厂有效的类型转换方法。

bull;of-valueOf需简洁替代返回对象的值,由EnumSet推广。

bull;getInstance-Returns所描述的一个实例参数但不能说相同的值。对Singleton来说,getInstance没有参数,并返回唯一的实例。

bull;newInstance像 getInstance一样,但newInstance保证每个实例返回有别于其他所有实例。

bull;getType像 getInstance一样,但是使用工厂方法是在不同的类。Type表示工厂方法返回的对象的类型。

bull;newType像newInstance一样,但是使用工厂方法是在不同的类。Type表示工厂方法返回的对象的类型。

总之,静态工厂方法和公共构造函数都有其用途,我们需要理解他们的相对优势。通常静态工厂更可取,首先避免第一反应提供公共构造函数,而没有考虑静态工厂。

第2条:遇到多个构造器参数是要考虑用构建器

静态工厂和构造函数有一个共同的限制:他们并没有很好地扩展到大量的可选参数。考虑一个类代表出现在包装食品的营养标签。这些标签有几个域是必需的:每份的含量,每罐的含量,每份的卡路里,和二十个可选域总脂肪、饱和脂肪、转化脂肪、胆固醇,钠,等等。大多数产品在某几个可选域中都有少数的非零值。

你应该写什么样的构造函数或静态工厂来编写呢?传统上,程序员使用重叠构造函数模式,你提供一个构造函数,只有必需的参数,第二个有一个可选参数,第三个有两个可选参数,等等,最后一个构造函数一个包含所有可选

剩余内容已隐藏,支付完成后下载完整资料


资料编号:[151164],资料为PDF文档或Word文档,PDF文档可免费转换为Word

您需要先支付 30元 才能查看全部内容!立即支付

企业微信

Copyright © 2010-2022 毕业论文网 站点地图