一、软件7大设计原则

开闭原则

依赖倒置原则

单一职责原则

接口隔离原则

迪米特原则

里氏替换原则

合成复用原则

1. 开闭原则

定义:一个软件实体,如类、模块和函数应该对扩展开发,对修改关闭。

用抽象构建框架,用实现扩展细节。

优点: 提过软件系统的可复用性及可维护性

 

Code:

增加ICourse 接口

public interface ICourse {
    Integer getId();
    String getName();
    Double getPrice();

}

  

JavaCourse类

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;
    }


}

  

增加打折类JavaDiscountCourse 

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

    public Double getOriginPrice(){
        return  super.getPrice();
    }

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

  

测试:

public class Test {
    public static void main(String[] args) {
        ICourse iCourse = new JavaDiscountCourse(90,"Java学习",300d);
        JavaDiscountCourse javaCourse = (JavaDiscountCourse)iCourse;

        System.out.println("课程Id:" + iCourse.getId() + "  名称:" + iCourse.getName() + " 折后价格:" + iCourse.getPrice() + " 原价: " + javaCourse.getOriginPrice());
    }
}

当课程增加打折功能时,我们没有在接口中增加打折方法,而是增加JavaDiscountCourse。 这样就做到了对接口ICourse 修改是关闭的,对扩展的功能进行开发,通过JavaDiscountCourse 来实现增加的功能

 

2. 依赖倒置原则

定义: 高层模块不应该依赖底层模块,二者都应该依赖其抽象。

抽象不应该依赖细节;细节应该依赖抽象

针对接口编程,不要针对实现编程

 

优点: 可以减少类间的耦合性、提高系统的稳定性,提高代码可读性和可维护性,可降低修改程序所造成的风险

2.1 Code:

新建Tom

public class Tom {

   public void studyJavaCourse(){
        System.out.println("Tom学习Java");
    }

    public  void studyAndroidCourse(){
        System.out.println("Tom学习Android");
    }

}    

新建测试类Test.java

 public static void main(String[] args) {
       Tom tom = new Tom();
        tom.studyAndroidCourse();
        tom.studyJavaCourse();

    }  

测试类依赖于Tom,如果此时要增加学习Ios方法,我们可以在Tom类中增加studyIosCourse。但是这样Test类完全依赖于Tom类,完全耦合在一起了。

 

2.2 修改后的Code

1) 新增接口

public interface ICourse {
    void  studyCourse();
}

  

2)增加JavaCourse类,实现ICourse接口

public class JavaCourse implements  ICourse{
    @Override
    public void studyCourse() {
        System.out.println("学习Java");
    }
}

  

3) 增加AndroidCourse类

public class AndroidCourse implements ICourse {
    @Override
    public void studyCourse() {
        System.out.println("学习Android");
    }
}

  

4) 测试类Test.java

   public static void main(String[] args) {
       Tom tom = new Tom();
       tom.study(new JavaCourse());
       tom.study(new AndroidCourse());
    }

 如果此时要增加学习Ios方法,只需要增加IosCourse类,并实现ICourse接口即可。Test类与Tom类解耦,Tom类与具体的课程实现解耦。

 

3. 单一职责原则

定义:不要存在多于一个导致类变更的原因

 一个类/接口/方法只负责一项职责

 

优点:降低类的复杂度、提高类的可读性,提高系统的可维护性、降低变更引起的风险

 

 4. 接口隔离原则

 定义:用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接口

一个类对一个类的依赖应该建立在最小的接口上

建立单一接口,不要建立庞大臃肿的接口

尽量细化接口,接口中的方法尽量少

 

注意点:

注意适当原则,一定要适度

 

优点:符合我们常说的高内聚低耦合的设计思想

      从而使得类具有很好的可读性、可扩展性和可维护性。

 

如下面的类图

设计模式实践

接口IAnimalAction有三个方法 eat,fly,swim。 Dog实现了这个接口,但是Dog不会fly。 Bird类实现了这个接口,但是有些Bird不会fly或者swim。

这样就导致了类中的一些空实现。

如下图的改进版本:

设计模式实践

Dog类实现了IEatAnimalAction和ISwimAnimalAction。

 

5. 迪米特原则

定义: 一个对象应该对其他对象保持最少的了解。又叫最少知道原则

尽量降低类与类之间的耦合

优点: 降低类之间的耦合

 

迪米特原则强调:

强调只和朋友交流,不和陌生人说话

朋友:出现在成员变量、方法的输入、输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类。

 

Code 需求:Boss问teamLeader,要知道线上有几个课程上线

1. 创建Course类

public class Course {
}

  创建TeamLeader类

public class TeamLeader {
    public  void  checkNumberOfCourses(List<Course> courseList){
        System.out.println("课程数量是:" + courseList.size());
    }
}    

创建Boss类

public class Boss {
    public  void commandCheckNumber(TeamLeader teamLeader){
        List<Course> courseList = new ArrayList<>();
        for(int i = 0; i < 20; i++){
            courseList.add(new Course());
        }

        teamLeader.checkNumberOfCourses(courseList);
    }
}

  创建测试类

public class Test
{
    public static void main(String[] args) {
        Boss boss = new Boss();
        TeamLeader teamLeader = new TeamLeader();
        boss.commandCheckNumber(teamLeader);

    }
}  

根据迪米特原则,Boss类中和Course类耦合在一起,实际上他不需要知道Course。

 

分析类图

设计模式实践

Boss类中创建Course中,耦合在一起了。

 

 

修改版本:

Boss类

public class Boss {
    public  void commandCheckNumber(TeamLeader teamLeader){
        teamLeader.checkNumberOfCourses();
    }
}

  

TeamLeader类

public class TeamLeader {
    public  void  checkNumberOfCourses(){

        List<Course> courseList = new ArrayList<>();
        for(int i = 0; i < 20; i++){
            courseList.add(new Course());
        }
        System.out.println("课程数量是:" + courseList.size());
    }
}

 其他类不变。 

UML图变化如下:

设计模式实践

 

 

 

 

二、设计模式

1. 创建新模式

       工厂方法模式

  抽象工厂模式

  建造者模式

  单例模式

  原型模式

 

2. 结构性模式

  适配器模式

  装饰者模式

  代理模式

  外观模式

  桥接模式

  组合模式

  享元模式

 

行为性模式

  策略模式

  观察者模式

  责任链模式

  备忘录模式

  模板方法模式

  迭代器模式

  中介者模式

  命令模式

  访问者模式

  解释器模式

  状态模式

 

相关文章: