왜 반응 구성 중 개방/폐쇄 원칙을 응용합니까?

너는 어지러운 코드를 보았니? 단지 그것을 태우고 싶을 뿐이야?나 있는 거 알아.😊. 이것이 바로 내가 소프트웨어 구조를 배우기 시작한 원인이다.나는 개발을 재미있게 하기 위해 깨끗하고 신축 가능하며 신뢰할 수 있는 코드 라이브러리를 개발하는 것을 고려하기 시작했다.새로운 기능을 실현하는 것은 긴장되는 것이 아니라 흥분되는 것이어야 한다.
본고에서 우리는 조합 모델을 어떻게 활용하고 개방/폐쇄 원칙(실체원칙에서)을 응용하여 우리의 응용 프로그램을 설계하여 사용하기 쉽고 확장 가능하며 코드를 작성하기 쉽도록 하는지를 연구하고자 한다.

please note: this is the second part of my React design pattern series with SOLID principles. You can find the first part



개방/폐쇄의 원칙은 무엇입니까?
대상을 대상으로 프로그래밍하는 과정에서 개방/폐쇄 원칙은'소프트웨어 실체(클래스, 모듈, 함수 등)는 확장을 위해 개방해야 하지만 수정을 위해 폐쇄해야 한다'고 규정한다.즉, 이러한 실체는 원본 코드를 수정하지 않은 상태에서 그 행위를 확장할 수 있다.

