名著解读-Effective Java 第一章 02 利用构造器改造多构造参数的构造方法

余生长醉 提交于 2020-08-13 04:00:47

多参数构造方法会有什么问题?

如下面代码你会发现,眼睛和耳朵的构造方法由于参数是一样的,这样会导致构造方法冲突。那我们有什么办法能 解决这样的问题呢?

public class Dog {
    //眼睛和耳朵至少必须填写一个
    private String eye;
    private String eyeColour; //填写的眼睛,必须填写眼睛颜色
    private String ear;
    private String earColour;//填写的耳朵,必须填写耳朵颜色


    public  Dog(String eye,String eyeColour){
        this.eye =  eye;
        this.eyeColour = eyeColour;
    }

    public  Dog(String ear,String earColour){
        this.ear =  ear;
        this.earColour = earColour;
    }

}

方法1利用Set方法处理

public class Dog {
    //眼睛和耳朵至少必须填写一个
    private String eye;
    private String eyeColour; //填写的眼睛,必须填写眼睛颜色
    private String ear;
    private String earColour;//填写的耳朵,必须填写耳朵颜色


    public String getEye() {
        return eye;
    }

    public void setEye(String eye) {
        this.eye = eye;
    }

    public String getEyeColour() {
        return eyeColour;
    }

    public void setEyeColour(String eyeColour) {
        this.eyeColour = eyeColour;
    }

    public String getEar() {
        return ear;
    }

    public void setEar(String ear) {
        this.ear = ear;
    }

    public String getEarColour() {
        return earColour;
    }

    public void setEarColour(String earColour) {
        this.earColour = earColour;
    }
}

测试代码

public class TwoTest {

    public static void main(String [] args) {
        Dog dog  =new Dog();
        dog.setEye("大眼睛");
        dog.setEyeColour("黑色");
        System.out.println("狗眼睛是"+dog.getEye()+"#狗眼睛颜色是"+dog.getEyeColour());
    }

}

set方法可以实现我们要的功能,但是这也存在一个十分严重的问题,如我们把setEyeColour 改成setEarColour,这样问题在日常开发也经常发生,有的程序员粗心引用错的方法

public class TwoTest {

    public static void main(String [] args) {
        Dog dog  =new Dog();
        dog.setEye("大眼睛");
//        dog.setEyeColour("黑色");
        dog.setEarColour("黑色");
        System.out.println("狗眼睛是"+dog.getEye()+"#狗眼睛颜色是"+dog.getEyeColour());
    }

}

可以看到这时候业务逻辑是错误的,但是系统的代码逻辑却是可以正常运行,这样发布到生产环境就会造成BUG。这也是使用set方法一个致命的弊端。那该如何解决这个问题呢?

方法2利用构造器

public class Dog {
    //眼睛和耳朵至少必须填写一个
    private String eye;
    private String eyeColour; //填写的眼睛,必须填写眼睛颜色
    private String ear;
    private String earColour;//填写的耳朵,必须填写耳朵颜色

//    public  Dog(String eye,String eyeColour){
//        this.eye =  eye;
//        this.eyeColour = eyeColour;
//    }
//
//    public  Dog(String ear,String earColour){
//        this.ear =  ear;
//        this.earColour = earColour;
//    }


    public String getEye() {
        return eye;
    }

    public void setEye(String eye) {
        this.eye = eye;
    }

    public String getEyeColour() {
        return eyeColour;
    }

    public void setEyeColour(String eyeColour) {
        this.eyeColour = eyeColour;
    }

    public String getEar() {
        return ear;
    }

    public void setEar(String ear) {
        this.ear = ear;
    }

    public String getEarColour() {
        return earColour;
    }

    public void setEarColour(String earColour) {
        this.earColour = earColour;
    }

    public static  class  Builder{
        //眼睛和耳朵至少必须填写一个
        private String eye;
        private String eyeColour; //填写的眼睛,必须填写眼睛颜色
        private String ear;
        private String earColour;//填写的耳朵,必须填写耳朵颜色
        public  Builder eye(String eye){
            this.eye = eye;return this;
        }
        public  Builder eyeColour(String eyeColour){
            this.eyeColour = eyeColour;return this;
        }
        public  Builder ear(String ear){
            this.ear = ear;return this;
        }
        public  Builder earColour(String earColour){
            this.earColour = earColour;return this;
        }
        public  Dog build() throws Exception{
            return  new Dog(this);
        }

    }
    private  Dog (Builder builder) throws Exception{
        this.ear = builder.ear;
        this.earColour = builder.earColour;
        this.eyeColour = builder.eyeColour;
        this.eye = builder.eye;
        if(eye!=null&&eyeColour==null){
            throw  new Exception("眼睛颜色没有填写");
        }
        if(ear!=null&&earColour==null){
            throw  new Exception("耳朵颜色没有填写");
        }

    }
}

我们在对象里面声明了一个构造器,Builder 并且在new 一个对象的时候已经规范好了业务逻辑。

public class TwoTest {

    public static void main(String [] args) throws Exception {
        Dog dog  =new Dog.Builder().eye("大眼睛").earColour("黑色").build();
        System.out.println("狗眼睛是"+dog.getEye()+"#狗眼睛颜色是"+dog.getEyeColour());
    }
}

这时候我们从代码层面完全规范好业务逻辑就可以避免粗心导致Bug的产生。

代码地址 https://gitee.com/406/DesignPattern.git

\src\t'wo目录中

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!