• 建造者模式


    在讲述这个模式之前,我们先看一个案例:建造小人(只需要建造的小人有头、身子、四肢即可)

    public class DrawPeople extends JFrame {
        //DrawSee构造方法
        public DrawPeople() {
            setBounds(0, 0, 500, 500);//窗体起始位置
            setVisible(true);//窗体是否可见
            setLayout(null); //窗体布局  
            setResizable(false);//窗体是否可进行拖动设置大小
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
            
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }        
            // 获取专门用于在窗口界面上绘图的对象
            Graphics  jg =  this.getGraphics();
            
            // 绘制区域
            paintComponents(jg);
        }
        
        
        //画一个人
        public void paintComponents(Graphics g) {
            try {
                g.drawArc(150, 50, 30, 30, 0, 360);//画头
                g.drawArc(145, 80, 40, 50, 0, 360);//画身子
                g.drawLine(150, 80, 130, 130);
                g.drawLine(180, 80, 200, 130);
                g.drawLine(160, 130, 145, 180);
                g.drawLine(170, 130, 185, 180);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    测试方法
    public class Test {
         public static void main(String[] args) {   
                new DrawPeople();
         }   
    }

    绘制结果如下图所示

    那我现在需要绘制一个比较瘦的人,怎么办?

    正常程序员都会想:这还不简单,把这个类复制一份,把绘制参数改下不就行了。

    那万一复制的时候少复制了一行,让小人缺胳膊少腿怎么办?

    这对一个人来说可是巨大的损失,谁都不想让身体残缺不全。这个问题怎么解决呢?

    下面介绍建造者模式:http://www.runoob.com/design-pattern/builder-pattern.html

    将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。

    那怎么用建造者模式呢?

    以画小人为例,我们需要画头、身体、左手、右手、左脚、右脚,所以我们先定义一个抽象的建造人的类,把这个过程稳定住,不让任何人遗忘当中的任何一步。

    public interface PersonBuilder {
        public abstract void buildHead();
        public abstract void buildBody();
        public abstract void buildArmLeft();
        public abstract void buildArmRight();
        public abstract void buildLegLeft();
        public abstract void buildLegRight();
    }

    然后我们需要建造一个胖的人,就让这个胖子类取继承这个抽象类,那就必须去重写这些抽象方法了,否则编译器也不让你通过。

    public class PersonFatBuilder extends JFrame implements PersonBuilder{
    
        private Graphics  g;
    
        public PersonFatBuilder() {
            setBounds(0, 0, 500, 500);//窗体起始位置
            setVisible(true);//窗体是否可见
            setLayout(null); //窗体布局  
            setResizable(false);//窗体是否可进行拖动设置大小
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
            
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }        
            // 获取专门用于在窗口界面上绘图的对象
            this.g =  this.getGraphics();
            
            // 绘制游戏区域
            paintComponents(this.g);
        }
    
        @Override
        public void buildHead() {
            g.drawArc(150, 50, 30, 30, 0, 360);//画头
        }
    
        @Override
        public void buildBody() {
            g.drawArc(145, 80, 40, 50, 0, 360);//画身子
        }
    
        @Override
        public void buildArmLeft() {
            g.drawLine(150, 80, 130, 130);
        }
    
        @Override
        public void buildArmRight() {
            g.drawLine(180, 80, 200, 130);
        }
    
        @Override
        public void buildLegLeft() {
            g.drawLine(160, 130, 145, 180);
        }
    
        @Override
        public void buildLegRight() {
            g.drawLine(170, 130, 185, 180);
        }
    }

    瘦子类也是用类似的代码去实现这个类就可以了。

    但现在只是保证胖子类拥有了头身手脚方法,但依然无法保证这些方法一定会被调用,怎么办?

    我们还缺少建造者模式中一个重要的类,指挥者(Director),用它来控制建造过程,也用它来隔离用户与建造过程的关联。

    public 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();
        }
    }

    测试方法

    public class Test {
        public static void main(String[] args) {
            PersonFatBuilder pfb = new PersonFatBuilder();
            PersonDirector pd = new PersonDirector(pfb);
            pd.createPerson();
        }
    }

    PersonDirector类的目的就是根据用户的选择来一步步建造小人,而建造的过程在指挥者这里完成,用户就不需要知道了,而且,每个建造过程都是一定要做的,保证了建造流程的正确性,这样,缺胳膊少腿的情况就不会出现了。

    做个比喻:Builder像是图纸,PersonFatBuilder是具体的施工人员,PersonDirector就是个监工,保证施工过程正确有序。

  • 相关阅读:
    前端学习笔记之BOM和DOM
    JAVA学习笔记之图解JAVA参数传递
    Python学习笔记之函数参数传递 传值还是传引用
    Java学习笔记之对象的复制和克隆
    如何科学正确的使用搜索引擎
    JAVA学习笔记之JAVA 对象引用以及赋值
    前端学习笔记之Z-index详解
    Python面试题目之Python的复制和赋值浅析
    Python面试题目之(针对dict或者set数据类型)边遍历 边修改 报错dictionary changed size during iteration
    判断对象是否为数组/函数
  • 原文地址:https://www.cnblogs.com/jwen1994/p/10116245.html
Copyright © 2020-2023  润新知