우리는 어떻게 React에서 OCP를 응용합니까?
자바나 파이톤 등 OOP 언어에서 이 개념은 계승을 통해 응용된다.이렇게 하면 코드를 건조하게 유지하고 결합을 줄일 수 있다.Angular 2+에 익숙하다면 Angular 2+에서 상속할 수 있음을 알 수 있습니다.그러나 자바스크립트는 순수한 대상 언어가 아니다. 자바,python, C# 등 대상 대상 언어를 지원하지 않는다.따라서 Angular 2+에서 인터페이스를 실현하거나 클래스를 확장할 때 프레임워크 자체가 백엔드에서 처리되어 OOP 코드를 작성하는 착각을 일으킬 수 있습니다.사실 우리는 그런 사치가 없다.React 팀은 상속이 아니라 기능 조합을 장려한다.고급 함수는 JavaScript에서 코드를 재사용하고 코드를 건조하게 유지하는 방법입니다.
몇 가지 코드를 살펴보고, 우리가 어떻게 구성 요소를 조합하는지, 그리고 어떻게 개방/폐쇄 원칙에 따라 깨끗하고 신뢰할 수 있는 코드를 작성하는지 봅시다.
다음은 AppOrderReport 구성 요소입니다.우리는 고객 대상을 도구로 전달하고 있다.
function App() {
  const customer = {
    name: 'Company A',
    address: '720 Kennedy Rd',
    total: 1000
  }
  return (
    <div className="App">
      <OrderReport customer={customer}/>
    </div>
  );
}
이제 OrderReport 구성 요소를 살펴보겠습니다.
function OrderReport(props) {
  return (
    <div>
      <b>{props.customer.name}</b>
      <hr />
      <span>{props.customer.address}</span>
      <br />
      <span>Orders: {props.customer.total}</span>
      {props.children}
    </div>
  );
}
이 구성 요소는 secrect;이 조금 있습니다.그것은 변화를 좋아하지 않는다.예를 들어, 우리가 새로운customer 대상이 있다면, 그것은 첫 번째 대상보다 여러 필드가 있다.우리는 도구로 전달되는 새로운 고객 대상에 따라 추가 정보를 제공하기를 희망한다.다음 코드를 보여 주세요.
const customerB = {
    name: "Company B",
    address: "410 Ramsy St",
    total: 1000,
    isEligible: true,
    isFastTracked: false
};
const customerC = {
    name: "Company C",
    address: "123 Abram Ave",
    total: 1010,
    specialDelivery: true
};
우리는 두 개의 새로운 고객 대상을 추가했는데, 모두 두 개의 새로운 추가 키가 있다.가령 이러한 키를 바탕으로 한다면 우리는 구성 요소에 추가적인 html 요소를 보여야 한다.따라서 App 구성 요소에서 다음과 같은 내용을 되돌려보냅니다.
return (
    <div className="App">
      <OrderReport customer={customer} />
      <OrderReport customer={customerB} />
      <OrderReport customer={customerC} />
    </div>
);
우리는 전달된 도구를 바탕으로 추가 기능을 보여주기 위해 OrderReport 구성 요소를 수정했다.그래서 저희 구성 요소가 지금 이렇게 보여요.
function OrderReport(props) {
  const [fastTracker, setFastTracker] = React.useState(props.isFastTracked);
  return (
    <div>
      <b>{props.customer.name}</b>
      <hr />
      <span>{props.customer.address}</span>
      <br />
      <span>Orders: {props.customer.total}</span>
      {props.customer.isEligible ? (
        <React.Fragment>
          <br />
          <button
            onClick={() => {
              setFastTracker(!fastTracker);
            }}
          />
        </React.Fragment>
      ) : null}
      {props.customer.specialDelivery ? (
        <div>Other Logic</div>
      ) : (
        <div>Some option for specialDelivery logic...</div>
      )}
      {props.children}
    </div>
  );
}
보시다시피 그것은 이미 매우 시끄럽게 변하기 시작했다.이것도 단일 책임 원칙에 위배된다.이 구성 요소는 현재 너무 많은 임무를 수행하는 것을 책임진다.개폐의 원리에 따라 구성 요소는 개방적이어야 하며 확장할 수 있지만 수정하기 위해 닫아야 한다. 그러나 여기서 우리는 한 번에 너무 많은 논리를 수정했다.우리는 또한 코드에 불필요한 복잡성을 도입했다.이 문제를 해결하기 위해서, 이 논리를 분해하기 위해 더 높은 구성 요소를 만듭니다.
const withFastTrackedOrder = BaseUserComponent => props => {
  const [fastTracker, setFastTracker] = React.useState(props.isFastTracked);
  const baseElments = (
    <BaseUserComponent customer={props.customer}>
      <br />
      <button
        onClick={() => {
          setFastTracker(!fastTracker);
        }}
      >
        Toggle Tracking
      </button>
      {fastTracker ? (
        <div>Fast Tracked Enabled</div>
      ) : (
        <div>Not Fast Tracked</div>
      )}
    </BaseUserComponent>
  );
  return baseElments;
};
위에서 말한 바와 같이 우리는 withFastTrackedOrder HOC를 만들었는데 이것은 OrderReport 구성 요소를 사용하고 추가 논리와 html을 추가했다.
현재, 우리의 모든 빠른 주문 논리는 withFastTrackedOrder 구성 요소에 봉인되어 있다.여기는 withFastTrackedOrder입니다. 추가 기능이 추가되었고 OrderReport에서 우리가 작성한 논리를 확장했습니다.OrderReport을 다음과 같은 최소 형식으로 복원하겠습니다.
function OrderReport(props) {
  return (
    <div>
      <b>{props.customer.name}</b>
      <hr />
      <span>{props.customer.address}</span>
      <br />
      <span>Orders: {props.customer.total}</span>
      {props.children}
    </div>
  );
}
현재 App에서 다음과 같이 렌더링하고 있습니다.
function App() {
  const FastOrder = withFastTrackedOrder(OrderReport);
  return (
    <div className="App">
      <OrderReport customer={customer} />
      <FastOrder customer={customerB} />
    </div>
  );
}
됐다.우리는 논리를 두 개의 유지보수적이고 깨끗한 구성 요소로 분해했다.OrderReport은 현재 확장을 위해 열려 있지만, 수정을 위해 닫혀 있습니다.
현재 우리는 우리의 업무 규칙이 특수 주문이 있는 고객에게 추가 html을 제공하도록 요구한다고 가정합시다.OrderReport을 더 연장할 수 있을까요?그럼요.OrderReport을 구성하는 또 다른 HOC를 만듭니다.
const withSpecialOrder = BaseUserComponent => props => {
  return (
      <BaseUserComponent customer={props.customer}>
        <div>I am very special</div>
        {props.children}
      </BaseUserComponent>
  );
};
withSpecialOrder 구성 요소는 OrderReport를 사용하고 에 html을 추가합니다.
현재 App에서는 다음과 같은 작업만 수행할 수 있습니다.
function App() {
  const FastOrder = withFastTrackedOrder(OrderReport);
  const SpecialOrder = withSpecialOrder(OrderReport);
  return (
    <div className="App">
      <OrderReport customer={customer} />
      <FastOrder customer={customerB} />
      <SpecialOrder customer={customerC} />
    </div>
  );
}
너무 예쁘지 않아요?우리는 우리의 조립품을 작은 덩어리로 나누었다.우리는 논리로 그것들을 분리했다. 우리는 결코 같은 논리를 다시 쓰지 않았다.우리의 모든 구성 요소는 확장할 수 있다.우리는 코드를 다시 사용하고 건조함을 유지할 수 있다.
우리 이 생각을 더욱 진일보합시다.현재 우리의 업무가 일부 특수 주문서의 당일 배달 서비스를 허용한다고 가정하자.우리는 SpecialOrderComponent을 봉인하고 이 추가 논리를 추가할 수 있는 더 높은 구성 요소를 만들 수 있습니다.구성 요소가 항상 열려 있고, 닫혀서 수정된다는 것을 기억하십시오.따라서 새 HOC가 생성됨에 따라 기존 구성 요소의 기능을 확장하고 있습니다.우리 이거 쓰자.
const withSameDayDeliver = SpecialOrderComponent => props => {
  return (
    <SpecialOrderComponent customer={props.customer}>
      <div>I am also same day delivery</div>
      {props.children}
    </SpecialOrderComponent>
  );
};
이제 이 새로운 HOC를 App에 적용해 보십시오.
function App() {
  const FastOrder = withFastTrackedOrder(OrderReport);
  const SpecialOrder = withSpecialOrder(OrderReport);
  const SameDayDelivery = withSameDayDeliver(withSpecialOrder(OrderReport));
  return (
    <div className="App">
      <OrderReport customer={customer} />
      <FastOrder customer={customerB} />
      <SpecialOrder customer={customerC} />
      <SameDayDelivery customer={customerC} />
    </div>
  );
}
지금 보시다시피 HOC를 사용하는 모드를 만들었습니다. 항상 확장할 수 있지만 복잡한 수정은 어렵습니다.우리는 가능한 한 많은 HOC를 추가할 수 있으며, 코드의 복잡성이 증가함에 따라, 우리는 심지어 이런 HOC를 혼합하고 일치시킬 수 있다.이것은 우리의 코드를 간단하고 사용하기 쉽게 한다.그것은 우리의 논리를 봉인해서, 이렇게 하면 전체 시스템에 영향을 주지 않을 것이다.장기적으로 보면 코드의 완전성을 유지할 수 있다.
이 글의 내용은 현재 진행 중이며, 나는 업계의 최상의 실천과 나의 개인적인 경험에 따라 끊임없이 그것들을 갱신할 것이다.당신의 피드백은 매우 중요합니다. 할 말이 있으면 댓글을 남겨 주십시오.나의 새로운 문장을 주목해 주세요.
너는 이 시리즈의 이전 문장의 링크를 찾을 수 있다.
만약 당신이 이 문장을 좋아한다면, 그것을 좋아해서, 내가 동력을 유지할 수 있도록 하세요:)
다음으로, 우리는 liskov의 교체가 어떻게 React 구성 요소 체계 구조에 응용되는지 토론할 것이다.기대하세요.

좋은 웹페이지 즐겨찾기