走穿java23种设计模式-4建造者模式详解
来源:互联网 发布:严宽乔振宇 知乎 编辑:程序博客网 时间:2024/05/01 04:38
走穿java23种设计模式-4建造者模式详解
说到建造者模式可能很多人没了解过,有些人可能看过但是没有理解到它的知识。
这个创建者模式要理解起来确实是有点麻烦的,而且它和工厂模式是很类似的。
总体来说设计模式分为三大类(23种):
创建型模式,共五种:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
结构型模式,共七种。行为型模式,共十一种。
创建型模式最简单的理解就是跟创建对象是直接相关的,都有new。。。
单例模式是只new一次
两个工厂模式是父类(接口)的对象,子类的new实例化
建造者模式是
原型模式是new一次,然后用复制的方法创建这个对象去使用,单例模式一个类一直是一个对象,而原型模式的那个类不止一个对象,只是第一次new出来,后面的对象用克隆的方式去创建多个同样的类。
建造者模式的定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
这里給大家分析一下:
定义的前半句说,构造与表示分离,其实就是继承(或实现)。
两种工厂模式也都是为某个对象提供一个接口,而且无需指定它们的具体类。
所以建造者模式的重点是后半句:同样的构建过程可以创建不同的结果。
但是我仔细想了一下,这句话说的也是太含糊了,并且和工厂模式也是类似的,工厂模式的接口也是定义了产品的过程,子类去实现,然后生产出不同的产品。
虽然是有点纠结但是还是应该先看完,在慢慢来深入理解这个建造者模式。
建造者模式的类图:
建造者模式中,有如下四种角色:
1.抽象建造者(Builder):该绝是用于规范产品的各个组成部分,并进行抽象,一般独立于应用程序的逻辑。
2.具体建造者(Concrete Builder):该角色实现抽象建造者中定义的所有方法,并且返回一个组件好的产品实例。
3.产品(Product):该角色是建造者中的复杂对象,一个系统中会有多个产品类,这些产品类不一定有共同的接口,可以是完成不相关的。
4.导演者(Director):该角色负责安排已有模块的顺序,然后告诉Builder开始建造
分析这个建造者的类图,可以看到这个模式和之前介绍的工厂模式,是很类似的,只是这个导演类是建造者模式里面特有的。
这里导演类调用抽象建造者类的方法来创建需要的产品对象,因为具体建造者类已经实现了这个抽象建造者类,并且和产品类做了相关联。
建造者模式里面的抽象建造者,一般是抽象类(可以有抽象方法和非抽象方法),但是也可以是接口。
对比一下工厂方法模式的类图:
这里可以看到工厂方法没有导演类,但是我感觉在Main方法里面调用抽象工厂里面的方法,和调用导演类是一样样的!
还有在建造者模式中没有看到抽象产品这个接口或抽象类,也是可以在建造者模式中加进去的,因为这只会规范一个类的标准,并不会影响这个设计模式本身。
如果建造者模式中去掉导演类,加上抽象产品类,那么工厂方法模式和建造者模式是一样样的。
建造者模式的实例
这里以生产两种奔驰汽车为实例,可以对比我之前写的工厂方法模式也是生产这两种奔驰汽车。
建造者模式实例类图
各个接口/类的代码:
1.抽象建造者类BenzBuilder
““
package p4_builder;
/**
* 抽象建造者BenzBuilder
* 相当于奔驰工厂的抽象产品接口类
*/
public interface BenzBuilder {
void setColor(String color);//设置颜色
void setSpeed(int speed);//设置速度void setPrice(double price);//设置价格Benz createBenz();//奔驰对象
}
““
2.抽象产品类Benz
package p4_builder;/** * 奔驰产品的抽象类 * 里面可以有抽象方法 */public abstract class Benz { String color; int speed; double price; //get和set方法 public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; }}
3.具体建造者类BenzC180Build、BenzE260Build
BenzC180Build
package p4_builder;/** * 生产奔驰C180的具体建造者 */public class BenzC180Builder implements BenzBuilder { Benz benz=new BenzC180(); @Override public void setColor(String color) { benz.setColor(color); } @Override public void setSpeed(int speed) { benz.setSpeed(speed); } @Override public void setPrice(double price) { benz.setPrice(price); } @Override public Benz createBenz() { return benz; }}
BenzE260Build
package p4_builder;/** * 生产奔驰C180的具体建造者 */public class BenzE260Builder implements BenzBuilder { Benz benz=new BenzE260(); @Override public void setColor(String color) { benz.setColor(color); } @Override public void setSpeed(int speed) { benz.setSpeed(speed); } @Override public void setPrice(double price) { benz.setPrice(price); } @Override public Benz createBenz() { return benz; }}
4.具体产品角色BenzC180、BenzE260
BenzC180
package p4_builder;/** * 奔驰C180的生产的具体类 */public class BenzC180 extends Benz { /** * 构造方法,创建的时候就设置基本属性 */ public BenzC180() { System.out.println("设计奔驰C180类型车辆"); } //写在子类,父类都是可以的 @Override public String toString() { return "车辆BenzC180的" + "颜色:'" + color + '\'' + ", 速度:" + speed + ", 价格:" + price; }}
BenzE260
package p4_builder;/** * 奔驰E260的生产的具体类 */public class BenzE260 extends Benz { /** * 构造方法,创建的时候就设置基本属性 */ public BenzE260() { System.out.println("设计奔驰E260类型车辆"); } //写在子类,父类都是可以的 @Override public String toString() { return "车辆BenzE260的" + "颜色:'" + color + '\'' + ", 速度:" + speed + ", 价格:" + price; }}
上面两个产品的具体类,继承的是抽象类,可以覆盖父类的方法。
5.导演类BenzDirector
package p4_builder;/** * 奔驰车辆生产的导演类 */public class BenzDirector { private BenzBuilder benzBuilder; public BenzC180 createBenzC180() { benzBuilder = new BenzC180Builder();//父类的对象,子类的实例化,多态的使用 benzBuilder.setColor("白色"); benzBuilder.setSpeed(180); benzBuilder.setPrice(25); return (BenzC180) benzBuilder.createBenz();//父类的对象强转成子类的 } public BenzE260 createBenzE260() { benzBuilder = new BenzE260Builder();//父类的对象,子类的实例化,多态的使用 benzBuilder.setColor("黑色"); benzBuilder.setSpeed(210); benzBuilder.setPrice(33); return (BenzE260) benzBuilder.createBenz();//父类的对象强转成子类的 }}
上面车辆的参数也是可以在BenzC180Builder里面设置好,但是我感觉抽出来比较直观,后期易维护。。。
如果在BenzC180Builder里面设置好,BenzBuilder的几个抽象方法不需要传入参数,具体的参数在BenzC180Builder设置
外边只看到:benzBuilder.setColor();//省略内部过程,,也是一种思想
6.调用者BuilderDemo
package p4_builder;/** * 建造者模式调用 * 生产两个奔驰车C180、E260 */public class BuilderDemo { public static void main(String[] a) { //实例化导演类 BenzDirector director = new BenzDirector(); //生产奔驰C180 BenzC180 benzC180 = director.createBenzC180(); //打印一下结果 System.out.println("" + benzC180.toString()); //生产奔驰E260 BenzE260 benzE260 = director.createBenzE260(); //打印一下结果 System.out.println("" + benzE260.toString()); }}
程序运行结果:
建造者模式就介绍到这里,大家想要深入理解就要多去研究类图中的几个角色。
其实建造者模式,没有那么人多知道,少人用,主要原因是工厂模式已经非常出名了,大家知道工厂模式,用工厂模式也方便很多的,各个角色的分配也是比较符合日常逻辑。
我想建造者模式得不到很多人的认识,主要原因是它本身就是仿照工厂模式的设计来设计的,盗版的东西,很难超越原本的事物,得不到大部分的人的认可,所有很多人用过就不怎么想用。同样是创建型的设计模式,用熟悉的工厂模式肯定比用别人陌生的建造者模式好一点,别人也是更容易理解。
之前也详细介绍过了抽象工厂模式:http://blog.csdn.net/wenzhi20102321/article/details/78153437
工厂方法模式:http://blog.csdn.net/wenzhi20102321/article/details/78129065
可以仔细对比一下工厂方法模式和抽象工厂模式,看看概念,看看类图,看看代码,就会明白了。
单例模式:http://blog.csdn.net/wenzhi20102321/article/details/77882203
java 23种设计模式介绍:http://blog.csdn.net/wenzhi20102321/article/details/54601909
共勉:站在巨人的肩膀上,你能看到更远;但是要记住,路一定是在脚下。
- 走穿java23种设计模式-4建造者模式详解
- 走穿java23种设计模式-5原型模式
- 走穿java23种设计模式-5原型模式
- 走穿java23种设计模式-6代理模式
- 走穿java23种设计模式-9组合模式
- 走穿java23种设计模式-10桥梁模式
- 走穿java23种设计模式-2工厂方法模式详解
- 走穿java23种设计模式-3抽象工厂模式详解
- 走穿java23钟设计模式-11外观模式
- 走穿23种设计模式-7装饰模式详解
- 走穿23种设计模式-8适配器模式详解
- java23种设计模式之建造者模式(Builder)
- java23种设计模式之建造者模式(Builder)
- Java23种设计模式——建造者模式
- java23种设计模式详解
- java23种设计模式详解
- java23种设计模式详解
- Java23种设计模式详解
- 登录注册功能的实现,核心的验证代码
- 浮点数在内存中的存储形式
- CF2017.10.5 C. Qualification Rounds
- mysql触发器
- SPI写解析
- 走穿java23种设计模式-4建造者模式详解
- disable default certificate verification in python 2.7.8
- 如何隐藏手机号码
- 如何在caffe中添加新的Layer
- CSharp第一讲-基本语法
- Lintcode139 Subarray Sum Closest solution 题解
- 华为机考笔试题-删数
- 鸡兔同笼问题
- 收集游戏制作的图片