不一样的建造者模式(设计模式二十一)
前言
什么是建造者模式?它是创建型,面临的问题是一个对象的创建较为复杂,是由其子部分通过某种算法组成的,它的子部分是变化的,但是其算法是稳定的。这个是非常常见的一种设计模式,后面会举例子,演化各种构建方式的历史进程。
正文
比如说,有一台电脑:
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();
是不是更加眼熟了?
构建方式很多,看具体情况,复杂程度来。
结
感觉万变不离其宗吧,需求就是希望构建和对象分开。上述只是个人的一些理解,如果不对望请指出。