응용 프로그램 o 개방형/폐쇄형 원칙 com Typescript e Java

王林
풀어 주다: 2024-08-29 14:38:05
원래의
370명이 탐색했습니다.

Aplicando o Open/Closed Principle com Typescript e Java

개념

추출

객체지향 개념에서의 추상화는 클래스가 반드시 갖춰야 할 필수적인 측면만을 정의하는 관행입니다. 클래스는 본질적으로 불완전하고 부정확해야 하위 클래스를 통해 특정성을 모델링할 수 있습니다. 그리하여 딸 클래스, 어머니 클래스, 그리고 상속이라는 개념이 생겨난다.

유산

상속은 상위 클래스의 동작을 상속하기 위해 한 클래스가 다른 클래스를 확장하는 클래스 간의 관계를 표현하는 것입니다.

단단한

SOLID는 Robert C. Martin(밥 삼촌)이 제안한 객체지향 프로그래밍의 5가지 기본 원칙을 나타내는 약어입니다. 여기에서 그의 기사에 대한 자세한 내용을 읽어보실 수 있습니다.
이러한 원칙은 코드의 구조와 유지 관리를 개선하여 코드를 더욱 유연하고 확장 가능하며 이해하기 쉽게 만드는 것을 목표로 합니다. 이러한 원칙은 프로그래머가 보다 체계적인 코드를 작성하고, 책임을 나누고, 종속성을 줄이고, 리팩토링 프로세스를 단순화하고, 코드 재사용을 촉진하는 데 도움이 됩니다.

개방/폐쇄 원칙

약어의 'O'는 '개방/폐쇄 원칙'을 의미합니다. Bob 삼촌이 이 원칙을 정의하기 위해 사용한 문구는 다음과 같습니다.

"수업은 연장을 위해 열려 있어야 하고 수정을 위해 닫혀야 합니다."

이 원칙에 따라 클래스나 객체의 동작을 확장해야 한다고 느낄 때마다 클래스 자체를 변경할 필요가 없도록 일반적인 방식으로 클래스나 모듈을 작성하는 애플리케이션을 개발해야 합니다. . 여기서의 연장은 절차의 추가 또는 변경으로 해석될 수 있습니다.

목표는 기존 코드를 변경할 필요 없이 새로운 기능을 추가할 수 있도록 하는 것입니다. 이렇게 하면 버그가 발생할 위험이 최소화되고 코드 유지 관리가 더욱 쉬워집니다.

실제 적용

제품 할인을 계산하는 할인 계산기 클래스가 있다고 가정해 보세요. 처음에는 전자제품과 의류라는 두 가지 제품 카테고리가 있습니다. OCP(개방/폐쇄 원칙)를 적용하지 않고 시작해 보겠습니다.

자바

class Product {
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

class DiscountCalculator {
    public double calculateDiscount(Product product) {
        if (product.getName().equals("Electronics")) {
            return product.getPrice() * 0.9; // 10% de desconto
        } else if (product.getName().equals("Clothing")) {
            return product.getPrice() * 0.8; // 20% de desconto
        }
        return product.getPrice();
    }
}

public class Main {
    public static void main(String[] args) {
        Product electronics = new Product("Electronics", 100);
        Product clothing = new Product("Clothing", 50);

        DiscountCalculator calculator = new DiscountCalculator();

        System.out.println(calculator.calculateDiscount(electronics)); // 90
        System.out.println(calculator.calculateDiscount(clothing)); // 40
    }
}
로그인 후 복사

타이프스크립트

class Product {
    private _name: string;
    private _price: number;

    constructor(name: string, price: number) {
        this._name = name;
        this._price = price;
    }

    public get name() { return this.name };

    public set name(value: string) { this.name = value };

    public get price() { return this.price };

