读书,有时候,我感觉总是有点绕和不具体。我阅读了代码,理解代码后,才有一种理解和把握的感觉。

优点三、
 
把某个对象的构建放给客户端来实现。
比如下面的实现,客户端Test,获取Service的实例具体类型,是由服务提供者Provider来确定的。
 
Services暴露服务提供者的注册方法,不同的服务提供者,会提供不同的实例。如下文,实现了DEFAULT_PROVIDER, COMP_PROVIDER, ARMED_PROVIDER三个服务提供者。
将服务提供者注册到Services中,用名称区别不同的服务提供者。
 
于是,客户端Test,在获取实例的时候,传递对应的服务提供者名称给Services,这样就可以获取指定类型的实例。
比如,Service s2 = Services.nexInstance("comp").获取的实例类型,是由COMP_PROVIDER来决定的。
// Simple test program for service provider framework
package org.effectivejava.examples.chapter02.item01; public class Test {
public static void main(String[] args) {
// Providers would execute these lines
Services. registerDefaultProvider(DEFAULT_PROVIDER);
Services. registerProvider("comp", COMP_PROVIDER);
Services. registerProvider("armed", ARMED_PROVIDER); // Clients would execute these lines
Service s1 = Services.newInstance();
Service s2 = Services.newInstance("comp" );
Service s3 = Services.newInstance("armed" );
System. out.printf("%s, %s, %s%n" , s1, s2, s3);
} private static Provider DEFAULT_PROVIDER = new Provider() {
public Service newService() {
return new Service () {
@Override
public String toString() {
return "Default service" ;
}
};
}
}; private static Provider COMP_PROVIDER = new Provider() {
public Service newService() {
return new Service () {
@Override
public String toString() {
return "Complementary service" ;
}
};
}
}; private static Provider ARMED_PROVIDER = new Provider() {
public Service newService() {
return new Service () {
@Override
public String toString() {
return "Armed service" ;
}
};
}
};
}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; public class Services {
private Services() {
} // Prevents instantiation (Item 4) // Maps service names to services
private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();
public static final String DEFAULT_PROVIDER_NAME = "<def>"; // 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();
}
}

--------------------------------------------------------------------------------------------------------------------------------------------------------

//在接口中,可以定义要客户端实现的方法
public interface Service {
// Service-specific methods go here
}

-------------------------------------------------------------------------------------------------------------------------------------------------------

// Service provider framework sketch - Service provider interface - Page 12
package org.effectivejava.examples.chapter02.item01; public interface Provider {
Service newService();
}

  

Item 1----------考虑用静态工厂方法代替构造器的更多相关文章

  1. Java - 用静态工厂方法代替构造器

    Effective Item - 考虑用静态工厂方法代替构造器我们有两种常见的方法获得一个类的实例: 公有的构造器 提供静态工厂方法(static factory method) 相对公有的构造器,静 ...

  2. 静态工厂方法VS构造器

    我之前已经介绍过关于构建者模式(Builder Pattern)的一些内容,它是一种很有用的模式用于实例化包含几个属性(可选的)的类,带来的好处是更容易读.写及维护客户端代码.今天,我将继续介绍对象创 ...

  3. 【Effective Java读书笔记】创建和销毁对象(一):考虑使用静态工厂方法代替构造器

    类可以提供一个静态方法,返回类的一个静态实例,如Boolean包装类的一个获取实例的静态方法 public static Boolean valueOf(boolean b) { return (b ...

  4. 改善JAVA代码01:考虑静态工厂方法代替构造器

    前言 系列文章:[传送门]   每次开始新的一本书,我都会很开心.新书新心情. 正文 静态工厂方法代替构造器 说起这个,好多可以念叨的.做了一年多的项目,慢慢也有感触. 说起构造器 大家很明白,构造器 ...

  5. Effective java读书札记第一条之 考虑用静态工厂方法取代构造器

    对于类而言,为了让client获取它自身的一个实例,最经常使用的方法就是提供一个共同拥有的构造器. 另一种放你发,也应该子每一个程序猿的工具箱中占有一席之地.类能够提供一个共同拥有的静态 工厂方法.它 ...

  6. 【读书笔记 - Effective Java】01. 考虑用静态工厂方法代替构造器

    获取类的实例有两种方法: 1. 提供一个公有的构造器(最常用). 2. 提供一个公有的静态工厂方法(static factory method). // 静态工厂方法示例 public static ...

  7. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  8. effective java 3th item1:考虑静态工厂方法代替构造器

    传统的方式获取一个类的实例,是通过提供一个 public 构造器.这里有技巧,每一个程序员应该记住.一个类可以对外提供一个 public 的 静态工厂方法 ,该方法只是一个朴素的静态方法,不需要有太多 ...

  9. Tips1:考虑用静态工厂方法代替构造器

    用静态工厂方法来代替构造器为外界提供对象 描述: 静态工厂方法代替构造器来给外界提供对象,创建对象依然是由构造器来完成的 创建对象和提供对象: 创建对象的方式: 构造器 提供对象来哦方式: 构造器 类 ...

随机推荐

  1. win10 死机

    其实Win10系统还是不错的,如果你的电脑升级Win10后中招经常死机,可以用下面的方案来应对. 1.下载安装支持兼容Win10的软件版本,下载软件之前看一下兼容列表里是否有Win10系统.虽然Win ...

  2. Java容器之Map接口

    Map 接口: 1. 实现 Map 接口的类是用来存储键-值(key-value)对: 2. Map 接口的实现类有 HashMap 和 TreeMap 等: 3. Map 类中存储的键-值对,通过键 ...

  3. HashCode和equals的理解

    -------------------------------------------------------------------------------------------第一篇博客---- ...

  4. 【Linux】CentOS安装redis

    CENTOS7下安装REDIS 安装完成之后使用:redis-cli命令连接,如图: 提示:/var/run/redis_6379.pid exists, process is already run ...

  5. 【Linux】- Ubuntu 配置mysql远程访问

    ubuntu上安装mysql非常简单只需要几条命令就可以完成. sudo apt-get install mysql-server   安装过程中会提示设置密码什么的,注意设置了不要忘了,安装完成之后 ...

  6. Gradle sync failed: Failed to find Build Tools revision 26.0.2的解决办法

    说明在android studio中没有 build tools 的26.0.2的版本,你确认一下,是否是这样: 点击==>android studio的菜单栏中Tools==>andro ...

  7. 只要访问的地址匹配cookie的地址时候 发送request请求时候 会携带上该cookie

    只要访问的地址匹配cookie的地址时候 发送request请求时候 会携带上该cookie

  8. Go语言【第三篇】:Go变量和常量

    Go语言变量 变量来源于数学,是计算机语言中能存储计算结果或能表示值抽象概念.变量可以通过变量名访问.Go语言变量名由字母.数字.下划线组成,其中首字母不能为数字,声明变量的一般形式是使用var关键字 ...

  9. 《转》'autocomplete="off"'在Chrome中不起作用解决方案

    最近项目中遇到一个令人头疼的问题,查阅各种资料,尝试各种方法,最终得以解决:哎···下面就说说这心酸的历程吧. 大家都知道autocomplete属性是表单字段中的HTML5新属性,该属性有两种状态值 ...

  10. BZOJ1604 & 洛谷2906:[USACO2008 OPEN]Cow Neighborhoods 奶牛的邻居——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1604 https://www.luogu.org/problemnew/show/P2906#sub ...