OCP๋ฅผ ์๋ฐํ๋ Button ์ปดํฌ๋ํธ(์ํฐํจํด)
๊ด๋ จ ํค์๋
OCP ์๋ฐ
Button ์ปดํฌ๋ํธ
๋จผ์ , ์๋ก์ด ๋ฒํผ variant๋ฅผ ์ถ๊ฐํ ๋๋ง๋ค ๊ธฐ์กด ์ฝ๋๋ฅผ ์์ ํด์ผ ํ๋ ์ํฐํจํด์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ด ๋ฐฉ์์ OCP๋ฅผ ์๋ฐํ๋ฉฐ ์ ์ง๋ณด์์ฑ์ ๋จ์ด๋จ๋ฆฝ๋๋ค.
// ์ํฐํจํด: OCP๋ฅผ ์๋ฐํ๋ Button ์ปดํฌ๋ํธ function Button({ variant, children, ...props }) { let className = 'button'; if (variant === 'primary') { className += ' button--primary'; } else if (variant === 'secondary') { className += ' button--secondary'; } else if (variant === 'danger') { className += ' button--danger'; } return ( <button className={className} {...props}> {children} </button> ); } // ์ฌ์ฉ ์์ <Button variant="primary">Primary Button</Button> <Button variant="secondary">Secondary Button</Button> <Button variant="danger">Danger Button</Button>
๐ ๋ฌธ์ ์
- ์๋ก์ด variant (์: success)๋ฅผ ์ถ๊ฐํ๋ ค๋ฉด Button ์ปดํฌ๋ํธ ๋ด๋ถ์ if-else ๋ก์ง์ ์์ ํด์ผ ํจ.
- ์ด๋ OCP์ "๋ณ๊ฒฝ์ ๋ซํ ์์ด์ผ ํ๋ค"๋ฅผ ์๋ฐ.
- ์ฝ๋๊ฐ ๋ณต์กํด์ง๊ณ , ์๋ก์ด ์๊ตฌ์ฌํญ์ด ์๊ธธ ๋๋ง๋ค ๊ธฐ์กด ์ฝ๋ ์์ ์ด ๋ถ๊ฐํผํด์ง.
OCP๋ฅผ ์ค์ํ๋ ๋ฆฌํฉํฐ๋ง ButtonBase ์ปดํฌ๋ํธ
๊ด๋ จ ํค์๋
OCP ์ค์
ButtonBase ์ปดํฌ๋ํธ
OCP๋ฅผ ์ค์ํ๊ธฐ ์ํด ButtonBase๋ผ๋ ๊ธฐ๋ณธ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ณ , ์ด๋ฅผ ํ์ฅํ์ฌ ๋ค์ํ ๋ฒํผ ๋ณํ์ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก ๋ฆฌํฉํฐ๋งํฉ๋๋ค. ์ด๋ฅผ ํตํด ์๋ก์ด variant๋ฅผ ์ถ๊ฐํ ๋ ๊ธฐ์กด ์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ ๋ ํ์ฅ์ด ๊ฐ๋ฅํด์ง๋๋ค.
// ๊ธฐ๋ณธ ์ปดํฌ๋ํธ ButtonBase function ButtonBase({ className, children, ...props }) { return ( <button className={`button ${className}`} {...props}> {children} </button> ); } // ํ์ฅ๋ ๋ฒํผ ์ปดํฌ๋ํธ๋ค const PrimaryButton = ({ children, ...props }) => ( <ButtonBase className="button--primary" {...props}> {children} </ButtonBase> ); const SecondaryButton = ({ children, ...props }) => ( <ButtonBase className="button--secondary" {...props}> {children} </ButtonBase> ); const DangerButton = ({ children, ...props }) => ( <ButtonBase className="button--danger" {...props}> {children} </ButtonBase> ); // ์ฌ์ฉ ์์ <PrimaryButton>Primary Button</PrimaryButton> <SecondaryButton>Secondary Button</SecondaryButton> <DangerButton>Danger Button</DangerButton> // ์๋ก์ด SuccessButton ์ถ๊ฐ (๊ธฐ์กด ์ฝ๋ ์์ ์์ด ๊ฐ๋ฅ) const SuccessButton = ({ children, ...props }) => ( <ButtonBase className="button--success" {...props}> {children} </ButtonBase> );
๐ ์ฅ์
- ํ์ฅ์ฑ: ์๋ก์ด ๋ฒํผ ๋ณํ(์: SuccessButton)์ ์ถ๊ฐํ ๋ ButtonBase๋ ๊ธฐ์กด ์ปดํฌ๋ํธ๋ฅผ ์์ ํ์ง ์์๋ ๋จ.
- ์ ์ง๋ณด์์ฑ: ๊ฐ ๋ฒํผ ๋ณํ์ด ๋ ๋ฆฝ์ ์ด์ด์ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํ๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์.
- OCP ์ค์: ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ธฐ ์ํด ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ํ์ฅ ๊ฐ๋ฅ.
์ปดํฌ๋ํธ ํฉ์ฑ ํจํด Card ์ปดํฌ๋ํธ
๊ด๋ จ ํค์๋
์ปดํฌ๋ํธ ํฉ์ฑ ํจํด
OCP๋ฅผ ์ค์ํ๋ ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ปดํฌ๋ํธ ํฉ์ฑ ํจํด์ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. Card ์ปดํฌ๋ํธ๋ฅผ ์๋ก ๋ค์ด, ๋ค์ํ ์ฝํ
์ธ ๋ฅผ ์ ์ฐํ๊ฒ ํ์ฅํ ์ ์๋๋ก ์ค๊ณํด ๋ณด๊ฒ ์ต๋๋ค.
๐ ๊ธฐ๋ณธ Card ์ปดํฌ๋ํธ
function Card({ header, body, footer, ...props }) { return ( <div className="card" {...props}> {header && <div className="card-header">{header}</div>} {body && <div className="card-body">{body}</div>} {footer && <div className="card-footer">{footer}</div>} </div> ); } // ์ฌ์ฉ ์์ <Card header={<h2>Card Title</h2>} body={<p>This is the card content.</p>} footer={<PrimaryButton>Action</PrimaryButton>} />
๐ ์๋ก์ด ํ์ฅ: ์ด๋ฏธ์ง ํฌํจ Card
const ImageCard = ({ image, ...props }) => ( <Card header={image && <img src={image} alt="Card Image" className="card-image" />} {...props} /> ); // ์ฌ์ฉ ์์ <ImageCard image="https://example.com/image.jpg" body={<p>This is an image card.</p>} footer={<SecondaryButton>Learn More</SecondaryButton>} />
๐ ์ฅ์
- ์ ์ฐ์ฑ: Card ์ปดํฌ๋ํธ๋ ๋ค์ํ ์ฝํ ์ธ (ํค๋, ๋ฐ๋, ํธํฐ)๋ฅผ ์กฐํฉํ์ฌ ํ์ฅ ๊ฐ๋ฅ.
- ์ฌ์ฌ์ฉ์ฑ: ImageCard์ ๊ฐ์ ์๋ก์ด ์ปดํฌ๋ํธ๋ฅผ ๊ธฐ์กด Card๋ฅผ ํ์ฉํด ์ฝ๊ฒ ์์ฑ.
- OCP ์ค์: ์๋ก์ด Card ๋ณํ์ ์ถ๊ฐํ ๋ ๊ธฐ์กด Card ์ปดํฌ๋ํธ๋ฅผ ์์ ํ ํ์ ์์.
๊ณ ์ฐจ ์ปดํฌ๋ํธ(HOC)๋ฅผ ํตํ ํ์ฅ
๊ณ ์ฐจ ์ปดํฌ๋ํธ(HOC)๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด ์ปดํฌ๋ํธ์ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ฌ OCP๋ฅผ ์ค์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฒํผ์ ๋ก๋ฉ ์ํ๋ฅผ ์ถ๊ฐํ๋ HOC๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
// HOC: ๋ก๋ฉ ์ํ๋ฅผ ์ถ๊ฐ function withLoading(Component) { return function LoadingComponent({ isLoading, children, ...props }) { return ( <Component {...props} disabled={isLoading}> {isLoading ? 'Loading...' : children} </Component> ); }; } // ๋ก๋ฉ ๊ฐ๋ฅํ ๋ฒํผ ์์ฑ const LoadingPrimaryButton = withLoading(PrimaryButton); const LoadingSecondaryButton = withLoading(SecondaryButton); // ์ฌ์ฉ ์์ <LoadingPrimaryButton isLoading={true}>Click Me</LoadingPrimaryButton> <LoadingSecondaryButton isLoading={false}>Click Me</LoadingSecondaryButton>
๐ ์ฅ์
- ๊ธฐ๋ฅ ํ์ฅ: withLoading HOC๋ฅผ ํตํด ๊ธฐ์กด ๋ฒํผ ์ปดํฌ๋ํธ์ ๋ก๋ฉ ๊ธฐ๋ฅ์ ์ถ๊ฐ.
- OCP ์ค์: ๊ธฐ์กด PrimaryButton์ด๋ SecondaryButton ์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ ์๋ก์ด ๊ธฐ๋ฅ ์ถ๊ฐ ๊ฐ๋ฅ.
- ์ฌ์ฌ์ฉ์ฑ: HOC๋ ๋ค๋ฅธ ์ปดํฌ๋ํธ์๋ ์ ์ฉ ๊ฐ๋ฅ.