码农小汪-设计模式之-Builder模式
建造者模式
将一个复杂的对象的构建与它的表示分离,使得同样构建的过程中可以创建不同的表示。这个话语看起来,好累啊!真心很难理解。
下面是它的UML图:
抽象建造者角色(Builder):为创建一个Product对象的各个部件指定抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此角色规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
具体建造者(ConcreteBuilder)
1)实现Builder的接口以构造和装配该产品的各个部件。即实现抽象建造者角色Builder的方法。
2)定义并明确它所创建的表示,即针对不同的商业逻辑,具体化复杂对象的各部分的创建
3) 提供一个检索产品的接口
4) 构造一个使用Builder接口的对象即在指导者的调用下创建产品实例
指导者(Director):调用具体建造者角色以创建产品对象的各个部分。指导者并没有涉及具体产品类的信息,真正拥有具体产品的信息是具体建造者对象。它只负责保证对象各部分完整创建或按某种顺序创建。
产品角色(Product):建造中的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产品的接口。
在大话设计模式中的例子说的比较的不错,我们也跟着说说:
- 第一个例子
吃饭的时候,菜饭的味道不够,鸡蛋比较的少啊,怎么回事呢?每个厨师的下味道肯定不一样啊,我们也要赚钱呢。对比。肯德基,每一家店的味道都是一致的,很规范。
我们吃的舒服,吃的安逸的主要是依赖于厨师做的怎么样!
依赖倒置原则:抽象不应该依赖细节,细节应该依赖于抽象。(面向接口编程)
我们吃的饭都是依赖于我们的厨师,所以我们很被动。
- 第二个例子
画一个小人,要求有头,手,脚。就行了
Pen p = new Pen(Color.Yellow);Graphics gThin = pictureBox1.CreateGraphics();gThin.DrawEllipse(p, 50, 20, 30, 30);头
gThin.DrawRectangle(p, 60, 50, 10, 50);身体
gThin.DrawLine(p, 60, 50, 40, 100);左手
gThin.DrawLine(p, 70, 50, 90, 100);右手
gThin.DrawLine(p, 60, 100, 45, 150);左脚
gThin.DrawLine(p, 70, 100, 85, 150);右脚
又要画个胖的小人,可惜啊,代码不能复用。画着画着少了一只腿。。。
这个和我们刚刚的老板少放了盐有什么区别呢?不管你是蛋炒饭,土豆肉丝饭,还是其他的盐必须得有啊。我们的画人程序也是一样的,不管你是胖的,瘦的,还是其他的情况。我们的人物基本的东西,都得存在啊,比如头,手,脚。这些都是构建一个人物必须拥有的啊!对于胖的,这个只是人物的一种表现形式!
有做了一个改进,不是分离嘛,我创建个瘦子类和胖子类,画的时候就行了,肯定不会错的。但是这个问题导致很严重啊,我还有各种各样的情况啊,高个的小人,短发的小人…帅气的人。表现人的品质有很多啊。都需要一一的去实现这些子类?这种够造的复杂性,就造就了我们的Builder模式的产生。不管小人,大人。我们都是有手,脚的。呵呵。我才不去管你到底怎么的。复杂的对象的构建与它的表示分离使得构建过程可以产生不同的表示哦
Builer模式就是为了构建复杂的对象的!
我们继续构建小人:
定义一个抽象的人类,可以画头身体左右手等等,子类的瘦子必须实行这些方法。
abstract class PersonBuilder
{protected Graphics g;protected Pen p;public PersonBuilder(Graphics g, Pen p){this.g = g;this.p = p;}public abstract void BuildHead();public abstract void BuildBody();public abstract void BuildArmLeft();public abstract void BuildArmRight();public abstract void BuildLegLeft();public abstract void BuildLegRight();
}
一个具体的人物
class PersonThinBuilder : PersonBuilder //无论胖的瘦的都可以
{public PersonThinBuilder(Graphics g, Pen p): base(g, p){ }public override void BuildHead(){g.DrawEllipse(p, 50, 20, 30, 30);}public override void BuildBody(){g.DrawRectangle(p, 60, 50, 10, 50);}public override void BuildArmLeft(){g.DrawLine(p, 60, 50, 40, 100);}public override void BuildArmRight(){g.DrawLine(p, 70, 50, 90, 100);}public override void BuildLegLeft(){g.DrawLine(p, 60, 100, 45, 150);}public override void BuildLegRight(){g.DrawLine(p, 70, 100, 85, 150);}
}
这个是指挥我们工作的人,依赖于抽象。面向接口编程。无论你是怎么样的人,我都会以一样的流程构建,不会缺少什么!
class PersonDirector
{private PersonBuilder pb;public PersonDirector(PersonBuilder pb){this.pb = pb;}public void CreatePerson()//构建人物类!{pb.BuildHead();pb.BuildBody();pb.BuildArmLeft();pb.BuildArmRight();pb.BuildLegLeft();pb.BuildLegRight();}
}
很多具体的细节都需要我们去继承BuilderPerson,构建的方法必须适合所有的子类哦
Pen p = new Pen(Color.Yellow);
PersonThinBuilder ptb = new PersonThinBuilder(pictureBox1.CreateGraphics(), p);
PersonDirector pdThin = new PersonDirector(ptb);//指导者创建了一个瘦人啊~~
pdThin.CreatePerson();
再来看看我们的实践呢! Android中这个比价常见~
我们通过一个例子来引出Builder模式。假设有一个Person类,我们通过该Person类来构建一大批人,这个Person类里有很多 属性,最常见的比如name,age,weight,height等等,并且我们允许这些值不被设置,也就是允许为null,该类的定义如下。
public class Person {private String name;private int age;private double height;private double weight;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}
}
我们构建这个Person可能有很多情况吧!
我们的够造函数可能是出奇的多,各种复杂
public Person(String name, int age, double height, double weight) {this.name = name;this.age = age;this.height = height;this.weight = weight;}
public Person() {}
public Person(String name) {this.name = name;
}
public Person(String name, int age) {this.name = name;this.age = age;
}
public Person(String name, int age, double height) {this.name = name;this.age = age;this.height = height;
}
这个样子,我们就可以构建各种new 方式
Person p1=new Person();
Person p2=new Person("小李");
Person p3=new Person("李四",18);
Person p4=new Person("小汪",21,180);
Person p5=new Person("赵六",17,170,65.4);
可以想象一下这样创建的坏处,最直观的就是四个参数的构造函数的最后面的两个参数到底是什么意思,可读性不怎么好,如果不点击看源码,鬼知道哪个是weight哪个是height。还有一个问题就是当有很多参数时,编写这个构造函数就会显得异常麻烦,这时候如果换一个角度,试试Builder模式,你会发现代码的可读性一下子就上去了。
我们给Person增加一个静态内部类Builder类,并修改Person类的构造函数,代码如下。
public class Person {private String name;private int age;private double height;private double weight;privatePerson(Builder builder){this.name=builder.name;this.age=builder.age;this.height=builder.height;this.weight=builder.weight;}
public String getName(){return name;}
public void setName(String name){this.name = name;
}
public int getAge(){return age;}
public void setAge(int age){this.age = age;}
public double getHeight(){return height;}
public void setHeight(double height){this.height = height;}
public double getWeight() {return weight;}
public void setWeight(double weight){this.weight = weight;} static class Builder{private String name;private int age;private double height;private double weight;public Builder name(String name){this.name=name;return this;}public Builder age(int age){this.age=age;return this;}public Builder height(double height){this.height=height;return this;}public Builder weight(double weight){this.weight=weight;return this;}public Person build(){return new Person(this);}}
}
从上面的代码中我们可以看到,我们在Builder类里定义了一份与Person类一模一样的变量,通过一系列的成员函数进行设置属性值,但是返回值都是this,也就是都是Builder对象,最后提供了一个build函数用于创建Person对象,返回的是Person对象,对应的构造函数在Person类中进行定义,也就是构造函数的入参是Builder对象,然后依次对自己的成员变量进行赋值,对应的值都是Builder对象中的值。此外Builder类中的成员函数返回Builder对象自身的另一个作用就是让它支持链式调用,使代码可读性大大增强。
构建的可读性大大的增强~~
Person.Builder builder=new Person.Builder();
Person person=builder.name("张三").age(18).height(178.5).weight(67.4).build();
定义一个静态内部类Builder,内部的成员变量和外部类一样。Builder类通过一系列的方法用于成员变量的赋值,并返回当前对象本身(this)。Builder类提供一个build方法或者create方法用于创建对应的外部类,该方法内部调用了外部类的一个私有构造函数,该构造函数的参数就是内部类Builder。外部类提供一个私有构造函数供内部类调用,在该构造函数中完成成员变量的赋值,取值为Builder对象中对应的值
码农小汪-设计模式之-Builder模式相关推荐
- 码农小汪-设计模式之-命令模式
大话设计模式的例子讲的非常的好,理解起来也方便!有时候忘了.想到这些特殊的例子感觉就是特别爽. 烤羊肉串带来的思考! 路边摊羊肉串: 老板,我这里排的比较先啊,我最先给钱.老板这个没有熟啊.我的是 辣 ...
- 小话设计模式:Builder模式
尊重他人的劳动成果,转载请标明出处:http://blog.csdn.net/gengqiquan/article/details/52764455, 本文出自:[gengqiquan的博客] 有一天 ...
- 码农小汪-Hibernate学习8-hibernate关联关系注解表示@OneToMany mappedBy @ManyToMany @JoinTable...
近期我也是有点郁闷,究竟是程序中处理关联关系.还是直接使用外键处理关联关系呢?这个的说法不一致!程序中处理这样的关联关系的话.自己去维护这样的约束.这样的非常乐观的一种做法!或者是直接在数据库中处理这 ...
- 码农小汪-Volatile和Transient
Volatile: Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在任何时刻,两个不同的线程总是看 ...
- Android设计模式之——Builder模式
一.介绍 Builder模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构造流程.该模式是为了将构建复杂对象的过程和它的部件解耦,使得构建过程 ...
- Java 设计模式之Builder模式
设计模式系列 创建型设计模式 Java 设计模式之单例模式 Java 设计模式之静态工厂方法模式 Java 设计模式之工厂方法模式 Java 设计模式之抽象工厂模式 Java 设计模式之Builder ...
- Java设计模式之Builder模式
Java设计模式之Builder模式 Java设计模式之Builder模式 简介 适用性 用LOL的出装备的顺序为例 基本实现代码 BasePerson的实现 DeMaXiYa的实现 QiTianDa ...
- 「设计模式(六) - Builder模式」
「设计模式(六) - Builder模式」 一.可定制化的 电脑的组装在生活中并不陌生,大家都有电脑,当然需求不一样配置也不一样.以Macbook Pro为例,像UI设计对图像模块GPU要求比较高,跑 ...
- Android常用设计模式之Builder模式理解
Android常用设计模式之Builder模式 1 单例模式 2 Builder模式 Builder模式的应用场景 总结 1 单例模式 单例模式之前有详细的介绍,可移步到链接: 常见的单例模式及其特点 ...
最新文章
- [翻译]IE8下VML的变化
- Ranger中对hive添加policy字后,hive登录用户可用,hive密码不管用的问题解决,HiveServer2 Authentication Custom的编写
- MyBatis 编程式开发中的核心对象及其作用?
- 1039. 到底买不买(20)
- 怎么将pdf转换成word
- 菜鸟的jQuery源码学习笔记(三)
- 字符串系列之最长回文子串
- .jardesc文件
- 如何解决IIS配置报错问题:存储空间不足?
- c++ 时间轮与时间堆定时器
- Pymol入门教程--基础
- 实现计算机系统的资源共享,实现多操作系统计算机的资源共享
- linux_shell_命令行查单词/shell英文词典工具包(sdcv/dict/trans/wd)
- macbook pro忘记开机密码怎么办
- android tv字体,android TV 屏幕适配 (一)
- win10此电脑不见了_Win10如何把控制面板放到桌面上?Win10控制面板不见了解决方法...
- DELPHI 控件的相对坐标与屏幕坐标转换
- 超详细python下简单快速下载opencv
- 关于事件相机的整理与思考
- 《Armv8/armv9架构入门指南》-【第四章】- ARMv8 寄存器