美文网首页
设计模式之四接口隔离原则

设计模式之四接口隔离原则

作者: 李2牛 | 来源:发表于2018-08-14 17:18 被阅读0次

    接口隔离的两种定义

    Clients should not be forced to depend upon interfaces that they don't use.(客户端不应依赖于它不需要的接口)

    Or

    The dependency of one class to another one should depend on the smallest possible interface.(类间的依赖关系应该建立在最小的接口上)

    简而言之:尽量细化接口,不要建立臃肿的接口,接口的方法尽可能的少。
    案例分析:评判一个学生的过程。我曾听说美国MIT的学生崇尚3S原则,即Study,Social,Sleep,普通的学生能够完成两项就十分厉害了。我们带着这样一个问题:按照3S的标准,怎样判定一个学生是否优秀?
    依照惯例画出UML图:


    判断优秀学生.jpg

    代码如下:

    AbstractJudge.java

    public abstract class AbstractJudge {
        IExcellentStudent student;
        AbstractJudge(IExcellentStudent student){
            this.student = student;
        }
        public abstract void judge();
    }
    

    JudgeA.java

    public class JudgeA extends AbstractJudge {
        JudgeA(IExcellentStudent student) {
            super(student);
        }
        public void judge() {
            System.out.println(" judgement is below:");
            super.student.study();
            super.student.social();
            super.student.sleep();
    
        }
    }
    

    IExcellentStudent.java

    public interface IExcellentStudent {
        void study();
        void social();
        void sleep();
    }
    

    StudentA.java

    
    public class StudentA implements IExcellentStudent {
        @Override
        public void study() {
            System.out.println("A gains good GPA");
        }
    
        @Override
        public void social() {
            System.out.println("A does well in social");
        }
    
        @Override
        public void sleep() {
            System.out.println("A gets enough sleep");
        }
    }
    

    Client.java

     public class Client {
        public static void main(String[] args) {
            StudentA studentA = new StudentA();
            JudgeA judgeA = new JudgeA(studentA);
            judgeA.judge();
        }
    }
    

    运行结果如下:

    An excellent student's judgement is below:
    A gains good GPA
    A does well in social
    A gets enough sleep
    

    这样的设计是存在问题的,JudgeA根据StudentA的三种方面成果进行评判,如果两项出类拔萃我们就称StudentA为优秀,但是我们把三项标准都放在一个接口里面,除非是全部满足的超级学生,一般的优秀学生难以全部优秀,那么不是所有的学生都具有三个方法,这就说明一个IExcellentStudent接口过度封装了,所以我们可以考虑将这个接口根据3s的三个方面两两封装成接口,一个学生根据自己的特长实现相应的接口。然后Judge就能根据学生的特长判断其是否优秀。


    接口隔离的实现

    代码如下:

    AbstractJudge.java

    public abstract class AbstractJudge {
        Study stu;
        Social soc;
        Sleep sle;
        AbstractJudge(Study stu, Social soc) {
            this.stu = stu;
            this.soc = soc;
        }
        AbstractJudge(Social soc, Sleep sle) {
            this.soc = soc;
            this.sle = sle;
        }
        AbstractJudge(Study stu, Sleep sle) {
            this.stu = stu;
            this.sle = sle;
        }
        public abstract void judge();
    }
    

    JudgeBaseOnStudySocial.java

    //根据study和social进行评判
    public class JudgeBaseOnStudySocial extends AbstractJudge {
        JudgeBaseOnStudySocial(Study study, Social social) {
            super(study, social);
        }
        public void judge() {
            System.out.println(" An excellent student's judgement when it come to Study and Social  is below:");
            super.stu.study();
            super.soc.social();
        }
    }
    

    Study .java

    public interface Study {
        void study();
    }
    

    Social.java

    public interface Social {
        void social();
    }
    

    Sleep.java

    public interface Sleep {
        void sleep();
    }
    

    StudentExcellentInStudyAndSocial .java

    //专长于学习和社交的学生类型
    public class StudentExcellentInStudyAndSocial implements Social, Study {
        @Override
        public void social() {
            System.out.println("A does well in social intercourse,start statement");
        }
    
        @Override
        public void study() {
            System.out.println("A studies well,start statement");
        }
    }
    

    Client.java

    public class Client {
        public static void main(String[] args) {
            StudentExcellentInStudyAndSocial student = new StudentExcellentInStudyAndSocial();
            JudgeBaseOnStudySocial judge = new JudgeBaseOnStudySocial((Study) student,(Social)student);
            judge.judge();
        }
    }
    

    这样我们就实现了客户端只依赖于有用的优秀特质接口,而类间的依赖关系只建立在最小的接口上,以后我们可以方便地拓展具有各种特质的学生类型,然后分别定义Judge进行评判。请牢记:系统面向拓展而不是面向更改。
    设计模式系列文章我们讨论的是理论情况,实际生产条件更加复杂,可能难以真正分清各种依赖或者没有必要分得太清依赖,那时我们需要因地制宜,灵活应用,教条主义要不得。与君共勉。

    相关文章

      网友评论

          本文标题:设计模式之四接口隔离原则

          本文链接:https://www.haomeiwen.com/subject/bchpbftx.html