说是原创,但本系列实际上是编程思想,Effective Java,深入理解JVM,以及一些大神
博客的笔记,主要内容就是一些理论问题的实践,一些实践问题容易踩的坑,一些坑的
解决方案 等,纯Java系列有十几篇,后面还会有安卓系列,相关的代码链接:纯java代
码– https://github.com/cowthan/JavaAyo,安卓demo代码–
https://github.com/cowthan/AyoWeibo,后续代码也会重整一下,以配合本系列的
内容。
本系列的部分章节和大部分的格式问题,之后会由Mr.LongFace同学负责,作为IT
行业的新生代,我们俩都是特别谦虚的人,所以欢迎各位尽情批评指正。
后续内容:
5 对象池:对象太重
6 Flyweight享元模式:对象太多
7 备忘录模式:状态保存,对象快照
8 原型模式:是啥来着
9 对象clone
10 序列化
11 四种引用
12 内存模型和垃圾回收
13 对象缓存
//常规模式
public static class Boolean{
//静态工厂方法
public static Boolean valueOf(boolean b){
return new Boolean(b);
}
private boolean v;
private Boolean(boolean b){
v = b;
}
}
//高级模式:限制对象的数目,比如单例,此处的例子是:Boolean基本就只能对应两个值
public static class Boolean{
//预定义的两个对象,某种意义上算是缓存,使用时可以省去创建对象的过程
public static final Boolean True = new Boolean(true);
public static final Boolean False = new Boolean(false);
//静态工厂方法
public static Boolean valueOf(boolean b){
return b ? True : False;
}
private boolean v;
private Boolean(boolean b){
v = b;
}
}
静态工厂方法的好处是:
优势1
:方法有名字,构造器没有,如BigInteger.probablePrime方法,这就是静态工厂,表示BitInteger(int, int, Random)返回的很可能是素数优势2
:可以预先构建对象,如Boolean.TRUE和FALSE,类似Flyweight模式优势3
:可以返回任意子类型的对象,返回的父类或者接口引用,具体实现类甚至可以对外隐藏,参考Java Collections Framework中集合接口的32个便利实现优势4
:简化Map这是从静态工厂好处3里引出来的,对外提供一个接口,客户端依赖于此接口实例,但并不关心具体实现
服务接口
:Service Interface,提供者实现,如Connection提供者注册API
:Provider Registreation API,用来注册实现,让客户端访问,如DriverManager.registerDriver()服务访问API
:Service Access API,客户端用来获取服务实例,这里就是灵活的静态工厂,如DriverManager.getConnection()服务提供者接口
,Service Provider Interface,可选,用来创建服务实例,如果没有这个,就得按照类名注册,并通过反射实例化,如Driver就是这个角色
/** * ================服务接口:Service Interface================== * 一个对外提供服务的接口,并且不同情况,会产生不同的Service对象, * 即通过Service的不同实现,对外提供不同的服务 * */
public interface Service {
void doService();
}
/** * ================服务提供者接口================== * 用来生成Service对象,注意,如果不使用Provider,则注册到Services的就得是Service实现类的Class对象, * newInstance也只能通过反射来了 * 问题就是Provider实现类应该有几个 * */
public interface Provider {
Service newService();
}
public class Services {
private Services(){}
//================提供者注册API==================//
//这里要么注册provider对象,要么注册Service实现类的Class,你选吧
private static final Map<String, Provider> providers = new ConcurrentHashMap<>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";
public static void registerDefaultProvider(Provider p){
registerProvider(DEFAULT_PROVIDER_NAME, p);
}
public static void registerProvider(String defaultProviderName, Provider p) {
providers.put(defaultProviderName, p);
}
//================服务访问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 class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public NutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
public static class Builder{
//必填的参数,无默认值
private final int servingSize;
private final int servings;
//选填的参数,有默认值
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;
public Builder(int servingSize, int servings){
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val){ calories = val; return this; }
public Builder fat(int val){ fat = val; return this; }
public Builder carbohydrate(int val){ carbohydrate = val; return this;}
public Builder sodium(int val){ sodium = val; return this; }
public NutritionFacts build(){
return new NutritionFacts(this);
}
}
}
public static void main(String[] args) {
NutritionFacts cocacola = new NutritionFacts.Builder(240, 8)
.calories(100)
.sodium(35)
.carbohydrate(27)
.build();
}
public interface Builder<T> {
public T build();
}
package com.cowthan.object_management;
public class NutritionFacts2 {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public NutritionFacts2(MyBuilder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
public static class MyBuilder implements Builder<NutritionFacts2>{
//必填的参数,无默认值
private final int servingSize;
private final int servings;
//选填的参数,有默认值
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;
public MyBuilder(int servingSize, int servings){
this.servingSize = servingSize;
this.servings = servings;
}
public MyBuilder calories(int val){ calories = val; return this; }
public MyBuilder fat(int val){ fat = val; return this; }
public MyBuilder carbohydrate(int val){ carbohydrate = val; return this;}
public MyBuilder sodium(int val){ sodium = val; return this; }
public NutritionFacts2 build(){
return new NutritionFacts2(this);
}
}
public static void main(String[] args) {
Builder<NutritionFacts2> builder = new NutritionFacts2.MyBuilder(240, 8)
.calories(100)
.sodium(35)
.carbohydrate(27);
NutritionFacts2 cocacola = builder.build();
}
}
/* 这里的Builder<NutritionFacts2> builder对象,可以传给任意的抽象工厂方法 */
public class Singleton {
public static final Singleton INSTANCE = new Singleton();
private Singleton(){}
private Object readResolve(){ return INSTANCE; }
public void provideService(){
}
}
//访问
Singleton.INSTANCE.provideService();
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton(){}
public static Singleton getInstance(){ return INSTANCE; }
private Object readResolve(){ return INSTANCE; }
public void provideService(){
}
}
//访问
Singleton.getInstance().provideService();
延迟加载
volatile的使用
public class Singleton{
private volatile static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
这里的说法是:
SingletonHolder作为一个内部类,会在访问时被加载,所以这里实现了延迟加载,并且内部类可以从语言层面上防止多线程的问题,比双重锁模式优雅的多。
public class Singleton{
private static class SingletonHolder{
private static final Singleton INSTANCE = new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
按照Effective Java书里说法,这个方法虽然没流行起来,但这个是最佳方式,第2版15页
//直接就能防止反射,防止序列化时生成新类
//是否延迟加载不知道
public enum Singleton {
INSTANCE;
public void provideService(){
}
}
public class Singleton {
private Singleton(){}
public void doSth(){
System.out.println("做点什么");
}
}
public class SingletonFactory {
private static Singleton singleton;
//===只实例化一次,使用暴力反射
static{
try {
Class cls = Class.forName(Singleton.class.getName());
Constructor cons = cls.getDeclaredConstructor();
cons.setAccessible(true);
singleton = (Singleton) cons.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
public static Singleton getSingleton(){
return singleton;
}
/** * 扩展:一个项目可以有一个单例构造器,负责生成所有单例对象,只需要传入类型, * 但是需要事先知道有几个单例类型 */
}
这节的内容感觉有点不对劲,仅作参考,别太信
更一般化的分析:
抽象工厂模式: 先看看下面的分析,我还没搞明白反正,太乱了,具体问题就在于这个模式怎么扩展
先明白两个概念:
在有多个业务品种,业务分类时,有下面这么几个概念
1、产品族,也叫产品线,不同的产品族的产品,应该可以组装成一件高等级产品,
如螺丝是一个产品族,分不同型号的螺丝,铁板是一个产品族,分不同型号的铁板,
门把手是一个产品族,分不同型号的门把手
——螺丝,铁板,门把手就可以组成一个车门
2、产品等级:不同型号的螺丝,不同型号的铁板,这个不同型号就是不同产品等级
所以对于产品而言:有两种选择
1、当产品族需要可扩展时:
有个:IProduct接口
有N个:AbstractXXProduct, N就是产品族的数量,如Abstract_Luosi,Abstract_Tieban,
Abstract_MenBaShou
对于每个产品族,有M个子类:Luosi_10, Luosi_12, Luosi_20, …,M就是产品等级的数量
——一共有M*N子类, N个抽象类,1个接口
扩展产品族只需要增加一个AbstractXXX, 和M个产品等级的子类
2、当产品等级需要可扩展时:
基本上增加产品族,就相当于增加产品线,
这不容易,但是增加产品等级,不需要扩展产品线,只要在
原先产品线上增加个等级就行
对于工厂而言:
——有个最大接口:AbstractFactory
——生产一个产品族,需要一个车间,就是一个XXXFactory,所以:
螺丝_Factory{
create_10号螺丝();
create_12号螺丝();
create_20号螺丝();
}
铁板_Factory{
create_10号铁板();
create_12号铁板();
create_20号铁板();
}
门把手_Factory{
create_10号门把手();
create_12号门把手();
create_20号门把手();
}
增加一个零件,就是增加一个产品族:
增加一个产品等级,如30号门把手
//人类的统一接口
public interface IHuman {
void say();
void getColor();
}
//实现类:黑人
public class BlackHuman implements IHuman{
@Override
public void say() {
System.out.println("我是黑种人");
}
@Override
public void getColor() {
System.out.println("黑色皮肤");
}
}
//实现类:黄人
public class YellowHuman implements IHuman{
@Override
public void say() {
System.out.println("我是黄种人");
}
@Override
public void getColor() {
System.out.println("黄色皮肤");
}
}
//白人略过...
//此时女娲造人,需要依赖于具体实现类
public static void main(String[] args) {
//===造白人
IHuman wh = new WhiteHuman();
wh.getColor();
wh.say();
//===造黑人
IHuman bh = new BlackHuman();
bh.getColor();
bh.say();
}
//加上个简单工厂:
public class HumanFactory{
public static <T extends IHuman> T createHuman(Class<T> clazz) {
IHuman human = null;
try{
human = clazz.newInstance();
}catch(Exception e){
e.printStackTrace();
System.out.println("生成错误");
}
return (T)human;
}
}
//现在女娲是这样工作:
public static void main(String[] args) {
//===造白人
IHuman wh = HumanFactory.createHuman(WhiteHuman.class);
wh.getColor();
wh.say();
//===造黑人
IHuman bh = HumanFactory.createHuman(BlackHuman.class);
bh.getColor();
bh.say();
//===造黄人
IHuman yh = HumanFactory.createHuman(YellowHuman.class);
yh.getColor();
yh.say();
}
代码还是类似简单工厂,因为产品体系还是很简单,就是给工厂多了个接口
public abstract class AbstractHumanFactory {
public abstract <T extends IHuman> T createHuman(Class<T> clazz);
}
public class HumanFactory extends AbstractHumanFactory{
@Override
public <T extends IHuman> T createHuman(Class<T> clazz) {
IHuman human = null;
try{
human = clazz.newInstance();
}catch(Exception e){
e.printStackTrace();
System.out.println("生成错误");
}
return (T)human;
}
}
女娲端的代码如下:
public static void main(String[] args) {
AbstractHumanFactory factory = new HumanFactory();
//===造白人
IHuman wh = factory.createHuman(WhiteHuman.class);
wh.getColor();
wh.say();
//===造黑人
IHuman bh = factory.createHuman(BlackHuman.class);
bh.getColor();
bh.say();
//===造黄人
IHuman yh = factory.createHuman(YellowHuman.class);
yh.getColor();
yh.say();
}
///===============定义产品族:男女===================///
public class AbstractMan implements IHuman{
}
public class AbstractWomen implements IHuman{
}
///===============定义产品等级:以男人为例=============///
public YellowMan extends AbstractMan{
}
///===============定义抽象工厂,每个产品族对应一个工厂,所以男人一个,女人一个===///
public abstract class AbstractHumanFactory {
public abstract IHuman createYellow();
public abstract IHuman createBlack();
public abstract IHuman createWhite();
}
public ManFactory extends AbstractHumanFactory{
}
public WomanFactory extends AbstractHumanFactory{
}