자바의 7 가지 설계 원칙, Liskov 대체 원칙의 의존 반전 (이해할 텍스트 코드 조합)

자바의 7 가지 디자인 원칙, 리히터 대체 원칙, 이해해야 할 텍스트 코드 조합의 신뢰 반전

원한다면 싸우고, 얻으면 소중히하고, 놓치면 잊어 버리세요. 인생은 완벽하지 않을 수 있습니다. 불완전하기 때문에 우리는 창조하고 노력하기 위해 계속 열심히 노력해야합니다. 시간은 생명 이니 소중한 삶을 소중히 여기고 삶의 모든 갈림길을 끈기있게 기다려야합니다.

7 가지 디자인 원칙은 무엇입니까?

  • 단일 책임 원칙
  • 인터페이스 분리 원리
  • 의존성 반전 (반전) 원리
  • 리히터 대체 원칙
  • 개폐 원리
  • Dimit의 법칙
  • 합성 재사용 원칙

일반적으로 모든 사람이 처음 6 개를 이해하고 합성 재사용 원칙이 없습니다.

7 가지 디자인 원칙을 사용하는 이유는 무엇입니까?

  • 코드 재사용 성 (동일한 코드를 여러 번 작성할 필요가 없음)
  • 가독성 (프로그래밍 표준화, 다른 프로그래머가 쉽게 읽고 이해할 수 있음)
  • 확장 성 (새로운 기능을 추가해야 할 때 유지 보수성이라고도하는 매우 편리합니다.)
  • 신뢰성 (새 기능을 추가해도 원래 기능에 영향을주지 않음)
  • 프로그램이 높은 응집력과 낮은 결합의 특성을 제시하도록합니다.

의존성 반전 원리

종속성 반전 원칙 정의 :

  • 고수준 모듈은 저수준 모듈에 의존해서는 안되며 둘 다 추상화에 의존해야합니다.
  • 반전 원리에 의존하는 핵심 아이디어는 인터페이스 지향 프로그래밍입니다.
  • 인터페이스 또는 추상 클래스를 사용하는 목적은 특정 작업을 포함하지 않고 좋은 사양을 공식화하고 세부 작업을 구현 클래스에 위임하여 완료하는 것입니다.

신뢰 반전의 원리는 디자인 개념에 기반을두고 있습니다. 세부 사항에 비해 추상이 훨씬 더 안정적입니다. 추상화 기반 프레임 워크는 세부 정보 기반 프레임 워크보다 훨씬 더 안정적 입니다. Java에서 추상화는 인터페이스 또는 추상 클래스를 나타내며 세부 사항은 특정 구현 클래스입니다.

일반 코드 :

//输出消息
public class QQNews {
    
    
    public  void  run(){
    
    
        Log.i("Inversion","我是 QQ 发送的消息 ");
    }
}
//接收消息
public class Information {
    
    
    public void showInfo(QQNews qqNews){
    
    
        qqNews.run();
    }
}

//使用代码:
Information information = new Information();
information.showInfo(new QQNews());

문제:

  • 클래스와 직접 상호 작용하며 전송 메시지는 상대적으로 고정됩니다.
  • 지금 위챗 메시지를 받고 싶다면 코드가 수정되어 수신이 안 돼서 이제 QQ 메시지 만받을 수 있습니다. 위챗 메시지 수신이 필요한 경우에는 위챗 메시지 수신 방법을 다시 작성해야합니다. 정보 클래스.
  • '버퍼 레이어'가없고 showInfo () 메서드가 QQNews 클래스와 직접 상호 작용하며 '탄력성'이 너무 낮습니다.
  • 종속성 반전 원칙을 준수하지 않는 경우 종속성 반전 원칙의 핵심 아이디어는 인터페이스 지향 프로그래밍입니다.

종속성 반전 원칙 코드를 따르십시오.

    ///接收的消息
