七大设计原则
开闭原则
依赖导倒置原则
单一职责原则
接口隔离原则
迪米特原则
里氏替换原则
合成复用原则
设计模式-创建型模式
工厂方法模式
抽象工厂模式
建造者模式
单例模式
原型模式
设计模式-结构性模式
适配器模式
装饰者模式
代理模式
外观模式
桥接模式
组合模式
享元模式
设计模式-行为型模式
策略模式
模板方法模式
观察者模式
访问者模式
迭代器模式
责任链模式
中介者模式
解释器模式
状态模式
命令模式
备忘录模式
开闭原则
定义:一个软件实体如类,模块和函数应该对扩展开放,对修改关闭。
用抽象构建框架,用实现扩展细节
优点:提高软件系统的可复用性及可维护性
下面给一个代码体现开闭原则:
package principle.openClose;
public interface ICourse {
Integer getId();
String getName();
Double getPrice();
}
package principle.openClose;
public class javaCoure implements ICourse {
private Integer id;
private String name;
private Double price;
public javaCoure(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;
}
}
package principle.openClose;
public class Test {
public static void main(String[] args) {
ICourse javaCoures = new javaCoure(88,"语文",100d);
System.out.println("课程id:"+javaCoures.getId()+" 课程名称:"+javaCoures.getName()+" 课程价格:"+javaCoures.getPrice());
}
}
现在价格要变的话怎么写呢?
方法一:在ICourse中加入如下代码
Double getDiscountPrice();
在javaCourse中添加如下代码
public Double getDiscountPrice(){
return this.price*0.8;
}
有啥问题呢,如果课程很多,那么所有的课程都要加上这些价格变化的方法。接口不能随便动,否则作为契约的作用就失去了。
方法二:直接在得到价格的方法中改
@Override
public Double getPrice() {
return this.price;
}
改成:
@Override
public Double getPrice() {
return this.price*0.8;
}
有啥问题呢?看起来比上面更简洁了。和上面一样,如果课程很多的话,修改的地方也很多,如果需求还要你显示原价,这就行不通了吧。在复杂一点,如果课程》300元的才进行打折活动,如果后面还加了优惠券的活动呢?
方法三:终极方法
增加一个方法,继承javaCoure
package principle.openClose;
public class JavaDiscountCourse extends javaCoure {
public JavaDiscountCourse(Integer id, String name, Double price) {
super(id, name, price);
}
@Override
public Double getPrice() {
return super.getPrice()*0.8;
}
public Double getOriginPrice(){
return super.getPrice();
}
}
依赖倒置原则
定义:高层模块不应该依赖低层模块,二者应该依赖其抽象。
抽象不应该依赖细节;细节应该依赖缓抽象
针对接口编程,不应该针对实现编程
优点:可以减少类间的耦合性,提高系统稳定性,提高代码可读性和可维护性,可降低修改程序所造成的风险。
请看下面代码:
package design.dependenceInVersion;
public class Xwy {
public void studyJavaCourse(){
System.out.println("xwy在学习java课程");
}
public void studyFECourse(){
System.out.println("xwy在学习前端课程");
}
}
再写一个测试类:
package design.dependenceInVersion;
public class Test {
public static void main(String[] args) {
Xwy xwy = new Xwy();
xwy.studyFECourse();
xwy.studyJavaCourse();
}
}
如果要再学习一个课程,就需要在Xwy类中加一个方法。
这是面向实现编程,实现类需要经常修改,扩展性差。
下面有几种改进的方法
package design.dependenceInVersion;
public interface Icourse {
void studyCourse() ;
}
package design.dependenceInVersion;
public class JavaCourse implements Icourse {
@Override
public void studyCourse() {
System.out.println("xwy在学习java课程");
}
}
package design.dependenceInVersion;
public class EFCourse implements Icourse {
@Override
public void studyCourse() {
System.out.println("xwy在学习前端课程");
}
}
package design.dependenceInVersion;
public class Xwy {
private Icourse icourse;
//v1
// public void studyFECourse() {
// System.out.println("FE课程");
// }
//
// public void studyJavaCourse() {
// System.out.println("java课程");
// }
//v2
// public void studyXwyCourse(Icourse icourse){
// icourse.studyCourse();
// }
//v3
// public Xwy(Icourse icourse) {
// this.icourse = icourse;
// }
//
// public void studyXwyCourse(){
// icourse.studyCourse();
// }
//v4
public void setIcourse(Icourse icourse) {
this.icourse = icourse;
}
public Xwy() {
}
public void studyXwyCourse(){
icourse.studyCourse();
}
}
package design.dependenceInVersion;
public class Test {
public static void main(String[] args) {
//v1
// Xwy xwy = new Xwy();
// xwy.studyFECourse();
// xwy.studyJavaCourse();
// //v2
// Xwy xwy = new Xwy();
// xwy.studyXwyCourse(new JavaCourse());
// xwy.studyXwyCourse(new EFCourse());
//v3
// Xwy xwy = new Xwy(new JavaCourse());
// xwy.studyXwyCourse();
//v4
Xwy xwy = new Xwy();
xwy.setIcourse(new JavaCourse());
xwy.studyXwyCourse();
xwy.setIcourse(new EFCourse());
xwy.studyXwyCourse();
}
}
上面有4种写法
第一种:直接实现Icoure接口,在客户端需要哪个方法就调哪个方法,Xwy xwy = new Xwy();
xwy.studyFECourse();
xwy.studyJavaCourse();
第二种方法:使用接口方法注入
Xwy xwy = new Xwy();
xwy.studyXwyCourse(new JavaCourse());
xwy.studyXwyCourse(new EFCourse());
第三种方法:使用构造器
Xwy xwy = new Xwy(new JavaCourse());
xwy.studyXwyCourse();
第四种方法:使用set注入
Xwy xwy = new Xwy();
xwy.setIcourse(new JavaCourse());
xwy.studyXwyCourse();
xwy.setIcourse(new EFCourse());
xwy.studyXwyCourse();
单一职责原则
- 定义:不要存在多于一个导致类变更的原因
- 一个类/ 接口/方法只负责一项职责
- 优点:降低类的复杂度、提高类的可读性,提高系统的可维护性、降低变更的风险
接口隔离原则
- 定义:用多个专门的接口,二不使用单一的总接口,客户端不应该依赖他不需要的接口
- 一个类对应一个类的依赖应该建立在最小的接口上
- 建立单一接口,不要建立庞大臃肿的接口
- 尽量细化接口,接口中的方法尽量少
- 适度原则,一定要适度
- 优点:符合高内聚低耦合的设计思想,从而使得类具有很好的可读性、可扩展性和可维护性
下面来先看下代码
package design.interfaceGeragion;
public interface IAnimalAction {
void eat();
void fly();
void swim();
}
package design.interfaceGeragion;
public class Dog implements IAnimalAction {
@Override
public void eat() {
}
@Override
public void fly() {
}
@Override
public void swim() {
}
}
package design.interfaceGeragion;
public class Bird implements IAnimalAction {
@Override
public void eat() {
}
@Override
public void fly() {
}
@Override
public void swim() {
}
}
再来看下面的代码
package design.interfaceGeragion;
public interface IEatAnimalAction {
void eat();
}
package design.interfaceGeragion;
public interface IFlayAnimalAction {
void fly();
}
package design.interfaceGeragion;
public interface ISwrimAction {
void swim();
}
package design.interfaceGeragion;
public class Bird implements IEatAnimalAction,IFlayAnimalAction {
@Override
public void eat() {
}
@Override
public void fly() {
}
}
package design.interfaceGeragion;
public class Dog implements IEatAnimalAction,ISwrimAction {
@Override
public void eat() {
}
@Override
public void swim() {
}
}
这个代码比上个代码更加灵活
迪米特原则
- 定义:一个对象对其他对象保持最少的了解。又叫最少知道原则
- 尽量降低类与类之间的耦合
- 优点:降低类之间的耦合
- 强调只和朋友交流
- 朋友:出现在成员变量、方法的输入、输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类
看下面的代码
package design.dimiter;
import java.util.List;
public class TeamLeader {
public void checkNumberOfCourse(List<Coures> couresList){
System.out.println("在线课程的数量是:"+couresList.size());
}
}
package design.dimiter;
public class Coures {
}
package design.dimiter;
import java.util.ArrayList;
import java.util.List;
public class Boss {
public void commandCheakNumber(TeamLeader teamLeader){
List<Coures> couresList = new ArrayList<>();
for (int i=0;i<20;i++){
couresList.add(new Coures());
}
teamLeader.checkNumberOfCourse(couresList);
}
}
package design.dimiter;
public class Test{
public static void main(String[] args) {
Boss boss = new Boss();
TeamLeader teamLeader = new TeamLeader();
boss.commandCheakNumber(teamLeader);
}
}
idea生成的类图如下:
course不应该和boss产生交集,把boss里的代码:
List<Coures> couresList = new ArrayList<>();
for (int i=0;i<20;i++){
couresList.add(new Coures());
}
移到TeamLeader中