不一样的建造者模式(设计模式二十一)

前言

什么是建造者模式?它是创建型,面临的问题是一个对象的创建较为复杂,是由其子部分通过某种算法组成的,它的子部分是变化的,但是其算法是稳定的。这个是非常常见的一种设计模式,后面会举例子,演化各种构建方式的历史进程。

正文

比如说,有一台电脑:

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();

是不是更加眼熟了?

构建方式很多,看具体情况,复杂程度来。

感觉万变不离其宗吧,需求就是希望构建和对象分开。上述只是个人的一些理解,如果不对望请指出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章