리스트에 보기를 포함하는 강력하고 경험적인 방법
본고는 단순 수요를 해결하는 가장 간단한 해결 방안에서 따라open/close principle하고 visitor pattern복잡한 수요를 해결하는 해결 방안으로 어떻게 발전하는지를 보여준다.
Consider this article to be programming language agnostic although I use React for the examples provided.
표준 방식
React에서 모든 항목의 목록을 보여주는 표준적인 방법은 매우 간단하고 효율적이다.다음 예는 React 공식 문서에서 발췌한 것이다.읽기 편하도록 항목 목록을 3줄 코드나 8줄 코드에 표시할 수 있음을 알 수 있습니다.
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
이것은 항목 목록을 보여주는 주요 방식이다. 만약 매우 간단한 목록이 있지만 그 중 어떠한 논리나 단순 논리가 없다면 이 방법을 따라야 한다.만약에 저희가 몇 가지 시각적 효과가 있다면요.
그러나 외부 변수에 따라 항목의 표시 방식을 수정해야 한다면 어떤 상황이 발생합니까?
논리를 조정하고 적당한 구성 요소를 만들어서 이런저런 방식으로 데이터를 나타낼 수 있습니다.예를 들어 목록에 앞의 숫자를 표시하지 않고 테이블에 표시해야 한다면 코드를 변경해야 한다.이 요구 사항을 제외하고 사용자가 항목을 보는 방식을 설정할 수 있도록 하는 또 다른 요구가 있습니다.
다음 코드는 이전 코드의 개선 사항으로 요구 사항에 적합한 구성 요소를 설정합니다.
const numbers = [1, 2, 3, 4, 5];
// View components
function ListView({ items }) {
return <ul>
{items && items.map(i => <li key={i}>{i}</li>)}
</ul>;
}
function TableView({ items }) {
return <table>
<tbody>
{items && items.map(i => <tr key={i}><td>{i}</td></tr>)}
</tbody>
</table>;
}
// View selector
function ViewSelector({ options, onSelect }) {
return <div>
{options && options.map(o =>
<div key={o}><a href="#" onClick={() => onSelect(o)}>{o}</a></div>)
}
</div>;
}
// Application component
function App() {
const options = ['list', 'table'];
const [view, setView] = React.useState(options[0]);
const onSelectHandler = (option) => {
setView(option);
};
return <div>
<ViewSelector options={options} onSelect={onSelectHandler} />
{view === 'list' && <ListView items={numbers} />}
{view === 'table' && <TableView items={numbers} />}
</div>;
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
이 코드는 잘 작동하고 시각적으로 매우 간단하여 읽기 쉽다.팀의 새로운 개발자로서, 당신은 이전의 코드를 신속하게 이해하고 모든 구성 요소의 직책을 확정할 수 있습니다.따라서 코드를 개선하거나 발생할 수 있는 모든 문제를 해결할 수 있습니다.진화의 한 예로, 내연된 숫자를 보기 위한 새로운 요구 사항을 추가할 수 있으며, 쉽게 새
View
구성 요소를 만들고 선택할 옵션에 추가할 수 있습니다.새 코드는 다음과 유사할 수 있습니다.const numbers = [1, 2, 3, 4, 5];
// Notice the new view component
function InlineView({ items }) {
return items && items.map(i => <span>{i}</span>);
}
function ListView({ items }) {
return <ul>
{items && items.map(i => <li key={i}>{i}</li>)}
</ul>;
}
function TableView({ items }) {
return <table>
<tbody>
{items && items.map(i => <tr key={i}><td>{i}</td></tr>)}
</tbody>
</table>;
}
function ViewSelector({ options, onSelect }) {
return <div>
{options && options.map(o =>
<div key={o}><a href="#" onClick={() => onSelect(o)}>{o}</a></div>)
}
</div>;
}
function App() {
// Notice the new option
const options = ['list', 'table', 'inline'];
const [view, setView] = React.useState(options[0]);
const onSelectHandler = (option) => {
setView(option);
};
// Notice how the new component has been added depending on `view` value
return <div>
<ViewSelector options={options} onSelect={onSelectHandler} />
{view === 'list' && <ListView items={numbers} />}
{view === 'table' && <TableView items={numbers} />}
{view === 'inline' && <InlineView items={numbers} />}
</div>;
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
우리는 깨고 있다open/close principle이제 응용 프로그램에서 프로젝트의 디스플레이 방식에 더 많은 기능을 제공하는 데 수요가 집중된다고 상상해 보세요.이외에 만약에 우리가 코드에 대해 더욱 높은 품질을 적용하고 코드 심사 과정에서 더욱 높은 관심을 얻으려면 이전의 코드가 open/close principle의 표준을 깨고 있음을 이해해야 한다.
The open/close principle says: "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"
새 뷰를 생성하거나 기존 뷰를 대체할 때마다
App
컴포넌트를 수정해야 합니다.테스트 - 단원, 집적 또는 그 어떠한 유형도 우리가 그것들을 인코딩해야 하지 않도록 수정해야 한다.이 모든 요소들은 우리의 코드가 어떻게 작동하는지에 대한 불확실성을 증가시켰다. 이것은 우리가 피해야 할 것이다.visitor pattern 유용한 기능
코드의 수정을 피하기 위해
App
구성 요소 기능을 닫는 것이 목표입니다.이 점을 실현하기 위해서, 우리는 다음 몇 단락에서 볼 수 있는 변경 사항을 적용해야 한다.우선, 우리는 모든 사용 가능한 보기 형식과 이 옵션의 모든 관련
View
구성 요소를 포함하는 새로운 서비스를 만들어야 한다.function ViewersService() {
// service variable
const views = {};
return {
// provide a copy of the views variable
get() {
return Object.assign({}, views);
},
// associate a view component to a type
register(type, viewComponent) {
if(undefined === views[type]) {
views[type] = [];
}
views[type].push(viewComponent);
}
};
}
// service instantiation
const viewers = new ViewersService();
// views registration
viewers.register('list', ListView);
viewers.register('table', TableView);
viewers.register('inline', InlineView);
그 다음에 우리는 파라미터를 통해 App
구성 요소에 이 실례를 제공해야 한다.그런 다음 이 옵션을 사용하여 사용 가능한 옵션을 가져오고 사용자 선택에 따라 적절한 뷰 어셈블리를 렌더링합니다.다음 코드에서, 우리는 보기 구성 요소에 접근할 필요가 있는지 확인하기 위해 검증기로 선택된 옵션을 사용합니다.우리는 이 값이 바로 검사할 값이라고 가정한다.
// Notice viewers parameter
function App({ viewers }) {
// Notice here that we get the views registrations from the instance
const views = viewers.get();
// Notice how options are obtained from the views keys
const options = Object.keys(views);
const [viewOption, setViewOption] = React.useState(options[0]);
const onSelectHandler = (option) => {
setViewOption(option);
};
// _views[viewOption]_ is the formula that determines the components to be visited
const viewsToVisit = views[viewOption];
// Notice how we go through all views registered for the option selected and render altogether.
const allViews = viewsToVisit.map(View => <View items={numbers} />);
return <div>
<ViewSelector options={options} onSelect={onSelectHandler} />
{allViews}
</div>;
}
언뜻 보기에, 이 코드는 초보자들에게 약간 도전적일 수 있다. 왜냐하면 그것은 구성 요소와 대상에 관련되기 때문이다.나는 이 예가 상대적으로 작다는 것을 알고 있지만, 이 해결 방안의 응용 범위가 갈수록 넓어지는 것을 감안하면.새로운 수요에 대해 개발자는 반드시 새로운
View
구성 요소를 만들고 이를 서비스에 등록해야 한다.예를 들어, 첫 번째 항목만 렌더링해야 하는 경우 다음 코드를 추가해야 합니다.function FirstItemView({ items }) {
return items && <span>{items[0]}</span>;
}
// this line to be added in the proper place
viewers.register('first', FirstItemView);
마무리본고는 광범위하게 사용되는visitor pattern 코드를 응용하여 코드와 유지보수성, 읽기 가능성을 개선하는 방법을 보여 주려고 한다.
나는 이것이 처음에는 매우 도전적이라고 생각하지만 복잡도가 증가하기 때문에 코드 줄이 증가할 때 유용할 것이라고 생각한다.
당신은 본문 중의 연습에 대해 어떤 견해를 가지고 있습니까?
이 문장이 너에게 유용하거나 즐겁게 읽혔으면 좋겠다.
Reference
이 문제에 관하여(리스트에 보기를 포함하는 강력하고 경험적인 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/codbugs/a-powerful-and-proven-way-to-include-views-on-list-rendering-1o43텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)