前言
什麼是建造者模式?它是建立型,面臨的問題是一個物件的建立較為複雜,是由其子部分通過某種演算法組成的,它的子部分是變化的,但是其演算法是穩定的。這個是非常常見的一種設計模式,後面會舉例子,演化各種構建方式的歷史程式。
正文
比如說,有一臺電腦:
public abstract class Computer
{
public void init()
{
//處理 part1 part2 part3 part4 part5 的組裝
}
public abstract void part1();
public abstract void part2();
public abstract void part3();
public abstract void part4();
public abstract void part5();
}
把電腦作為抽象類。要製造5個部分,然後init是組裝,電腦組裝步驟一樣,是穩定的部分。
然後具體的實現類如下:
class HuweiComputer : Computer
{
public override void part1()
{
throw new NotImplementedException();
}
public override void part2()
{
throw new NotImplementedException();
}
public override void part3()
{
throw new NotImplementedException();
}
public override void part4()
{
throw new NotImplementedException();
}
public override void part5()
{
throw new NotImplementedException();
}
}
這樣似乎沒有問題,同樣也突出了我們的重點,達到了 它的子部分是變化的,但是其演算法是穩定的,如果是一般簡單的到這裡也就結束了。
但是有一個問題,那就是類態臃腫了,我們可以去看.net core服務的構建,它很龐大,但是沒有臃腫。那麼接下來,就可以實現構建和物件分開,就是物件的構建提取出去,不要成為類的負擔。
其實在最理想的情況下是物件的構建本來就應該和物件分開,最好是物件方法同樣要和物件分開,但是呢這樣會造成難以維護。
public abstract class ComputerBuilder
{
protected Computer computer;
public void init()
{
//處理 part1 part2 part3 part4 part5 的組裝
}
public Computer GetComputer()
{
return computer;
}
public abstract void part1();
public abstract void part2();
public abstract void part3();
public abstract void part4();
public abstract void part5();
}
public class Computer
{
}
那麼具體的HuweiComputer 這樣寫。
public class HuweiComputerBuilder : ComputerBuilder
{
public HuweiComputerBuilder()
{
computer = new Computer();
}
public override void part1()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part2()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part3()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part4()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part5()
{
//呼叫Computer操作
throw new NotImplementedException();
}
}
然後獲取到華為電腦的時候這樣寫:
HuweiComputerBuilder builder=new HuweiComputerBuilder ();
Computer huaweiComputer builder.init().GetComputer();
然後還可以再優化一下,把構建演算法和構建部分分開。
public class Computer
{
}
public abstract class ComputerBuilder
{
protected Computer computer;
public Computer GetComputer()
{
return computer;
}
public abstract void part1();
public abstract void part2();
public abstract void part3();
public abstract void part4();
public abstract void part5();
}
public class HuweiComputerBuilder : ComputerBuilder
{
public HuweiComputerBuilder()
{
computer = new Computer();
}
public override void part1()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part2()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part3()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part4()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part5()
{
//呼叫Computer操作
throw new NotImplementedException();
}
}
public class ComputerDirector
{
public ComputerBuilder computerBuilder;
public ComputerDirector(ComputerBuilder computerBuilder)
{
this.computerBuilder = computerBuilder;
//原來builder的init computerBuilder
}
public Computer GetComputer()
{
return computerBuilder.GetComputer();
}
}
增加一個嚮導器ComputerDirector把init 構建部分分開。那麼呼叫方式就是。
HuweiComputerBuilder huweiComputerBuilder =new HuweiComputerBuilder();
ComputerDirector computerDirector=new ComputerDirector(huweiComputerBuilder);
computerDirector.GetComputer();
這樣寫的考慮是以後構建演算法可能很多,便於init的橫向擴充套件。
思想到這裡基本是結束的,但是沒有結合到實際複雜的業務中。
我們看到這麼寫的也少,因為呢,比如這裡的電腦,任何不同牌子的電腦多多少少會有一些特色。那麼可能就有很多實體類,那麼寫法就得變化。
public class Computer
{
}
public class HuaweiComputer
{
//一些屬性,方法
}
public abstract class ComputerBuilder<T>
{
public abstract T GetComputer();
public abstract void part1();
public abstract void part2();
public abstract void part3();
public abstract void part4();
public abstract void part5();
}
public class HuweiComputerBuilder : ComputerBuilder<HuaweiComputer>
{
private HuaweiComputer computer;
public HuweiComputerBuilder()
{
computer = new HuaweiComputer();
}
public override HuaweiComputer GetComputer()
{
return computer;
}
public override void part1()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part2()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part3()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part4()
{
//呼叫Computer操作
throw new NotImplementedException();
}
public override void part5()
{
//呼叫Computer操作
throw new NotImplementedException();
}
}
public class ComputerDirector<T>
{
public ComputerBuilder<T> computerBuilder;
public ComputerDirector(ComputerBuilder<T> computerBuilder)
{
this.computerBuilder = computerBuilder;
//原來builder的init computerBuilder
}
public T GetComputer()
{
return computerBuilder.GetComputer();
}
}
因為HuaweiComputer-》ComputerBuilder 是垂直分散的,如果可變現性(橫向擴充套件Computer或者init演算法)沒有那麼複雜的話,那麼可以這樣寫。
public class HuaweiComputer2
{
public static class HuweiComputerBuilder
{
public static HuaweiComputer GetComputer()
{
var computer =new HuaweiComputer();
//init
return computer;
}
private static void part1()
{
//呼叫Computer操作
throw new NotImplementedException();
}
private static void part2()
{
//呼叫Computer操作
throw new NotImplementedException();
}
private static void part3()
{
//呼叫Computer操作
throw new NotImplementedException();
}
private static void part4()
{
//呼叫Computer操作
throw new NotImplementedException();
}
private static void part5()
{
//呼叫Computer操作
throw new NotImplementedException();
}
}
}
那麼寫法可以這樣:
HuaweiComputer2.HuweiComputerBuilder.GetComputer();
如果把GetComputer理解為builder 是不是就非常熟悉了?
如果複雜一點,需要做一些配置可以這樣寫:
public class HuaweiComputer2
{
private string config;
private HuaweiComputer2()
{
}
public static HuweiComputerBuilder getBuilder()
{
return new HuweiComputerBuilder();
}
public class HuweiComputerBuilder
{
private HuaweiComputer2 huaweiComputer2;
public HuweiComputerBuilder()
{
huaweiComputer2 = new HuaweiComputer2();
}
public HuaweiComputer GetComputer()
{
var computer =new HuaweiComputer();
//init
return computer;
}
public HuweiComputerBuilder setConfig(string config)
{
huaweiComputer2.config = config;
return this;
}
private void part1()
{
//呼叫Computer操作
throw new NotImplementedException();
}
private void part2()
{
//呼叫Computer操作
throw new NotImplementedException();
}
private void part3()
{
//呼叫Computer操作
throw new NotImplementedException();
}
private void part4()
{
//呼叫Computer操作
throw new NotImplementedException();
}
private void part5()
{
//呼叫Computer操作
throw new NotImplementedException();
}
}
}
那麼獲取方式為:
HuaweiComputer2.getBuilder().setConfig("").GetComputer();
是不是更加眼熟了?
構建方式很多,看具體情況,複雜程度來。
結
感覺萬變不離其宗吧,需求就是希望構建和物件分開。上述只是個人的一些理解,如果不對望請指出。