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

优点三、
 
把某个对象的构建放给客户端来实现。
比如下面的实现,客户端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. 关于PHP使用GD库生成的验证码无法在别处显示

    https://segmentfault.com/q/1010000002522270

  2. 《剑指offer》---跳台阶问题

    本文算法使用python3实现 1. 问题1 1.1 题目描述:   一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法.   时间限制:1s:空间限制:3276 ...

  3. perf 是怎么计算调用栈的时间的?

    在我真个malloc的执行过程中共调用了8次的syswrite的系统调用,其中有两次来自于__lib_write, 两次来自于__memmove_avx_unaligned,然后__memmove_a ...

  4. [剑指Offer] 39.平衡二叉树

    题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树. class Solution { public: int Get_Height(TreeNode* root) { if(root == NU ...

  5. 【bzoj4832】[Lydsy2017年4月月赛]抵制克苏恩 概率期望dp

    题目描述 你分别有a.b.c个血量为1.2.3的奴隶主,假设英雄血量无限,问:如果对面下出一个K点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输入 输入包含多局游戏. 第一行包含一个整数 T (T ...

  6. hadoop的第一个hello world程序(wordcount)

    在hadoop生态中,wordcount是hadoop世界的第一个hello world程序. wordcount程序是用于对文本中出现的词计数,从而得到词频,本例中的词以空格分隔. 关于mapper ...

  7. [洛谷P3346][ZJOI2015]诸神眷顾的幻想乡

    题目大意:给你一棵$n$个点的树,最多有$20$个叶子节点,问共有几个不同的子串 题解:广义$SAM$,对每个叶子节点深搜一次,每个节点的$lst$设为这个节点当时的父亲,这样就可以时建出来的$SAM ...

  8. Linux相关——手写测试程序

    由于本人太弱,,,不会lemon,,,也不会在ubuntu下安装lemon,所以我选择手写测试程序emmmm 首先要写这个东西我们要先知道对拍怎么写. ; i <= ; i++) { syste ...

  9. [AHOI2014/JSOI2014]支线剧情 有上下界费用流

    ---题面--- 题解: 第一眼费用流,,然后想了好久怎么建图,,,最后发现是最小费用可行流的板子题.... 其实还没有很懂这个算法,所以这里只是摆一下步骤,以后再补理解吧. 首先一个思路就是转换图, ...

  10. BZOJ1011 [HNOI2008]遥远的行星 【奇技淫巧】

    1011: [HNOI2008]遥远的行星 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge Submit: 5058  Solve ...