Java面试题总结开放平台iOS应用框架

软件设计七大原则

2018-08-20  本文已影响8人  AKyS佐毅

1、开闭原则

不要改你以前写的代码,你应该加一些代码去扩展原来的功能,来实现新的需求。好处很好理解,改原来的代码很容易影响原来的功能,特别是接手别人的代码,不理解原先业务场景的情况下。

新添加校验规则的话,尽量不要修改以前的校验规则。可以回引入新的风险。

具体代码实现:

image

举例: 比如有一个课程抽象类,该课程包含课程id,名称,价格。同时开放的课程有java课程,C语言课程。上面的UML图就是两者之间的关系。

如果在此基础上需要添加优惠课程。那么我们有两种实现方式。一种就是直接在抽象接口中声明一个优惠获得价格的方法。另一种就是在java课程中直接修改获取价格的方法。

但是这两种方式都会存在问题。前者的问题在于修改的地方太多,接口是不应该经常变化的,尤其是在有很多实现类的前提下,这样修改会让我们修改很多实现类。后者的问题在于我们就无法获取原来的价格。不符合需求。

那么究竟怎样是合理的呢?

如果只是java课程打折,那么我们最好使用继承的方式,对原来的java课程进行扩展。

image

尽量不对底层的方法进行修改,防止风险的扩散。越高层的影响越小,提高了复用性。

2、依赖倒置原则

image

上图是典型的面向实现编程,一旦我们需要添加新的课程就需要修改该类,改动是很频繁的。这里我们引入抽象。然后实现接口的方式。在应用层通过参数注入的方式调用具体实现类。

image

当然这样会有一个问题,我们在Mical类中只能注入一次ICourse的实例。那么为了多次调用,需要将ICourse暴露出去。

image

3、单一职责原则

例如声明一个鸟类,方法为行动的方式

public class Bird {

    public void mainMoveMode(String birdName) {
        System.out.println(birdName+ "用翅膀飞");
    }
}

在实际调用时,属于鸟类的有大雁,企鹅,鸵鸟。那么其实企鹅和鸵鸟其实不是使用翅膀的,这就出现了需求不一致的问题。我们一般的做法就是根据传入的参数判断,然后输出不同的结果。

public class Bird {

    public void mainMoveMode(String birdName) {
        if (birdName.equals("鸵鸟")){
            System.out.println(birdName + "用脚走");
        }else {
            System.out.println(birdName + "用翅膀飞");
        }
    }
}

这样会更改实现的具体流程,不留神就改错了。尤其是对于边界条件比较复杂的处理流程而言。

image

再比如课程类

public interface Course {
    //获取课程信息
    String getCourseName();
    byte[] getCourseVideo();
    
    //课程管理
    void studyCourse();
    void refundCourse();
}

在这个类中,我们可以看到获取课程信息和退单是相互影响的。

那么我们可以将其进行拆分。

image

4、接口隔离原则

比如狗是不会飞的,那么我们要实现这个接口,就必须将它的fly方法不予实现。造成了浪费。
我们可以适度的将接口拆分,但不可过于细

image

5、迪米特法则

防疫站需要每个宠物的信息,这时候需要一个EpidemicStation对象。如何获取宠物信息有2种方式
通过宠物的主人,EpidemicStation早已有了Host对象,而Host中有一系列关于宠物(Animal)的方法
直接new一个宠物的对象,获取相关信息。

我们肯定直接会选择第一种。。。直觉是可以少建个对象。。。早说了我就是这种偷懒的程序猿。。。然而莫名的契合了迪米特法则。

Host只需要对Animal对象保持关注,而EpidemicStation只需要对Host对象保持关注。EpidemicStation对象不需要了解Animal。感觉直接点就是,在一个类中应该少出现其他类,其实这也是解耦的需要。

6、里氏替换原则

换句话说,所有引用基类的地方必须能透明地使用其子类的对象。

由定义可知,在使用继承时,遵循里氏替换原则,在子类中尽量不要重写和重载父类的方法。

继承包含这样一层含义:父类中凡是已经实现好的方法(相对抽象方法而言),实际上是在设定一系列的规范和契约,虽然它不强制要求所有的子类必须遵循这些契约,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破坏。而里氏替换原则就是表达了这一层含义。

继承作为面向对象三大特性之一,在给程序设计带来巨大遍历的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能产生故障。

public interface ICourse {

    Integer getId();

    String getName();

    Double getPrice();
}
public class JavaCourse implements ICourse {

    private   Integer id;

    private String name;

    private  Double price;


    public JavaCourse( Integer id,String name, Double price) {
        this.id = id;
        this.name = name;
        this.price  = price;
    }

    @Override
    public Integer getId() {
        return this.id;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public Double getPrice() {
        return this.price;
    }


    @Override
    public String toString() {
        return "JavaCourse{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

public class JavaDiscountCourse extends JavaCourse {

    public JavaDiscountCourse(Integer id, String name, Double price) {
        super(id, name, price);
    }

    public Double getDisCountPrice(){
        return  super.getPrice()* 0.8;
    }

    @Override
    public Double getPrice() {
        return super.getPrice() ;
    }
}
public static void main(String[] args) {

        ICourse javaCourse = new JavaDiscountCourse(95,"Java架构设计",128.0);
        System.out.println(

                "课程Id:"+javaCourse.getId()
                + "课程名称:"+ javaCourse.getName()
                + "课程原格:"+ javaCourse.getPrice()
                + "课程优惠价格:"+ ((JavaDiscountCourse) javaCourse).getDisCountPrice()
        );
    }

7、合成复用

组合/聚合可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少;其次才考虑继承,在使用继承时,需要严格遵循里氏代换原则,有效使用继承会有助于对问题的理解,降低复杂度,而滥用继承反而会增加系统构建和维护的难度以及系统的复杂度,因此需要慎重使用继承复用。

举个例子还是会有助于理解哈:比如一个人可以是学生也可以是经理而“学生”和“经理”都可以成为某公司的“雇员”,这里就可以来理解一下Has-A和Is-A了 学生和经理都是人的一种 那么他们与人的关系就是 Is-A 的关系,而 雇员是人的一个属性 所以 雇员与人之间是 Has-A 的关系,如果聚合复用原则来设计的话关系图如下:

145天以来,Java架构更新了 428个主题,已经有91位同学加入。微信扫码关注java架构,获取Java面试题和架构师相关题目和视频。上述相关面试题答案,尽在Java架构中。

上一篇 下一篇

猜你喜欢

热点阅读