7大原则
不会设计模式,何以叫java工程师?
若有不恰之处,请各位道友指正~
单一职责原则
- 1,降低类的复杂度,一个类只负责一项职责
- 2,提高类的可读性,可维护性
- 3,降低变更带来的风险
- 4,只有类中方法足够少,可以在方法级别上违反单一原则
开闭原则
- 1,一个软件实体如类,模块和函数应该对外扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节
- 2,当软件需要变化时,尽量通过扩展软件的实体的行为来实现变化,而不是通过修改已有的代码实现变化
比较直接喜欢先上代码看,容易理解:
public class OpenClose {
public static void main(String[] args) {
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
}
}
// 绘图的类
class GraphicEditor{
public void drawShape(Shape s){
s.draw();
}
}
abstract class Shape{
public abstract void draw();
}
//三角形
class Rectangle extends Shape{
@Override
public void draw() {
System.out.println("绘制三角形");
}
}
class Circle extends Shape{
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
简而言之
开闭原则:就是使用抽象类或者接口的方式实现子类,然后调用方使用父类作为入参。这样可以避免一个类,new一个对象,调用一个方法。
里氏替换原则
- 在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法
- 里氏替换原则告诉我们,继承实际上让两个类耦合性增强,在适当的情况下,可以通过聚合,组合,依赖解决问题
直接上代码看:
public class LiskovSubstitution {
public static void main(String[] args) {
B b = new B();
Integer plus = b.plus(11, 7);
System.out.println(plus);
}
}
class Base{
//把更加基础的方法和成员写道Base类
}
class A extends Base{
public Integer add(int a , int b){
return (a-b) - 9;
}
}
class B extends Base{
//组合
private A a = new A();
public Integer add(int a , int b){
return a-b;
}
public Integer plus(int a , int b){
return this.a.add(a,b);
}
}
简而言之
里氏替换原则:当两个父子继承的类,有相同方法的时候,就用更基础的类作为父类,通过组合的方式解耦。
接口隔离原则
直接上代码:
public class InterfaceSegregation {
public static void main(String[] args) {
C c = new C();
c.depend2(new A());// C类 通过接口依赖 A类
}
}
//接口类
interface Interface1{
void operation1();
}
interface Interface2{
void operation2();
void operation3();
}
interface Interface3{
void operation4();
void operation5();
}
//实现
class A implements Interface2 ,Interface3{
@Override
public void operation2() {
System.out.println("2");
}
@Override
public void operation3() {
System.out.println("3");
}
@Override
public void operation4() {
System.out.println("4");
}
@Override
public void operation5() {
System.out.println("5");
}
}
// C类通过接口 Interface2 ,Interface3 依赖(使用)A类,但是指挥用到2,3,4,5方法
class C{
public void depend2(Interface2 i){
i.operation2();
}
public void depend3(Interface2 i){
i.operation3();
}
public void depend4(Interface3 i){
i.operation4();
}
public void depend5(Interface3 i){
i.operation5();
}
}
简而言之
接口隔离原则:当A 要实现 B的时候,A其实只需要B其中的几个方法时,可以把A拆分成若干个接口。
依赖倒置原则
依赖关系传递的三种方式
- 1,接口传递
- 2,构造方法传递
- 3,setter方式传递
注意事项:
- 1,低层模块尽量都要有抽象类或接口,或者两者都用
- 2,变量的声明类型尽量是抽象或接口,这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序的扩展和调优
- 3,继承时遵循里氏替换原则
上代码:
public class DependenceInversion {
public static void main(String[] args) {
//接口实现
// Person person = new Person();
// person.get(new Mail());
// person.get(new Wechat());
//构造方法传递
// Person person = new Person(new Mail());
// person.get();
//setter方式传递
Person person = new Person();
person.setter(new Mail());
person.get();
}
}
class Person{
// 接口传递
// public void get(Ireceiver ireceiver){
// ireceiver.sendMsg();
// }
// 构造方法传递
// public Ireceiver ireceiver;
// public Person(Ireceiver ireceiver){
// this.ireceiver = ireceiver;
// }
// public void get(){
// ireceiver.sendMsg();
// }
//setter方式传递
public Ireceiver ireceiver;
public void get(){
ireceiver.sendMsg();
}
public void setter(Ireceiver ireceiver){
this.ireceiver = ireceiver;
}
}
class Mail implements Ireceiver{
@Override
public void sendMsg() {
System.out.println("发送邮件");
}
}
class Wechat implements Ireceiver{
@Override
public void sendMsg() {
System.out.println("发送微信消息");
}
}
interface Ireceiver{
void sendMsg();
}
简而言之
依赖倒置原则:回头看看开闭原则,会发现两个玩意差不多吧,抽象类改成接口了。使用三种方式去接受参数(方法入参,构造方法,setter方法)
迪米特法则
- 1,一个对象应该对其他对象保持最少的了解
- 2,类与类关系越密切,耦合度越大
- 3,对于被依赖的类不管多复杂,都尽量将逻辑封装在类内部,对外提供public 方法,不对外泄露任何信息
- 4,只与直接朋友通讯
- 5,直接朋友(成员变量/方法参数/方法返回值称为直接朋友)(推荐),即陌生的朋友(局部变量的的形式出现在类的内部)(不推荐)
上代码干:
public class Demeter {
public static void main(String[] args) {
}
}
//学校总部egeEmployee员工
class Employee{
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
// ... 做employee 做的事,别让别的类调用Employee 来处理,只提供public 方法
}
//学院员工
class CollegeEmployee{
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
简而言之
迪米特原则:和单一原则差不多,一个是类中的成员描述的对象单一性。迪米特原则则单一对象的操作,应该由该对象封装,对外只提供public方法。
合成复用原则
1,尽量是使用合成/聚合的方式,而不是使用继承(参考:设计模式1之(UML类图))