Композиция против наследования в React | Сравнение и контраст
Скачать этот великолепный Приложение React Native Store Locator шаблон для создания собственного приложения для поиска магазинов всего за несколько минут. Используя этот полностью закодированный стартовый набор, написанный на React Native, вы экономите недели на проектировании и разработке и можете сосредоточиться на других важных задачах, таких как привлечение клиентов и маркетинг.
Если у вас есть какие-либо знания об объектно-ориентированном программировании, то вы, возможно, слышали эти два слова — наследование и композиция. Наследование и композиция — две важные части объектно-ориентированного программирования, когда речь идет о возможности повторного использования кода. Обе эти концепции также применимы к компонентам React. Следовательно, концепция наследования и композиции очень важна.
Строительные компоненты в Реагировать это весело, но иногда это может быть утомительно. Предположим, одному компоненту нужна кнопка синего цвета, а другому нужна кнопка с черной рамкой. Точно так же третьему компоненту нужна кнопка желтого цвета с синей рамкой. Теперь писать код для кнопки каждый раз с разным стилем, конечно, утомительно и немного разочаровывает. Должны быть способы повторного использования кода и улучшения компонентов.
Да, и наследование, и композиция могут использоваться для повторного использования кода и улучшения компонентов, но, по мнению основной команды React, мы должны предпочесть композицию наследованию.
Как упоминалось ранее, и наследование, и композиция являются частями объектно-ориентированного программирования. Обе эти концепции широко используются в программировании для улучшения возможности повторного использования и улучшения кода. В этой статье мы обсудим, что лучше работает в React, Inheritance или Composition.
Наследование — это концепция объектно-ориентированного программирования, при которой один класс наследует свойства и методы другого класса. Это полезно для повторного использования кода. Давайте посмотрим, как это реализовано в React.
Реализация
import React from 'react';
import './App.css';
class Vehicle extends React.Component{
constructor(props){
super(props)
this.className = 'Vehicle'
}
render(args){
return(
<h1 className={this.className}>{this.props.children}{args}</h1>
)
}
}
class Car extends Vehicle{
constructor(props){
super(props)
}
}
class Bike extends Vehicle{
constructor(props){
super(props)
}
}
class Main extends React.Component{
render(){
return(
<React.Fragment>
<Vehicle>Vehicle</Vehicle>
<Car>Car</Car>
<Bike>Bike</Bike>
</React.Fragment>
)
}
}
export default Main;
В основном классе используются три компонента: Автомобиль, Автомобиль и Мотоцикл. Транспортное средство является базовым классом, в то время как классы Car и Bike являются производными от него с помощью ключевого слова extends. Классы Car и bikes наследуют свойства класса Vehicle. Метод рендеринга в классе Vehicle наследуется обоими производными классами. Кроме того, свойство className также наследуется классами Car и Bike.
Добавление еще одного компонента
Добавим еще один компонент. Этот компонент будет стремиться напечатать название транспортного средства, как мы делали ранее, используя this.props.children. Но на этот раз он также напечатает вместе с ним дополнительный текст, который будет передан из этого самого компонента. Следующий класс также является производным классом класса Vehicle с дополнительной обработкой.
class Truck extends Vehicle {
constructor(props){
super(props)
}
render(){
return <div>
{super.render()}<span> is a heavy vehicle</span>
</div>
}
}
В этом компоненте мы использовали метод рендеринга. Помните, что этот класс наследует метод рендеринга класса Vehicle. Итак, чтобы добавить дополнительный текст, мы должны использовать метод super для вызова метода рендеринга базового класса. Наблюдаем за выходом.
Это не то, что мы ожидали. «Грузовик — это тяжелое транспортное средство», это должно быть в одной строке с одним CSS. Это один из недостатков использования наследования в React. Однако мы можем добиться желаемых результатов, используя аргументы. Давайте посмотрим, как это сделать.
class Vehicle extends React.Component{
constructor(props){
super(props)
this.className = 'Vehicle'
}
render(args){
return(
<h1 className={this.className}>{this.props.children} {args}</h1>
)
}
}
class Truck extends Vehicle{
constructor(props){
super(props)
}
render(){
return <div>{super.render(<span> is a heavy vehicle</span>)}</div>
}
}
Обратите внимание на изменения, внесенные в классы Vehicle и Truck.
В классе Truck мы передали тег span с текстом методу рендеринга базового класса, т.е. Vehicle.
В классе Vehicle мы использовали аргумент и вывели его с названием автомобиля. Посмотрим, получим ли мы желаемый результат или нет.
Да, мы получили желаемый результат. Но так ли это? Нет, это не так. Мы передали аргумент от класса Truck, а как насчет других классов? Мы не должны использовать этот метод, потому что класс Vehicle должен учитывать варианты использования другого класса. Помните, чем больше вариантов использования, тем больше аргументов. Здесь это выглядит нормально, но когда будет несколько подобных случаев, код станет сложным, и его будет очень сложно поддерживать. Мы используем наследование для повторного использования кода, чтобы код в первую очередь выглядел менее сложным? Не так ли?
Есть лучший способ кодировать повторное использование и улучшать компоненты. В наследовании использовался метод отношения «является». Производные компоненты должны были наследовать свойства базового компонента, и это было довольно сложно при изменении поведения любого компонента. Композиция стремится к чему-то лучшему. Вместо того, чтобы наследовать свойства других компонентов, почему бы не наследовать только поведение и добавить поведение к желаемому компоненту?
Композиция не наследует свойства, только поведение. Это плюс, но почему? При наследовании было сложно добавить новое поведение, потому что производный компонент наследовал все свойства родительского класса, и добавить новое поведение было довольно сложно. Нам пришлось добавить больше вариантов использования. Но в композиции мы наследуем только поведение, а добавление нового поведения довольно просто и легко. Давайте разберемся с этим на примере, который является модифицированной версией предыдущего примера.
Реализация
import React from 'react';
import './App.css';
class Vehicle extends React.Component{
render(){
return(<h1 className=”Vehicle”>{this.props.children}</h1>)
}
}
class Car extends React.Component{
render(){
return(<Vehicle>{this.props.children}</Vehicle>)
}
}
class Bike extends React.Component{
render(){
return(<Vehicle>{this.props.children}</Vehicle>)
}
}
class Main extends React.Component{
render(){
return(<React.Fragment>
<Vehicle>Vehicle</Vehicle>
<Car>Car</Car>
<Bike>Bike</Bike>
</React.Fragment>
)
}
}
export default Main;
В приведенном выше коде мы использовали Composition. Обратите внимание: ни один из кодов не наследуется от какого-либо другого компонента. Но мы видим, что классы Car и Bike наследуют поведение класса Vehicle. Мы только что использовали компонент Vehicle внутри обоих классов. Посмотрим на результат.
Очевидно, что классы Car и Bike наследуют поведение класса Vehicle. Теперь давайте добавим еще один компонент, который унаследует поведение класса Vehicle, но наряду с существующим поведением мы добавим и новое поведение.
class Truck extends React.Component{
render(){
return(
<Vehicle>{this.props.children}<span> is a heavy vehicle. </span></Vehicle>
)
}
}
Мы снова добавили компонент Truck, но на этот раз мы использовали Composition. Мы также добавили к нему новое поведение. Посмотрите, как это легко. Нам не нужно ничего делать с классом Vehicle. Таким образом, не затрагивая любой другой компонент.
<Vehicle>{this.props.children}<span> is a heavy vehicle. </span></Vehicle>
Сравните это с наследственным. Наверняка композиция легкая и простая. Мы можем добавить поведение по нашему выбору к любому компоненту, не вызывая никаких проблем.
Это завершает наше понимание наследования и композиции в React.
Вот почему композиция предпочтительнее наследования. Использование композиции довольно легко и просто, в то время как наследование становится намного сложнее с добавлением большего количества кода. Добавление поведения настолько просто в композиции, что нам достаточно изменить код только в компоненте. При наследовании возникает сложность добавления нового поведения. Добавление большего количества поведения приводит к большему количеству вариантов использования, что, в свою очередь, приводит к большему количеству аргументов. Код становится более сложным и неуправляемым. Следовательно, логично предпочесть композицию наследованию в React. Таким образом, эта статья распространяет концепцию наследования и композиции, которая важна для любого программиста.