public interface Iinversion {
    
    
    void run();
}
//QQ发送消息
public class QQNews implements Iinversion {
    
    
    @Override
    public void run() {
    
    
        Log.i("Inversion", "我是 QQ 发送的消息");
    }
}
//微信发送消息
public class WeChatNews  implements Iinversion{
    
    
    @Override
    public void run() {
    
    
        Log.i("Inversion","我是 微信 发送的消息");
    }
}

코드 사용 :

InversionBean inversionBean = new InversionBean();
inversionBean.run(new QQNews());
inversionBean.run(new WeChatNews());

이점:

  • 클라이언트 (InversionBean)는 Iinversion (인터페이스) 과만 상호 작용하고 결합이 감소하며 종속성 반전에서 인터페이스 지향 프로그래밍의 원칙이 엄격하게 준수됩니다.
  • 위와 같이 코드가 수정되지 않고 조건을 판단 할 필요가 없습니다 .QQ 통과시 QQ 메시지를 받고, WeChat 통과시 WeChat 메시지를 받게됩니다. 훨씬 더 안정적입니다.

반전 원리에 의존하는 세 가지 방법 :

방법 1 :

전송 인터페이스 (Iinversion)의 구현 클래스 (QQNews)를 통해 인터페이스 전송 완료

public interface Iinversion {
    
    
    ///接收的消息
    void run();
}
public class QQNews implements Iinversion {
    
    
    @Override
    public void run() {
    
    
        Log.i("Inversion", "我是 QQ 发送的消息");
    }
}

Information information = new Information();
information.showInfo(new QQNews());

방법 2 :

매개 변수화 된 구성 방법을 통해 인터페이스 전송 완료

public interface Iinversion {
    
    
    ///接收的消息
    void run();
}

public class Information {
    
    

   Iinversion mIinversion;
   
    public Information(Iinversion iinversion) {
    
    
        mIinversion = iinversion;
    }
    public void showInfo(){
    
    
        mIinversion.run();
    }
}
//使用代码
Information information = new Information(new QQNews());
information.showInfo();

방법 3 :

set 메소드를 통해 인터페이스 전송을 완료하십시오.

public interface Iinversion {
    
    
    ///接收的消息
    void run();
}
//传递消息 
public class QQNews implements Iinversion {
    
    
    @Override
    public void run() {
    
    
        Log.i("Inversion", "我是 QQ 发送的消息");
    }
}

public class Information {
    
    

    private Iinversion mIinversion;

    public void showInfo(){
    
    
        mIinversion.run();
    }
    public void setIinversion(Iinversion iinversion) {
    
    
         mIinversion =iinversion;
    }
}

//使用代码:
Information information = new Information();
information.setIinversion(new QQNews());
information.showInfo();

리히터 대체 원칙

기본 소개 :

  • 리히터 대체 원칙은 1988 년 MIT 성의 여성이 제안했습니다.

리히터 대체 원칙의 정의 :

  • 상속 할 때 Richter 대체 원칙을 따르고 하위 클래스에서 상위 클래스의 메서드를 재정의하지 마십시오.
  • 기본 클래스에 대한 모든 참조는 하위 클래스의 객체를 투명하게 사용할 수 있어야합니다.
  • Richter 대체 원칙은 상속이 실제로 두 클래스의 결합을 향상 시킨다는 것을 말하며 적절한 상황에서 집계, 구성 및 종속성을 통해 문제를 해결할 수 있습니다.
  • 프로그램의 상위 클래스는 하위 클래스로 대체 될 수 있습니다.

Richter의 대체 원칙 코드를 준수하지 않음 :

public class ReplaceA {
    
    
    public int show(int a, int b){
    
    
        return  a+b;
    }
}

public class ReplaceB extends ReplaceA{
    
    
    @Override
    public int show(int a, int b){
    
    
        return  a-b;
    }
}

//使用代码:
 //里氏替换原则
ReplaceA replaceA = new ReplaceA();
ReplaceB replaceB = new ReplaceB();

