You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

学习装饰器模式遇方法覆盖难题:无法重写Phone类访问器

Understanding Method Overriding with the Decorator Pattern in TypeScript

Hey there! Let's work through your confusion around method overriding and how it fits with the Decorator Pattern using your Phone.ts class as a starting point.

First, let's unpack your existing code. You've set up a base Phone class where the price getter throws an error—this is a valid way to force subclasses to implement that logic, but we can make this cleaner (and catch issues at compile time) using TypeScript's abstract classes.

Step 1: Refactor the Base Phone Class to Be Abstract

Instead of relying on runtime errors, marking the class and price getter as abstract tells TypeScript that any subclass must provide an implementation for price. This eliminates the chance of forgetting to override it later:

export abstract class Phone {
  private description: string;

  constructor(description = 'Default description') {
    this.description = description;
  }

  get phoneDescription() {
    return this.description;
  }

  // Abstract getter forces subclasses to implement this logic
  abstract get price(): number;
}

Step 2: Create a Concrete Phone Subclass (Standard Overriding)

Let's build a specific phone brand class that overrides the price getter. This is classic inheritance-based overriding:

import Phone from './Phone';

export class SamsungGalaxy extends Phone {
  constructor() {
    super('Samsung Galaxy S24');
  }

  // Override the abstract price getter with a concrete value
  get price(): number {
    return 899;
  }
}

Step 3: Implement the Decorator Pattern (Dynamic Behavior Extension)

The Decorator Pattern is all about dynamically adding behavior to objects without altering their original class. Decorators will also "override" the price getter, but instead of providing a standalone value, they wrap the behavior of an existing Phone instance.

Here's an example of a ScreenProtectorDecorator that adds a screen protector to any phone and increases the total price:

import Phone from './Phone';

export class ScreenProtectorDecorator extends Phone {
  private decoratedPhone: Phone;

  constructor(phone: Phone) {
    // Append decorator details to the original phone's description
    super(`${phone.phoneDescription}, with tempered glass screen protector`);
    this.decoratedPhone = phone;
  }

  // "Override" the price getter to add the screen protector cost
  get price(): number {
    return this.decoratedPhone.price + 29;
  }
}

How It All Comes Together

Let's use these classes to see overriding and decoration in action:

import SamsungGalaxy from './SamsungGalaxy';
import ScreenProtectorDecorator from './ScreenProtectorDecorator';

// Start with a basic Galaxy
let myPhone = new SamsungGalaxy();
console.log(myPhone.phoneDescription); // Output: Samsung Galaxy S24
console.log(myPhone.price); // Output: 899

// Dynamically add a screen protector using the decorator
myPhone = new ScreenProtectorDecorator(myPhone);
console.log(myPhone.phoneDescription); // Output: Samsung Galaxy S24, with tempered glass screen protector
console.log(myPhone.price); // Output: 928

Key Differences Between Inheritance Overriding and Decorator Wrapping

  • Inheritance-based overriding: Static, set at compile time. Subclasses replace the base class's abstract implementation with their own fixed logic.
  • Decorator-based wrapping: Dynamic, done at runtime. Decorators don't replace the original behavior—they extend it by calling the decorated object's method and adding extra logic around it. You can even stack multiple decorators (e.g., add a case and a screen protector) to build up behavior incrementally.

Tweaking Your Original Error Handling (If You Skip Abstract Classes)

If you prefer to stick with a non-abstract base class, you can improve your error message to make debugging clearer:

get price(): number {
  throw new Error('The price getter must be overridden by a subclass or decorator');
}

内容的提问来源于stack exchange,提问作者deojeff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:27:29