本文的内容基本来自How To Design a (module) API,下面是我对里面涉及代码的一个实现。
 
1:Allow access only from a friend code
SPI:Service Provider Interface
API 和SPI的区别:
In case of an API that is offering methods to clients, there is no problem with additions. Extending the functionality to offer more functionality to clients cannot hurt them - if they do not want they do not need to use it.

In the cas of an SPI, the situation is exactly the oposite. Adding new method into an interface that others must provide effectively breaks all existing implementations, because they do not implement it! On the other hand it acceptable and valid to stop calling (de facto removal) a method from an SPI. If the operation flow is not part of the contract, not calling one method should not break anything.
 
API additions are fine but removing functionality is not; SPI de-facto removals are allowed, but additions are not.
 
代码接口如下:
src
├─apipkg
│AccessorImpl.java
│Item.java
├─implpkg
│Accessor.java
│Test.java
首先创建一个ITEM类,该类只允许同一个包才能访问
package apipkg;


public final class Item {
  private int value;

  static {
    // register bridge for implpkg
    new AccessorImpl();
  }

  /** Contructor for friends */
  Item() {
  }

  public void setValue(int x) {
    value = x;
  }

  public int getValue() {
    return value;
  }
}
为了其他的包(如implpkg)的类也能访问ITEM类,创建了Accessor
package implpkg;

import apipkg.Item;

public abstract class Accessor {
  private static Accessor DEFAULT;
  static {
    try {
      Class.forName(Item.class.getName(), true, Item.class.getClassLoader());
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  public Accessor() {
    assert DEFAULT == null;
    assert getClass().getName().equals("apipkg.AccessorImpl");
    DEFAULT = this;
  }

  public static Accessor getDefault() {
    return DEFAULT;
  }

  protected abstract Item newItem();
}
之后在apipkg下面添加对应的实现类:
package apipkg;

import implpkg.Accessor;

final class AccessorImpl extends Accessor {
  protected Item newItem() {
    return new Item();
  }
}
测试:
package implpkg;

import apipkg.Item;

public class Test {
  public static void main(String[] args) {
    Item item = Accessor.getDefault().newItem();
    item.setValue(10);
    System.out.println(item.getValue());;
  }
}
 
2:Interfaces vs. abstract classes
代码结构如下:
src
├─abintf
│├─impl
││InsCookieImpl.java
││InsCookieImpl2.java
││InsCookieImpl3.java
││Test.java
│└─intf
│InstanceCookie.java
│InstanceCookie2.java
创建一个接口InstanceCookie:
package abintf.intf;

public interface InstanceCookie {
  public String instanceName();

  public Class instanceClass();

  public Object instanceCreate();

}
接口的实现类:
package abintf.impl;

import abintf.intf.InstanceCookie;

public class InsCookieImpl implements InstanceCookie {

  public Class instanceClass() {
    return InsCookieImpl.class;
  }

  public Object instanceCreate() {
    return new InsCookieImpl();
  }

  public String instanceName() {
    return InsCookieImpl.class.getName();
  }
}
测试该实现:
    InstanceCookie isCookie = new InsCookieImpl();
    System.out.println(isCookie.instanceName());
输出:
abintf.impl.InsCookieImpl
 
---------------------------------------------------------------------------------------------
 
之后需要在接口中添加instanceOf方法,为保证原有代码不变,在原接口中添加了内部Info接口,修改后的接口如下:
package abintf.intf;

public interface InstanceCookie {
  public String instanceName();

  public Class instanceClass();

  public Object instanceCreate();

  public interface Of extends InstanceCookie {
    public boolean instanceOf(Class type);
  }
}
修改后接口的实现类:
package abintf.impl;

import abintf.intf.InstanceCookie;

public class InsCookieImpl2 implements InstanceCookie.Of {

  public Class instanceClass() {
    return InsCookieImpl2.class;
  }

  public Object instanceCreate() {
    return new InsCookieImpl2();
  }

  public String instanceName() {

    return InsCookieImpl2.class.getName();
  }

  public boolean instanceOf(Class type) {
    return InsCookieImpl2.class.equals(type);
  }

}
测试该实现类:
    InstanceCookie isCookie2 = new InsCookieImpl2();
    System.out.println(isCookie2.instanceName());
    if (isCookie2 instanceof InstanceCookie.Of) {
      boolean bool1 = ((InstanceCookie.Of) isCookie2).instanceOf(InsCookieImpl2.class);
      System.out.println(bool1);
      bool1 = ((InstanceCookie.Of) isCookie2).instanceOf(InsCookieImpl.class);
      System.out.println(bool1);
    }
输出:
abintf.impl.InsCookieImpl2
true
false
------------------------------------------------------------------------------------
接口设计的改进:
package abintf.intf;

public interface InstanceCookie2 {
  public Info instanceInfo();

  public static final class Info {
    private String intanceName;

    private Class instanceClass;

    public String getIntanceName() {
      return intanceName;
    }

    public void setIntanceName(String intanceName) {
      this.intanceName = intanceName;
    }

    public Class getInstanceClass() {
      return instanceClass;
    }

    public void setInstanceClass(Class instanceClass) {
      this.instanceClass = instanceClass;
    }

    public Object instanceCreate() {
      Object obj = null;
      try {
        if (this.instanceClass != null) {
          obj = instanceClass.newInstance();
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
      return obj;
    }

    public boolean instanceOf(Class type) {
      return type != null ? type.equals(this.instanceClass) : false;
    }
  }
}
实现该接口:
package abintf.impl;

import abintf.intf.InstanceCookie2;

public class InsCookieImpl3 implements InstanceCookie2 {

  public Info instanceInfo() {
    Info info = new Info();
    info.setInstanceClass(InsCookieImpl3.class);
    info.setIntanceName(InsCookieImpl3.class.getName());
    return info;
  }

}
 
测试该实现类:
    InstanceCookie2 isCookie3 = new InsCookieImpl3();
    Info info = isCookie3.instanceInfo();
    System.out.println(info.getIntanceName());
    System.out.println(info.instanceOf(InsCookieImpl3.class));
    System.out.println(info.instanceOf(InsCookieImpl.class));
输出:
abintf.impl.InsCookieImpl3
true
false