    public set price(value: number) { this.price = value };
}

class DiscountCalculator {
    public calculateDiscount(product: Product): number {
        if (product.name === 'Electronics') {
            return product.price * 0.9; // 10% de desconto
        } else if (product.name === 'Clothing') {
            return product.price * 0.8; // 20% de desconto
        }
        return product.price;
    }
}

const electronics = new Product('Electronics', 100);
const clothing = new Product('Clothing', 50);

const calculator = new DiscountCalculator();

console.log(calculator.calculateDiscount(electronics)); // 90
console.log(calculator.calculateDiscount(clothing)); // 40
로그인 후 복사

OCP 미적용시 발생하는 문제

캡슐화 위반: 새 제품 유형에 다른 할인이 필요할 때마다 if의 새 조건을 포함하여 계산 할인 메서드를 수정해야 합니다.

유지 관리의 어려움: if/else 또는 스위치가 너무 많아 메서드가 커지면 유지 관리 및 테스트가 어려워집니다.

버그 발생 위험: 메소드를 변경하면 해당 메소드에 의존하는 코드의 다른 부분에 버그가 발생할 수 있습니다.

어떻게 고치나요?

이제 기존 코드를 수정하지 않고도 새로운 유형의 할인을 추가할 수 있도록 코드를 리팩터링하여 개방/폐쇄 원칙을 적용해 보겠습니다.

자바

class Product {
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

interface DiscountStrategy {
    double calculate(Product product);
}

class ElectronicsDiscount implements DiscountStrategy {
    @Override
    public double calculate(Product product) {
        return product.getPrice() * 0.9; // 10% de desconto
    }
}

class ClothingDiscount implements DiscountStrategy {
    @Override
    public double calculate(Product product) {
        return product.getPrice() * 0.8; // 20% de desconto
    }
}

class NoDiscount implements DiscountStrategy {
    @Override
    public double calculate(Product product) {
        return product.getPrice();
    }
}

class DiscountCalculator {
    private DiscountStrategy discountStrategy;

    public DiscountCalculator(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }

    public double calculateDiscount(Product product) {
        return discountStrategy.calculate(product);
    }
}

public class Main {
    public static void main(String[] args) {
        Product electronics = new Product("Electronics", 100);
        Product clothing = new Product("Clothing", 50);
        Product books = new Product("Books", 30);

        DiscountCalculator electronicsDiscount = new DiscountCalculator(new ElectronicsDiscount());
        DiscountCalculator clothingDiscount = new DiscountCalculator(new ClothingDiscount());
        DiscountCalculator booksDiscount = new DiscountCalculator(new NoDiscount());

        System.out.println(electronicsDiscount.calculateDiscount(electronics)); // 90
        System.out.println(clothingDiscount.calculateDiscount(clothing)); // 40
        System.out.println(booksDiscount.calculateDiscount(books)); // 30
    }
}
로그인 후 복사

타이프스크립트

class Product {
    private _name: string;
    private _price: number;

    constructor(name: string, price: number) {
        this._name = name;
        this._price = price;
    }

    public get name() { return this.name };

    public set name(value: string) { this.name = value };

    public get price() { return this.price };

    public set price(value: number) { this.price = value };
}

interface DiscountStrategy {
    calculate(product: Product): number;
}

class ElectronicsDiscount implements DiscountStrategy {
    calculate(product: Product): number {
        return product.price * 0.9; // 10% de desconto
    }
}

class ClothingDiscount implements DiscountStrategy {
    calculate(product: Product): number {
        return product.price * 0.8; // 20% de desconto
    }
}

class NoDiscount implements DiscountStrategy {
    calculate(product: Product): number {
        return product.price;
    }
}

class DiscountCalculator {
    private discountStrategy: DiscountStrategy;

    constructor(discountStrategy: DiscountStrategy) {
        this.discountStrategy = discountStrategy;
    }

    public calculateDiscount(product: Product): number {
        return this.discountStrategy.calculate(product);
    }
}

const electronics = new Product('Electronics', 100);
const clothing = new Product('Clothing', 50);
const books = new Product('Books', 30);

const electronicsDiscount = new DiscountCalculator(new ElectronicsDiscount());
const clothingDiscount = new DiscountCalculator(new ClothingDiscount());
const booksDiscount = new DiscountCalculator(new NoDiscount());

console.log(electronicsDiscount.calculateDiscount(electronics)); // 90
console.log(clothingDiscount.calculateDiscount(clothing)); // 40
console.log(booksDiscount.calculateDiscount(books)); // 30
로그인 후 복사

결론

기존 코드 기반을 크게 수정하지 않고도 새로운 기능이나 동작을 추가해야 하는 경우 개방/폐쇄 원칙을 적용하는 것이 필수적입니다. 실제로 시간이 지남에 따라 코드베이스를 100% 변경하는 것을 방지하는 것은 사실상 불가능하지만 새로운 기능을 삽입하기 위해 변경되는 총 코드량을 완화하는 것은 가능하다는 것을 알 수 있습니다.

이 원칙은 새로운 요구 사항을 충족하든 오류를 수정하든 관계없이 코드가 변경 사항에 더 잘 적응할 수 있도록 해줍니다.

위 내용은 응용 프로그램 o 개방형/폐쇄형 원칙 com Typescript e Java의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!