首页  >  文章  >  web前端  >  Typescript 和 Java 中的开闭原则应用

Typescript 和 Java 中的开闭原则应用

王林
王林原创
2024-08-29 14:38:05370浏览

Aplicando o Open/Closed Principle com Typescript e Java

概念

抽象

面向对象概念中的抽象是一种仅定义类必须具有的基本方面的实践。从本质上讲,类必须是不完整且不精确的,以便我们可以通过子类对特殊性进行建模。由此产生了子类、母类和继承的概念。

遗产

继承是类之间关系的表示,其中一个类扩展另一个类以继承父类的行为。

坚硬的

SOLID 是一个缩写词,代表面向对象编程的五个基本原则,由 Robert C. Martin(鲍勃大叔)提出。在这里您可以阅读有关他的文章的更多信息。
这些原则旨在改进代码的结构和维护,使其更加灵活、可扩展且更易于理解。这些原则可以帮助程序员创建更有组织的代码、划分职责、减少依赖、简化重构过程并促进代码重用。

开闭原理

缩写中的“O”代表“开/闭原则”。 Bob叔叔用来定义这个原则的一句话是:

“类必须对扩展开放,但对修改关闭”

根据这个原则,我们必须开发一个应用程序,确保我们以通用的方式编写类或模块,以便每当您觉得需要扩展类或对象的行为时,您不需要更改类本身。这里的扩展可以理解为程序的添加或更改。

目的是允许添加新功能而无需更改现有代码。这可以最大限度地减少引入错误的风险并使代码更易于维护。

实际应用

假设您有一个 DiscountCalculator 类来计算产品折扣。最初,我们有两个产品类别:电子产品和服装。让我们从不应用 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 的问题

封装违规:每次新的产品类型需要不同的折扣时,都需要修改calculateDiscount方法,包括在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% 更改代码库,但可以减少插入新功能所需更改的代码总量。

这个原则使得代码更能适应变化,无论是满足新的需求还是纠正错误。

以上是Typescript 和 Java 中的开闭原则应用的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn