

————— 第二天 —————









————————————










首先,我們來定義一個Product類:
public class Product {
ArrayList<String> parts = new ArrayList<String>();
public void add(String part) {
parts.add(part);
}
public void show() {
System.out.println(parts);
}
}
接下來,我們定義抽象的Builder類:
public abstract class Builder {
public abstract void buildPartA();
public abstract void buildPartB();
public abstract Product getResult() ;
}
然后,是具體的Builder實作類:
public class ConcreteBuilder extends Builder {
private Product product = new Product();
public Product getResult() {
return product;
}
@Override
public void buildPartA() {
product.add("構建產品的上半部分");
}
@Override
public void buildPartB() {
product.add("構建產品的下半部分");
}
}
在Builder類之外,則是Director類來控制Builder的生產程序:
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void construct() {
builder.buildPartA();
builder.buildPartB();
}
}
最后,是客戶端的測驗代碼:
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.getResult();
product.show();
我們來看一下運行的結果:
[構建產品的上半部分, 構建產品的下半部分]



// 默認采用Builder進行建造
public OkHttpClient() {
this(new Builder());
}
// 由builder配置分發器、代理、協議以及自定義攔截器等
OkHttpClient(Builder builder) {
this.dispatcher = builder.dispatcher;
this.proxy = builder.proxy;
this.protocols = builder.protocols;
/** 省略大段代碼 */
boolean isTLS = false;
for (ConnectionSpec spec : connectionSpecs) {
isTLS = isTLS || spec.isTls();
}
/** 省略大段代碼. */
if (interceptors.contains(null)) {
throw new IllegalStateException("Null interceptor: " + interceptors);
}
if (networkInterceptors.contains(null)) {
throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
}
}
public static final class Builder {
public Builder() {
// 分發器、協議、代理的默認引數
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
proxySelector = ProxySelector.getDefault();
if (proxySelector == null) {
proxySelector = new NullProxySelector();
}
}
Builder(OkHttpClient okHttpClient) {
// 反向配置分發器、代理、協議
this.dispatcher = okHttpClient.dispatcher;
this.proxy = okHttpClient.proxy;
this.protocols = okHttpClient.protocols;
// 新增所有自定義攔截器和自定義網路攔截器
this.interceptors.addAll(okHttpClient.interceptors);
this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
}
// 配置代理
public Builder proxy(@Nullable Proxy proxy) {
this.proxy = proxy;
return this;
}
// 向攔截器鏈中增加自定義攔截器
public Builder addInterceptor(Interceptor interceptor) {
if (interceptor == null) throw new IllegalArgumentException("interceptor == null");
interceptors.add(interceptor);
return this;
}
// 最后是build()方法,生成OkHttpClient物件
public OkHttpClient build() {
return new OkHttpClient(this);
}
}


/**將指定的字串追加到此字符序列*/
@Override
public StringBuilder append(CharSequence s) {
super.append(s);// 實作程序略
return this;
}
/**將此字符序列用其反轉形式取代*/
@Override
public StringBuilder reverse() {
super.reverse();// 實作程序略
return this;
}
下面讓我們來撰寫一下測驗代碼:
StringBuilder sb = new StringBuilder("若為自由故");
sb.append("只要主義真");
sb.reverse();
System.out.println(sb);
StringBuilder sb1 = new StringBuilder("若為自由故");
sb1.reverse();
sb1.append("只要主義真");
System.out.println(sb1);
測驗結果如下:
System.out: 真義主要只故由自為若
System.out: 故由自為若只要主義真








建造者模式與簡單工程模式的區別,在于建造者模式多出一個Builder類,使得創建物件的靈活性大大增加,適用于如下場景:
(1)創建一個物件,多個同樣的方法的呼叫順序不同,產生的結果不同
(2)創建一個物件,特別復雜,引數多,而且很多引數都有默認值




System.out.println("Hello World");




短短一行代碼,背后有什么樣的機制呢?
Java的編譯原理,是將Hello.java編譯成能被VM理解的Hello.class,然后再轉化為能被不同硬體設備理解的bytecode進而執行的,
著名的位元組碼增強框架ASM,就是在Hello.java編譯成Hello.class時可以讀取并分析類資訊、改變類行為、增強類功能甚至生成新的類的bytecode分析和操作框架,
我們來看一下相關的代碼,代碼當中的mv,來自ASM框架的MethodVisitor介面,
// 訪問System類的型別為PrintSystem型別的靜態變數out
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
// 訪問常量池中的資料"Hello World"
mv.visitLdcInsn("Hello World");
// 呼叫PrintStream類的println()方法并把剛才獲取到的物件當做String型別的引數傳入
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);





轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/293169.html
標籤:java