Log.i("LiReplace","2 + 3 = "+replaceA.show(2,3)+"");
Log.i("LiReplace","2 + 3 = "+replaceB.show(2,3)+"");

알 수있는 바와 같이:

  • 클래스 A의 출력은 a + b의 합입니다.
  • 클래스 B에서 클래스 A의 show () 메서드가 다시 작성되고 출력은 ab입니다.

문제:

  • 클래스 B는 클래스 A를 상속하기 때문에 클래스 A의 모든 메서드를 클래스 B에서 사용할 수 있으므로 클래스 B의 결합이 매우 높아집니다.
  • 그리고 A 급에 새로운 메소드가 추가되고 B 급을 사용하지 않으면 커플 링 개선으로 이어질 수 있는데, B 급을 사용하지 않으면 호출 할 수 있고 B 급의 침입 성을 증가 시키는가?
  • 이 코드에서 replaceB의 원래 의도는 부모 클래스의 show () 메서드를 호출하여 합계하는 것이었지만 차이점을 찾기 위해 부모 클래스의 show () 메서드를 다시 작성했음을 잊었습니다!

가설 1 :
이제 클래스 B가 클래스 A의 메서드를 재정의했다는 것을 잊었습니다. 클래스 B에서 show ()를 사용 합니다. 원하는 결과는 summation 입니다.하지만 클래스 B는 클래스 A의 메서드를 재정 의하여 Calculated as a 차이 , 아마도 코드를보고 문제를 찾을 수있을 것입니다. 그런 다음 예를 들어 보겠습니다.

가설 2 : 이제 BCD의 세 가지 클래스가 있으며 모두 클래스 A에서 상속됩니다.

지금 내 요구 사항을 바꾸면 곱셈은 C, 나눗셈은 D를 원하는데 어떻게 써야하나요? 하나 하나 판단하고 커플 링이 너무 큽니다. 이제 A, B, C, D는 4입니다. 약간 혼란 스러워요, 이건 일방 통행입니다. 백팔 십이 있다면 직접적으로 멋지지 않습니다 o (╥﹏╥) o

Liskov 대체 원칙을 따르는 방법을 살펴 보겠습니다.

Richter의 대체 원칙의 작성을 따르십시오.

솔루션 :
클래스 A와 클래스 B가 더 많이 사용되는 상위 클래스 (BaseReplace)를 상속하도록합니다.

public class BaseReplace {
    
    
}

public class ReplaceA extends BaseReplace{
    
    
    public int show(int a, int b){
    
    
        return  a+b;
    }
}

public class ReplaceB extends BaseReplace{
    
    
    public int show(int a, int b){
    
    
        return  a-b;
    }
}

UML图(2.1):

분석:

  • 클래스 A와 클래스 B는 완전히 관련이 없으며 완전히 두 개의 별도 모듈입니다.
  • 전혀 커플 링 없음

클래스 B에서 클래스 A의 메서드를 사용하는 경우 :

조합 / 집계 방식 :

public class ReplaceB extends BaseReplace{
    
    
    ReplaceA replaceA = new ReplaceA();
    
    public int show(int a, int b){
    
    
        return  a-b;
    }

    public void useAshow(int a,int b ){
    
    
        replaceA.show(a,b);
    }
	public class ReplaceA extends BaseReplace{
    
    
	    public int show(int a, int b){
    
    
	        return  a+b;
	    }
	}
}
//使用代码
ReplaceB replaceB = new ReplaceB();
replaceB.useAshow(2,3)

클래스 B에서 조합을 사용하는 방법은 여전히 ​​클래스 A의 방법을 사용할 수 있음을 알 수 있습니다.

이것이 리히터 대체 원칙입니다.

의존성 반전 원리

리히터 대체 원칙

당신은 또한 좋아할 수 있습니다 :

디자인 패턴 / 디자인 원칙 카탈로그 페이지로 이동

독창성은 쉽지 않습니다. 좋아하는 걸 잊지 마세요 ~

추천

출처blog.csdn.net/weixin_44819566/article/details/112187562