Java 设计模式-建造者模式

134 阅读2分钟
  1. 需求分析:
    在一个游戏系统中, 现在需要使用代码画两个小人, 一个胖小人和一个瘦小人, 并且画小人的代码要能够复用, 因为在系统的许多地方都可能需要调用该代码来生成小人.

    public class ThinPersonBuilder {
        private Graphics graphics;
        
        public ThinPersonBuilder(Graphics graphics) {
            this.graphics = graphics;
        }
        
        public Person build() {
            this.graphics.drawEllipse(50, 20, 30, 30);
            this.graphics.drawRectangle(60, 50, 10, 50);
            this.graphics.drawLine(60, 50, 40, 100);
            this.graphics.drawLine(70, 50, 90, 100);
            this.graphics.drawLine(60, 100, 45, 150);
            this.graphics.drawLine(70, 100, 85, 150);
        }
    }
    

    这里存在的一些问题. 一个人的构建过程是稳定的, 包括构建头, 身体, 左手, 右手, 左脚, 右脚. 而在上面的build()方法中, 这一系列的构建过程并没有被约束起来. 在实际的编码过程中, 很有可能因为少写或多写一行代码, 导致小人构建的不完整. 我们采用建造者模式来改进.

    public abstract class PersonBuilder {
        protected Graphics graphics;
    
        public PersonBuilder(Graphics graphics) {
            this.graphics = graphics;
        }
        // 这里使用不同的方法名来区分不同的建造步骤
        protected abstract void buildHead();
        protected abstract void buildBody();
        protected abstract void buildLeftArm();
        protected abstract void buildRightArm();
        protected abstract void buildLeftLeg();
        protected abstract void buildRightLeg();
    }
    
    /**
     * 瘦小人的建造者
     */
    public class ThinPersonBuilder extends PersonBuilder {
        public ThinPersonBuilder(Graphics graphics) {
            super(graphics);
        }
    
        @Override
        public void buildHead() {
            this.graphics.drawEllipse(50, 20, 30, 30);
        }
    
        @Override
        public void buildBody() {
            this.graphics.drawRectangle(60, 50, 10, 50);
        }
    
        @Override
        public void buildLeftArm() {
            this.graphics.drawLine(60, 50, 40, 100);
        }
    
        @Override
        public void buildRightArm() {
            this.graphics.drawLine(70, 50, 90, 100);
        }
    
        @Override
        public void buildLeftLeg() {
            this.graphics.drawLine(60, 100, 45, 150);
        }
    
        @Override
        public void buildRightLeg() {
            this.graphics.drawLine(70, 100, 85, 150);
        }
    }
    /**
     * 建造小人的指挥者
     */
    public class PersonDirector {
        private PersonBuilder personBuilder;
    
        public PersonDirector(PersonBuilder personBuilder) {
            this.personBuilder = personBuilder;
        }
        // 这里约束的小人的建造过程, 所以不会出现小人不完整的情况
        public void createPerson() {
            this.personBuilder.buildHead();
            this.personBuilder.buildBody();
            this.personBuilder.buildLeftArm();
            this.personBuilder.buildRightArm();
            this.personBuilder.buildLeftLeg();
            this.personBuilder.buildRightLeg();
        }
    }
    
  2. 建造者模式定义: Separate the construction of a complex object from its representation so that the same construction process can create different representations(将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示)

    builder pattern
    建造者模式将复杂对象的构建过程进行约束, 使得不同对象的构建过程保持稳定.

  3. 建造者模式的应用:
    java.lang.StringBuilder#append() 方法
    java.lang.StringBuffer#append()方法

  4. 建造者模式的扩展:
    建造者模式是通过组装零件的方式进行对象的构建, 组装不同对象的能效也不同, 建造者模式强调的是建造的过程, 这时它与工厂方法的不同.

  5. 参考:
    [1] : Java 库中的设计模式
    [2] : 设计模式之禅
    [3] : Head First 设计模式
    [4] : 大话设计模式