面向对象概念中的抽象是一种仅定义类必须具有的基本方面的实践。从本质上讲,类必须是不完整且不精确的,以便我们可以通过子类对特殊性进行建模。由此产生了子类、母类和继承的概念。
继承是类之间关系的表示,其中一个类扩展另一个类以继承父类的行为。
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
封装违规:每次新的产品类型需要不同的折扣时,都需要修改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中文网其他相关文章!