GameMale
登陆 / 注册 搜索

USERCENTER

SEARCHSITE

搜索

查看: 971|回复: 12
收起左侧

[技术交流] 【java】设计模式-建造者模式

[复制链接] |关注本帖

邪恶的面具堕落之舞风雪之家香喷喷的烤鸡眼镜蛇图腾寻觅牧羊人

     楼主| 白冥 发表于 2024-5-21 16:22:23 | 显示全部楼层 |阅读模式 |取消关注该作者的回复
    本帖最后由 白冥 于 2024-5-24 22:10 编辑
    1. public class House {
    2.     private LivingRoom livingRoom;
    3.     private Bedroom bedroom;
    4.     private Bathroom bathroom;
    5.     private House (Builder builder) {
    6.         this.livingRoom=builder.livingRoom;
    7.         this.bedroom=builder.bedroom;
    8.         this.bathroom=builder.bathroom;
    9.     }
    10.     static final class Builder {
    11.         private LivingRoom livingRoom;
    12.         private Bedroom bedroom;
    13.         private Bathroom bathroom;

    14.         public Builder setLivingRoom (LivingRoom livingRoom) {
    15.             this.livingRoom=livingRoom;
    16.             return this;
    17.         }

    18.         public Builder setBedroom (Bedroom bedroom) {
    19.             this.bedroom = bedroom;
    20.             return this;
    21.         }

    22.         public Builder setBathroom (Bathroom bathroom) {
    23.             this.bathroom = bathroom;
    24.             return this;
    25.         }

    26.         public House build () {
    27.             return new House (this);
    28.         }
    29.     }
    30. }
    复制代码
           建造者模式(Builder Pattern)是一种对象构建的设计模式,它允许你在一个单独的类中组合所有必要的逻辑来创建复杂对象,同时又能保持代码的可读性和封装性。建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
    **建造者模式通常包括以下几个角色:**
    • Product(产品):这是需要被构建的对象,通常包含多个组成部件或属性。
    • Builder(建造者):这是一个抽象接口,用于规范产品的构建步骤。它通常包含一系列用于构建产品各个部分的抽象方法,但并不涉及具体的构建细节。
    • ConcreteBuilder(具体建造者):这是Builder接口的实现,它提供了具体的构建逻辑,包括设置产品的各个属性和组件。一个ConcreteBuilder通常与一个未完成的产品实例相关联,并提供了建造和获取产品的方法。
    • Director(指挥者):这是一个负责指导ConcreteBuilder如何构建产品的类。它确保产品的构建过程按照特定的顺序进行,但它并不直接参与产品的构建工作,而是委托给ConcreteBuilder来完成。
    • Client(客户端):这是使用Director和ConcreteBuilder来构建产品的代码。客户端通常只需要与Director交互,而不需要关心具体的构建细节。

    **建造者模式的主要优点包括:**
    • 封装性:建造者模式将构建复杂对象的步骤封装在ConcreteBuilder中,使得客户端代码更加简洁和清晰。
    • 灵活性:通过定义不同的ConcreteBuilder类,可以轻松地改变产品的构建逻辑,而无需修改客户端代码。
    • 可读性:通过使用Director类来指导构建过程,可以增加代码的可读性和可维护性。
            建造者模式通常用于构建具有多个步骤和复杂组件的对象,例如,配置复杂的系统配置、创建一个包含多个部分和属性的文档或报告等。通过分离构建逻辑和表示逻辑,建造者模式使得代码更加模块化、可测试和可维护。


            这段代码展示了一个典型的建造者模式实现。在这个例子中,House 类代表要被构建的产品,而 Builder 是一个内部静态类,它扮演了具体建造者的角色。Builder 类中的方法允许客户端设置 House 对象的各个组成部分,并最终通过 build() 方法构建出一个完整的 House 对象。
    **这段代码的功能描述如下:**
    • 产品(Product):House 类是产品,代表一个房子。它有三个主要组成部分:客厅(LivingRoom)、卧室(Bedroom)和浴室(Bathroom)。这些部分在 House 类中以私有成员变量的形式存在。
    • 建造者(Builder):Builder 内部类是一个具体建造者,它负责构建 House 对象。这个类有三个私有成员变量,分别对应房子的三个部分,并提供相应的设置方法(setLivingRoom、setBedroom、setBathroom)。每个设置方法都返回 Builder 类型的实例,以便支持链式调用。最后,build() 方法用于创建并返回一个配置完成的 House 对象。
    • 客户端使用:客户端可以通过创建 Builder 的实例,然后调用其设置方法来配置房子,并最终调用 build() 方法来获取一个完整的 House 对象。

             在这个例子中,没有明确的 Director 角色,因为 Builder 自己承担了构建的逻辑。在更复杂的场景中,Director 可能会作为一个独立的类存在,用于指导 Builder 如何构建产品,这里的Builder 既包含了构建逻辑也包含了指导逻辑。

    评分

    参与人数 1追随 +1 堕落 +1 收起 理由
    bigbigbig3 + 1 + 1

    查看全部评分

      收起(3)
    • 白冥 白冥 :使用这个模式是这样的:
      House house = new House.Builder
      .setLivingRoom()
      .setBedroom()
      .setBathroom()
      .build();
      2024-05-21 16:30 回复
    • 白冥 白冥 :这样的,忘记写括号和参数了:
      House myHouse = new House.Builder()  
          .setLivingRoom(new LivingRoom())  
          .setBedroom(new Bedroom())  
          .setBathroom(new Bathroom())  
          .build();
      2024-05-21 16:31 回复
    • 白冥 白冥 :应用:
      public class Tree {
          public Node root;
          public class Node {
              private final int key;
              private Node leftNode;
              private Node rightNode;
              private Node(Builder builder) {
                  this.key=builder.key;
                  this.leftNode=builder.leftNode;
                  this.rightNode=builder.rightNode;
              }
              public static final class Builder {
                  private int key;
                  private Node leftNode = null;
                  private Node rightNode = null;
                  public int setKey(int key) {
                      this.key = key;
                      return this;
                  }
                  public Builder setLeftNode(Node node) {
                      this.leftNode = node;
                      return this;
                  }
                  public Builder setLeftNode(Builder builder) {
                      this.leftNode = builder.build();
                      return this;
                  }
                  public Builder setRightNode(Node node) {
                      this.rightNode = node;
                      return this;
                  }
                  public Builder setRightNode(Builder builder) {
                      this.rightNode = builder.build();
                      return this;
                  }
                  public Node build() {
                      return new Node (this);
                  }
              }
              public int getKey () {
                  return this.key;
              }
              public Optional<Node> getLeftNode () {
                  return Optional.ofNullable(leftNode);
              }
              public Optional<Node> getRightNode () {
                  return Optional.ofNullable(rightNode);
              }
          }
          public Tree (int key) {
                  this.root = new Node.Builder().setKey(key).build();
          }
          public void insert (int key) {
              this.root = insertRecursive(this.root,key);
          }
          private Node insertRecursive (Node node, int key) {
              if (node == null) {
                  return new Node.Builder().setKey(key).build();
              }
              if (key < node.getKey()) {
                  node.leftNode = insertRecursive(node.leftNode, key);
              } else if (key > node.getKey()) {
                  node.rightNode = insertRecursive(node.rightNode, key);
              }
              return node;
          }
          public void delete (int key) {
              this.root = deleteRecursive(this.root, key);
          }
          private Node deleteRecursive (Node node, int key) {
              if (node == null) {
                  return null;
              }
              if (key < node.getKey()) {
                  node.leftNode = deleteRecursive(node.leftNode, key);
              } else if (key > node.getKey()) {
                  node.rightNode = deleteRecursive(node.rightNode, key);
              } else {
                  if (node.leftNode == null) {
                      return node.rightNode;
                  } else if (node.rightNode == null) {
                      return node.leftNode;
                  } else {
                      Node minNode = node.findMin(node.rightNode);
                      minNode.leftNode=node.leftNode;
                      minNode.rightNode=deleteRecursive(minNode.rightNode, key);
                      return minNode;
                  }
              }
              return node;
          }
          private Node findMin (Node node) {
              if (node.leftNode == null) {
                  return node;
              }
              return findMin(node.leftNode);
          }
      }
      2024-05-23 21:54 回复
    • 我也说一句

    回复

    使用道具 举报

    百相千面-晦永远的克叔業火死鬥实现梦想官复原职虚空之海的鲸Zootopia幸运女神的微笑『逆境中的幸运女神』御医神兔

      回复

      使用道具 举报

      实现梦想業火死鬥魔法不朽·传奇不熄卡洛斯·奥利维拉白野威十年一梦官复原职男巫之歌永浴爱河虚空之海的鲸

        这个代码好像有不少新功能,观摩看看。
        回复

        使用道具 举报

        泰比里厄斯夏日柯基人到中年Life of Water寻觅史莱姆牧场吃饱金币的Doge邦尼尼

          回复

          使用道具 举报

          诺曼底号性感男神GMForever Titanic魔法不朽·传奇不熄業火死鬥诺克提斯·路西斯·伽拉姆克莱夫・罗兹菲尔德岛田源氏巴哈姆特『终点站:极地』

            妈诶谁能想到离开大学第一次看代码是在游戏论坛上
            回复

            使用道具 举报

            艾吉奥时间尽头的虚空蒂法·洛克哈特你的答案『随时随地开启!』生金蛋的鹅暗影烈焰虎克船长

              翻了翻这个模块的其他帖子,每个都解决了一些或一个论坛相关的问题
              但这帖子有点意义不明,也不像是想交流的样子,发在这里做什么
              纯个人总结记录可以发日志,想分享交流经验可以去csdn
                收起(6)
              回复

              使用道具 举报

              牧羊人

                回复

                使用道具 举报

                『住在GM村』珊瑚泡泡鱼不曾寄出的信件小小安全帽魔眼护符骑兽之子近地夜航元气菠菜人烈焰天使弓龙血指环

                  回复

                  使用道具 举报

                  『住在GM村』格拉迪欧拉斯雪王的心脏『星河碎片』『灰域来音』预知水晶球炽天使之拥『伊黎丝的赞词』纯真护剑『随时随地开启!』

                    回复

                    使用道具 举报

                    脉律辐石劫掠核芯御医神兔夏日柯基幽灵竹筒黄金树的恩惠探险三杰士图腾饼干生活拍立得璀璨金币

                      回复

                      使用道具 举报

                      安德鲁·库珀索尔·奥丁森安德森‧戴维斯走出失恋阴影的罗罗詹米·多南

                        回复

                        使用道具 举报

                        收到情书SCP-s-1889-第二页缘起星空虚空之海的鲸裸体克里斯圣甲虫秘典『随时随地开启!』被释放的灵魂『随时随地开启!』无尽的怀表

                          回复

                          使用道具 举报

                          荒野大镖客:救赎 II瑞雪兆丰年,生灵万物新神秘挑战书艾吉奥GM論壇榮譽勛章森林羊男驯化红龙幼崽

                            回复

                            使用道具 举报

                            您需要登录后才可以回帖 登录 | 立即注册

                            本版积分规则

                            文字版|手机版|小黑屋|GameMale

                            GMT+8, 2024-12-22 15:28 , Processed in 0.132814 second(s), 101 queries , Redis On.

                            Copyright © 2013-2024 GameMale

                            All Rights Reserved.

                            快速回复 返回列表