文章目录
建造者模式
当我一看到这个模式的时候,一脸懵逼,然后去看代码,什么玩意这是。但是当你了解了其驱动背景,也就知道了建造者模式的爽。
建造模式的核心是为了分离对象的属性与创建过程,使用建造者模式创建出来的对象属性,被赋予了对应的值,换句话说,就是使用建造者模式,对应对象的属性要给一些默认值。建造者模式,用大白话说,我觉得就是** 适用于同一个对象在创建过程中有很多种组合这种 ** 。
与工厂模式的在实现方式上有所雷同,但是其内部含义是不一样的。可以理解为,使用建造者模式,就是跟对象属性初始化相关的,与普通方法类不同。
与工厂模式不同的是:
但相同的是他们最终的结果都是返回一个对象给客户端。
实现方式(一)
这个实现方式,与工厂模式类似,由中间商进行创建,看代码。
创建一个对象
上面也说了,建造者模式的背景是对对象属性的赋值,所以首先有一个对象,来创建人吧
public class Human {
private String head;
private String body;
private String hand;
private String foot;
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getHand() {
return hand;
}
public void setHand(String hand) {
this.hand = hand;
}
public String getFoot() {
return foot;
}
public void setFoot(String foot) {
this.foot = foot;
}
}
接口
创建人的步骤,头、收、身体、脚、智商等,所以我们需要创建一个接口,来规定建造者的流程。
public interface IBuildHuman {
public void buildHead();
public void buildBody();
public void buildHand();
public void buildFoot();
public Human createHuman();
}
创建具体实现者
public class Man implements IBuildHuman {
Human human;
public Man (){
human = new Human();
}
@Override
public void buildHead() {
human.setHead("男人的头");
}
@Override
public void buildBody() {
human.setBody("男人的身体");
}
@Override
public void buildHand() {
human.setHand("男人的手");
}
@Override
public void buildFoot() {
human.setFoot("男人的脚");
}
@Override
public Human createHuman() {
return human;
}
}
public class WoMen implements IBuildHuman {
Human human;
public WoMen (){
human = new Human();
}
@Override
public void buildHead() {
human.setHead("女人的头");
}
@Override
public void buildBody() {
human.setBody("女人的身体");
}
@Override
public void buildHand() {
human.setHand("女人的手");
}
@Override
public void buildFoot() {
human.setFoot("女人的脚");
}
@Override
public Human createHuman() {
return human;
}
}
创建director
director就是建造者模式的精髓,它是来执行我们刚才的造人动作的。没错,精髓就是我们刚才的造人动作,director的角色相当于工厂模式中的factory,但是具体实现还是不一样的,工厂模式中是根据参数进行创建对象并返回,而建造者模式的director,是在给对象的属性赋值并返回。
public class Director {
public Human createHumanByDirecotr(IBuildHuman bh){
bh.buildBody();
bh.buildFoot();
bh.buildHand();
bh.buildHead();
return bh.createHuman();
}
}
//我们改一下,可以更加类似于工厂模式
public class Director {
public Human createHumanByDirecotr(String param){
IBuildHuman bh;
if(StringUtils.equals(param,"1")){
bh = new Man();
}else{
bh = new WoMen();
}
//这样的话,我们就需要改一下接口实现类了,弄成模板方法(请自行实现),还要添加一个抽象类,个人感觉没必要!!
return bh.createHuman();
}
}
测试类
public class BuilderTest {
public static void main(String[] args){
Director director = new Director();
Human human = director.createHumanByDirecotr(new Man());
System.out.println(human.getHead());
System.out.println(human.getBody());
System.out.println(human.getHand());
System.out.println(human.getFoot());
Human human2 = director.createHumanByDirecotr(new WoMen());
System.out.println(human2.getHead());
System.out.println(human2.getBody());
System.out.println(human2.getHand());
System.out.println(human2.getFoot());
}
}
实现方式二,去掉Director
需要最初对象的构造方法
需要一个建造类
public class HumanBuilder {
// 男人、女人
private String type;
// 身材健壮or丰满
private String shencai;
//这个是建造者模式好像约定俗成的方法名,代表建造,里面把自身对象传给Human
public Human Build () {
Assert.assertNotNull(type);
Assert.assertNotNull(shencai);
return new Human(this);
}
public HumanBuilder type(String type) {
this.type = type;
return this;
}
public HumanBuilder shencai(String shencai) {
this.shencai= shencai;
return this;
}
}
public class Human {
private String head;
private String body;
private String hand;
private String foot;
public Human (HumanBuilder hb){
if(StringUtils.equals(hb.type,"1")){
this.head="男人头";
this.foot="男人脚";
//。。。省略
}else{
this.body="女人身体";
this.foot="女人脚";
//。。。省略
}
if(StringUtils.equals(hb.shencai,"1")){
this.head="强壮";
//。。。省略
}else{
this.body="丰满";
//。。。省略
}
}
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getHand() {
return hand;
}
public void setHand(String hand) {
this.hand = hand;
}
public String getFoot() {
return foot;
}
public void setFoot(String foot) {
this.foot = foot;
}
}
@Test
public void test() {
Human Human = new HumanBuilder().shencai("丰满").type("女人").build();
System.out.println(JSON.toJSONString(car));
}
与工厂模式的不同与相同点
工厂模式中,关注的是对象的创建,并不关注对象的内容、属性,
而建造者模式,关注的则是对象中的属性赋值,两者侧重点不同。
而相同点则是,他们最终的结果,都是返回一个对象给客户端。
适配器模式
适配器模式,顾名思义,就是适配,那什么时候做适配呢,当然是被调用者,不能满足调用这所期待的样子,所以,我们需要在中间加一层适配。比如:
被调用者方法名是,sourceRequest()
调用者期待的方法名是hopeRequest()
如果不用适配器模式,那只能修改现有代码,如果sourceRequest方法或者hopeRequest方法都被很多方法调用,使用的地方都得要改成期望值,所以,不要修改。
分析适配器模式,我认为分析关键点应该站在调用者位置上,因为我们由现有的接口去适配它,所以我们需要一个与之相同的方法名,那有没有可以实现方法名一样,但是需要不能有具体的方法实现(因为具体实现,是需要调用被调用者的方法)----有,那就是接口、或者抽象类。但是由于java单继承的特性,所以在这个模式中接口类不能用抽象类来体现。
实现适配器有两种方式
类适配器
类适配器模式,就是在通过类继承的方式实现适配。
public interface AdacpterInterface {
public void hopeRequest();
}
public class SourceRequest {
public void sourceRequest(){
System.out.println("sourceRequest");
}
}
//因为类单继承的特性,所以类适配器模式下,hopeRequest方法定义所在的类不能用抽象类表示
public class AdapterRequest extends SourceRequest implements AdacpterInterface {
@Override
public void hopeRequest() {
sourceRequest();
}
}
对象适配器
方法适配器,就是在适配器中,持有需要适配的的对象,就是对象适配器模式
只需要该一下我们的适配器类就可以。
public class AdapterRequest2 implements AdacpterInterface{
private SourceRequest sourceRequest;
public AdapterRequest2(SourceRequest sourceRequest){
this.sourceRequest = sourceRequest;
}
@Override
public void hopeRequest() {
sourceRequest.sourceRequest();
}
}
如果我们接口方法是用抽象类表示的呢
public abstract class AdapterAbstract {
public abstract void hopeRequest();
}
public class AdapterRequest3 extends AdapterAbstract{
private SourceRequest sourceRequest;
public AdapterRequest3(SourceRequest sourceRequest){
this.sourceRequest = sourceRequest;
}
@Override
public void hopeRequest() {
sourceRequest.sourceRequest();
}
}
也就是说当我们采用类适配器模式的时候,适配的接口不能用抽象类体现,而对象适配器可以使用。
适配器的优缺点
优点
- 复用。现有的类不符合系统的需要,通过适配器模式就可以让这些功能得到复用
- 解耦。引入适配类,无序修改原来的代码
- 扩展。在调用被适配接口前后,可以加入一些其他方法。(AOP思想)
缺点
缺点就是过多的使用适配器,会让人看起来非常混乱,比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,所以一般尽量不使用适配器,如果使用的地方多了,那么可以考虑一下重构了
不同模式的适配的优缺点
类适配器模式
继承方式,所以代码看起来简化,适配器类无需再设置额外的属性来引用被适配者的实例。
也是因为继承的方式,所以它是静态的定义方式,在灵活性上比较低,耦合度较高
对象适配器模式
对象引用的方式,是动态组合方式,也就是灵活性高,低耦合
对应的就要额外设置一个属性,来引用实例,较之复杂