开闭原则(面向对象的核心原则):
软件实体面向修改关闭,面向拓展开放
实现的核心是:抽象
将类似的东西抽取出来,便于代码的重复利用(相同部分由父类描述
将不像的东西抽取出来,便于功能的拓展(不同部分由子类去描述
//在设计上,子类共有并相似的方法则抽象出来由父类进行描述,并不相似的实现则由子类自己去进行实现
public abstract class Human{
public abstract void say();
public void breathe(){
System.out.println("呼吸");
}
}
class Peo1 extends Human{
public void say(){
System.out.println("我是Peo1");
}
}
class Peo2 extends Human{
public void say(){
System.out.println("我是Peo2");
}
}
单一职责原则(高内聚):
一个类只应该有一种引起它变化的原因,不应该有多个引起它变化的理由
一个类只应该完成一个职责相关的业务,不要让一个类去承担过多的职责(以职责去划分问题域)
public class A{
public void aSay(){
bRun();
cFight();
}
public void bRun(){
...
}
public void cFight(){
...
}
}
public class A{
B b = new B();
C c = new C();
public void aSay(){
b.run()
c.fight();
}
}
class B{
public void run(){
...
}
}
class C{
public void fight(){
...
}
}
依赖倒置原则(低耦合):
面向抽象编程,不要面向具体编程
尽量使用抽象耦合,代替具体耦合
class A{
...
}
class B extends A{
...
}
class C extends A{
...
}
public class Test{
public static List<B>bList = new ArrayList<B>();
public static List<C>bList = new ArrayList<c>();
}
class A{
...
}
class B extends A{
...
}
class C extends A{
...
}
public class Test{
public static List<A>bList = new ArrayList<A>();
}
聚合组合复用原则:
尽量使用聚合组合达到代码的复用,而不是使用继承达到代码复用
由于在java中只能单根继承,用继承方式来重用代码并不现实,而聚合/组合方式是可行的
class Bird{
public void fly(){
...
}
}
class Fish{
public void swimming(){
...
}
}
public class peo{
//人无法通过继承而直接同时使用两个类的方法
}
class Airplane{
public void fly(){
...
}
}
class Ship{
public void swimming(){
...
}
}
public class peo{
//但是可以通过聚合/组合方式进行方法的调用
Airplane airplane = new Airplane();
Ship ship = new Ship();
airplane.fly();
ship.swimming();
}
里氏替换原则:
父类出现的地方,子类一定可以进行替换,如果父类的方法在子类中并不适用(或是发生了歧义),则应该断开父子关系,采用依赖、聚合/组合实现代码复用。
因为父类中的属性与方法子类无条件继承,会造成父类的方法在子类中不适用的情况发生
public class Gun{
public void say(){
System.out.println("这是一把枪")
}
public abstract void kill();
}
class AkGun extends Gun{
...
}
class ToyGUn extends Gun{
//玩具理论上无法实现枪械的kill方法,并不能继承此父类
}
class ToyGUn{
public void say(Gun g){
g.say();
}
}
迪米特法则:
软件实体之间应该尽量减少交互,不要因为一个类的变化而导致另外一个类的变化
public class MainRun{
A a = new A();
a.say();
a.run();
a.fight();
}
class A{
public void say(){
...
}
public void run(){
...
}
public void fight(){
...
}
}
public class MainRun{
A a = new A();
a.all();
}
class A{
public void all(){
say();
run();
fight();
}
public void say(){
...
}
public void run(){
...
}
public void fight(){
...
}
}