在设计模式中建造者模式是一种创建型模式
创建者模式:将复杂的生产过程与产品表现本身进行分离,使同样的生产过程产生不同的产品,对两者进行解耦
创建者模式分为四个角色:
Builder(抽象建造者):它为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是getResult(),它们用于返回复杂对象。Builder既可以是抽象类,也可以是接口。
ConcreteBuilder(具体建造者):它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。
Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中。
例:我们以电脑的创建为例
通俗的讲:
产品类:电脑生产需要的零件
抽象建造者:电脑零件设计图中和产品交付书
具体建造者:按图设计零件
指挥者:依照零件组装电脑
总体UML图:
产品角色:
//品牌 private String Brand; //CPU private String CPU; //主板 private String Mainboard; //显卡 private String Graphics; public String getBrand() { return Brand; } public void setBrand(String brand) { Brand = brand; } public String getCPU() { return CPU; } public void setCPU(String cPU) { CPU = cPU; } public String getMainboard() { return Mainboard; } public void setMainboard(String mainboard) { Mainboard = mainboard; } public String getGraphics() { return Graphics; } public void setGraphics(String graphics) { Graphics = graphics; } @Override public String toString() { return "computerproduct [Brand=" + Brand + ", CPU=" + CPU + ", Mainboard=" + Mainboard + ", Graphics=" + Graphics + "]"; }
抽象建造者:
//组合一个产品对象 computerproduct computer=new computerproduct(); //创建品牌 public abstract void builderBrand(); //创建CPU public abstract void builderCPU(); //创建显卡 public abstract void builderGraohics(); //创建主板 public abstract void builderMainboard(); public computerproduct getcomputers() { //返回具体对象 return computer; }
具体建造者(这里写了两个建造者):
建造者1:
//创建一个机械师电脑 @Override public void builderBrand() { // TODO Auto-generated method stub computer.setBrand("机械师(深海幽灵)"); } @Override public void builderCPU() { // TODO Auto-generated method stub computer.setCPU("intel i7"); } @Override public void builderGraohics() { // TODO Auto-generated method stub computer.setGraphics("GTX2070 独立8GB"); } @Override public void builderMainboard() { // TODO Auto-generated method stub computer.setMainboard("深海主板"); }
建造者2:
//华硕,飞行堡垒 @Override public void builderBrand() { // TODO Auto-generated method stub computer.setBrand("华硕(飞行堡垒)"); } @Override public void builderCPU() { // TODO Auto-generated method stub computer.setCPU("intel i7"); } @Override public void builderGraohics() { // TODO Auto-generated method stub computer.setGraphics("GTX2070 独立8GB"); } @Override public void builderMainboard() { // TODO Auto-generated method stub computer.setMainboard("华硕主板"); }
指挥者:
abstractbuildercomputer computer; public Directorcomputer(abstractbuildercomputer computer) { this.computer=computer; } public computerproduct getcomputer1() { computer.builderBrand(); computer.builderCPU(); computer.builderGraohics(); computer.builderMainboard(); return computer.getcomputers(); }
测试类:
public static void main(String[] args) { concretenessbuildercomputer2 a=new concretenessbuildercomputer2(); Directorcomputer my=new Directorcomputer(a); System.out.print(my.getcomputer1().toString()); }
输出结果:
computerproduct [Brand=华硕(飞行堡垒), CPU=intel i7, Mainboard=华硕主板, Graphics=GTX2070 独立8GB]
建造者模式的主要优点:
- 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
- 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。由于指挥者类针对抽象建造者编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便,符合 "开闭原则"。
- 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
建造者模式的主要缺点:
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,例如很多组成部分都不相同,不适合使用建造者模式,因此其使用范围受到一定的限制。
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,增加系统的理解难度和运行成本。
一,StringBuilder源码解析
StringBuilder是创建者模式的一个典型案例,但它根标准的建造者模式也出入
stringbuilder继承的类和实现的接口:
这里我们只看AbstractStringBuilder类结构
AbstractStringBuilder继承了Appendable, CharSequence,因为CharSequence是char
值的可读序列不做为建造者我们忽略
Appendable源码:
public interface Appendable { Appendable append(CharSequence var1) throws IOException; Appendable append(CharSequence var1, int var2, int var3) throws IOException; Appendable append(char var1) throws IOException; }
它定义了append规则
AbstractStringBuilder源码一部分:
public AbstractStringBuilder append(Object obj) { return this.append(String.valueOf(obj)); } public AbstractStringBuilder append(String str) { if (str == null) { return this.appendNull(); } else { int len = str.length(); this.ensureCapacityInternal(this.count + len); this.putStringAt(this.count, str); this.count += len; return this; } } public AbstractStringBuilder append(StringBuffer sb) { return this.append((AbstractStringBuilder)sb); }
它实现了Appendable的append方法
StringBuilder源码:
public StringBuilder append(Object obj) { return this.append(String.valueOf(obj)); } @HotSpotIntrinsicCandidate public StringBuilder append(String str) { super.append(str); return this; } public StringBuilder append(StringBuffer sb) { super.append(sb); return this; } public StringBuilder append(CharSequence s) { super.append(s); return this; } public StringBuilder append(CharSequence s, int start, int end) { super.append(s, start, end); return this; }
基本上所有方法都通过super()调用了父类,并返回了自己本身
在StringBuilder中,Appendable做为抽象创建者,AbstractStringBuilder属于具体创建者,StringBuilder即是产品类也是指挥者
二,StringBuffer源码
StringBuffer的继承类
它和StringBuilder一样都是继承AbstractStringBuilder类,实现接口也是一样的
但看它的一部分源码:
public synchronized int compareTo(StringBuffer another) { return super.compareTo(another); } public synchronized int length() { return this.count; } public synchronized int capacity() { return super.capacity(); } public synchronized void ensureCapacity(int minimumCapacity) { super.ensureCapacity(minimumCapacity); } public synchronized void trimToSize() { super.trimToSize(); } public synchronized void setLength(int newLength) { this.toStringCache = null; super.setLength(newLength);
前面都加了synchronized关键字,以此得知它和StringBuilder相比它是线程安全的,而StringBuilder是非线程安全的(其他功能一致)
Comments | NOTHING
Warning: Undefined variable $return_smiles in /www/wwwroot/wql_luoqin_ltd/wp-content/themes/Sakura/functions.php on line 1109