1. 程式人生 > >不一樣的建造者模式(設計模式二十一)

不一樣的建造者模式(設計模式二十一)

### 前言 什麼是建造者模式?它是建立型,面臨的問題是一個物件的建立較為複雜,是由其子部分通過某種演算法組成的,它的子部分是變化的,但是其演算法是穩定的。這個是非常常見的一種設計模式,後面會舉例子,演化各種構建方式的歷史程序。 ### 正文 比如說,有一臺電腦: ``` 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 { 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 { 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 { public ComputerBuilder computerBuilder; public ComputerDirector(ComputerBuilder 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(); ``` 是不是更加眼熟了? 構建方式很多,看具體情況,複雜程度來。 ### 結 感覺萬變不離其宗吧,需求就是希望構建和物件分開。上述只是個人的一些理解,如果不對望請