一、开闭原则
开闭原则是面向对象设计的最基础原则,其核心可以概括为对扩展开放,对修改封闭。这句话意思是当需求变更时可以对原有代码进行扩展实现新功能,不需要改动原有代码。举个不太恰当的例子。例如原有三轮车销售店只销售三轮车,因业务扩张现在也销售自行车。此时比较能体现开闭原则,我们可以再遵循三轮车定义方法重新处理自行车的逻辑。
代码demo如下,先创建car实体
public class Car {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String print() {
return "name:" + this.name;
}
}
定义基础接口
public interface BaseCar {
Car getCar();
}
处理三轮车逻辑
public class ThreeRoundsCar implements BaseCar {
public Car getCar() {
Car car = new Car();
car.setName("三轮车");
return car;
}
}
处理自行车逻辑
public class TwoRoundsCar implements BaseCar {
public Car getCar() {
Car car = new Car();
car.setName("两轮车");
return car;
}
}
创建测试方法
public class Test {
public static void main(String[] args) {
// 所有车遵循同一接口定义,最开始只有三轮车处理逻辑
BaseCar threeRounds = new ThreeRoundsCar();
Car ThreeRoundsCar = threeRounds.getCar();
System.out.println(ThreeRoundsCar.print());
// 新增两轮车处理逻辑,其逻辑完全由TwoRoundsCar实现,不影响三轮车
BaseCar twoRounds = new TwoRoundsCar();
Car twoRoundsCar = twoRounds.getCar();
System.out.println(twoRoundsCar.print());
}
}
二、里氏替换原则
里氏替换原则可以概括为子类可以扩展父类的功能,但不能改变父类原有的功能,其解释如下:
1.子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
2.子类中可以增加自己特有的方法。
3.当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
4.当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
代码demo如下,创建父类Parent
public class Parent {
public String getInfo(){
return "parent";
}
}
创建子类Child
public class Child extends Parent {
// 父类方法不是抽象方法不能覆盖,降低代码出现问题几率
// public String getInfo(){
// return "child";
// }
// 子类可自定义方法
public String get() {
return "child";
}
}
创建测试类
public class Test {
public static void main(String[] args) {
Child child = new Child();
System.out.println(child.getInfo());
System.out.println(child.get());
}
}
三、依赖倒置原则
依赖倒置原则可以概括为通过抽象类或接口使各模块之间彼此独立,降低耦合度。
以司机驾车为例,代码demo如下,创建司机接口Driver
public interface Driver {
public void driverCar(BaseCar baseCar);
}
创建司机实现类
public class DriverImpl implements Driver {
public void driverCar(BaseCar baseCar) {
baseCar.run();
}
}
创建车基础接口
public interface BaseCar {
void run();
}
三轮车实现baseCar接口,增加处理逻辑
public class ThreeRoundsCar implements BaseCar {
public void run() {
System.out.println("三轮车运行");
}
}
创建测试类运行
public class Test {
public static void main(String[] args) {
// 司机开三轮车
Driver driver = new DriverImpl();
ThreeRoundsCar threeRoundsCar = new ThreeRoundsCar();
driver.driverCar(threeRoundsCar);
}
}
如果想开自行车可以新增自行车实现baseCar接口,在测试类中TwoRoundsCar twoRoundsCar = new TwoRoundsCar();进行调用
public class TwoRoundsCar implements BaseCar {
public void run() {
System.out.println("自行车运行");
}
}
四、接口隔离原则
接口隔离原则指建立单一接口,接口中方法尽量少,当接口中方法过多时拆分出来。
demo代码如下,新建BaseCar接口
public interface BaseCar {
void run();
void run1();
void run2();
void run3();
}
新建ThreeRoundsCar实现类,ThreeRoundsCar使用run2,run3方法。
public class ThreeRoundsCar implements BaseCar {
public void run() {
}
public void run1() {
}
// ThreeRoundsCar 用run2,run3
public void run2() {
System.out.println("run2");
}
public void run3() {
System.out.println("run3");
}
}
新建TwoRoundsCar实现类,该实现类使用run,run1方法。
public class TwoRoundsCar implements BaseCar {
// TwoRoundsCar 用run,run1
public void run() {
System.out.println("自行车运行");
}
public void run1() {
System.out.println("run1");
}
public void run2() {
}
public void run3() {
}
}
此时TwoRoundsCar用不到run2,run3。ThreeRoundsCar用不到run,run1为遵循接口隔离原则,需要对BaseCar拆分为TwoRoundsBaseCar与ThreeRoundsBaseCar两个接口,接口中定义需要的方法。
public interface TwoRoundsBaseCar {
void run();
void run1();
}
public interface ThreeRoundsBaseCar {
void run2();
void run3();
}
五、单一职责原则
单一职责指一个类或接口只负责一种功能,比如新建BaseCar接口,其拥有自身职能与商品职能
public interface BaseCar {
// 自身职能
void run();
// 商品职能
void buyCar();
}
这种情况违反了单一职责,需要对接口进行拆分为自身职能接口与商品职能接口。
public interface GoodsFunctionCar {
// 商品职能
void buyCar();
}
public interface SelfFunctionCar {
// 自身职能
void run();
}
六、迪米特法则
迪米特法则要求尽量减少类之间直接交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果一个对象的某一个方法需要调用另一个对象的诸多方法,可以通过第三者转发这个调用,调用者对被调用者内部的情况知道的越少越好。
以消费者买车为例,消费者与汽车工厂之间不必要彼此通信,在实际写代码时可增加工厂代理类负责消费者与汽车工厂间通信。代码如下
新建汽车工厂CarFactory
public class CarFactory {
public void placeOrder() {
System.out.println("定制化汽车下单");
}
public void create() {
System.out.println("定制化制作");
}
public void pickUpCar() {
System.out.println("提货");
}
}
新建经销商销售汽车
public class CarProxy {
/**
* 销售汽车
*/
void saleCar() {
CarFactory carFactory = new CarFactory();
carFactory.placeOrder();
carFactory.create();
carFactory.pickUpCar();
}
}
消费者只需通过经销商购买即可
public class Consumer {
void buyCar() {
CarProxy carProxy = new CarProxy();
carProxy.saleCar();
}
}