Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript类方法定义用于计算带配料的食品价格的最佳实践_Javascript_Class_Oop_Model - Fatal编程技术网

javascript类方法定义用于计算带配料的食品价格的最佳实践

javascript类方法定义用于计算带配料的食品价格的最佳实践,javascript,class,oop,model,Javascript,Class,Oop,Model,我开了一家餐馆,并创建了软件来确定菜单上所有项目的价格 我首先为每个菜单项创建一个类,这样就可以使用接口计算价格 interface HasPrice { getPrice(): number; } class Ramen implements HasPrice { getPrice() { return 5; } } class Spaghetti implements HasPrice { getPrice() { retur

我开了一家餐馆,并创建了软件来确定菜单上所有项目的价格 我首先为每个菜单项创建一个类,这样就可以使用接口计算价格

interface HasPrice {
    getPrice(): number;
}

class Ramen implements HasPrice {
    getPrice() {
        return 5;
    }
}
class Spaghetti implements HasPrice {
    getPrice() {
        return 10;
    }
}
然后她决定应该有顶部,所以她使用了装饰图案

class RamenWithPork extends Ramen {
    getPrice() {
         super.getPrice() + 3;
    }
}
这一直有效,直到我决定扩展topping菜单,它变得太麻烦,无法处理组合数量的类。我应该如何修复它?

装饰图案 好的,这就是我们的工作——你们可以把你们的对象包装成另一个,用额外的行为来装饰它们。这解决了复杂的依赖层次结构的问题。你已经经历过了,但只是为了说明一下——假设你经历过

class Rament {}
class RamenWithPork extends Ramen {}
class RamenWithChicken extends Ramen {}
class RamenWithMushrooms extends Ramen {}
如果您有
RamenwithChickendMushroom
,会发生什么?你是扩展鸡肉拉面还是蘑菇拉面还是仅仅是拉面?如果你有
拉面,里面有猪肉、牛肉和鸡肉,那该怎么办?首先,你能记得这个班的名字吗?如果你一天后坐下来,你能记得是猪肉、鸡肉和蘑菇还是猪肉、蘑菇和鸡肉吗?第二,如何在类层次结构中对其进行建模

这里是decorator模式的用武之地-您可以创建如下decorator:

然后可以与任何食物一起使用。这里的
界面附加功能是为了方便起见。它有助于保持依赖关系层次结构的重点和实用性——
HasPrice
有点太模糊了——任何东西都可能有价格,但通过
OrderAddition
我们确切地知道这是什么类型的。另一种调用它的方法是
OrderDecorator
——它有点枯燥,但更具描述性,可以立即调用所使用的设计模式

使用类 因此,以下是使用装饰器时代码的外观:

interface MainDish { //renaming it to be more descriptive
    getPrice(): number;
}

class Ramen implements MainDish {
    getPrice() {
        return 5;
    }
}
class Spaghetti implements MainDish {
    getPrice() {
        return 10;
    }
}

//decorators would need to do the same as the object they decorate, 
//so the decorator implements the MainDish interface
interface OrderAddition extends MainDish {} 

abstract class AbstractOrderAddition implements OrderAddition {
  protected base: MainDish;

  constructor(base: MainDish) {
    this.base = base;
  }

  abstract getPrice(): number;
}

class WithChicken extends AbstractOrderAddition {
    getPrice() {
      return this.base.getPrice() + 5
    }
}

class WithMushrooms extends AbstractOrderAddition {
    getPrice() {
      return this.base.getPrice() + 1
    }
}

class WithPork extends AbstractOrderAddition {
    getPrice() {
      return this.base.getPrice() + 3
    }
}
这将允许您执行以下操作:

let order: MainDish = new Ramen();
order = new WithPork(order);
order = new WithMushrooms(order);

使用装饰函数 然而,这是装饰师的高度正式用法。在JavaScript中,您可以简化其中的一些功能,并且仍然保持相同的想法。您可以使用装饰器作为函数来修改给定的实例,而不是使用类:

interface OrderAdditionMaker{
  (additionalPrice: number) : AddToOrder
}

interface AddToOrder {
  (base: MainDish) : MainDish
}

const withChicken: AddToOrder = function withChicken(base: MainDish): MainDish {
  //take a reference of the original
  const originalGetPrice: MainDish["getPrice"] = base.getPrice.bind(base);

  //overwrite the `getPrice` method
  base.getPrice = function(): ReturnType<MainDish["getPrice"]> {
    return originalGetPrice() + 5;
  }

  return base;
}
接口OrderAdditionMaker{
(附加价格:编号):AddToOrder
}
接口AddToOrder{
(底座:主盘):主盘
}
const with chicken:AddToOrder=函数with chicken(基:主菜):主菜{
//参考原文
const originalGetPrice:MainDish[“getPrice”]=base.getPrice.bind(base);
//覆盖“getPrice”方法
base.getPrice=function():ReturnType{
返回originalGetPrice()+5;
}
返回基地;
}
通过使用,这可以进一步概括为更具功能性的路由,以便您可以轻松派生所有装饰器函数:

//interface for making decorators
interface OrderAdditionMaker{
  (additionalPrice: number) : AddToOrder
}

//decorator function
interface AddToOrder {
  (base: MainDish) : MainDish
}

const withExtra: OrderAdditionMaker = function (additionalPrice: number) {
  return function (base: MainDish): MainDish {
    const originalGetPrice: MainDish["getPrice"] = base.getPrice.bind(base);
    base.getPrice = function (): ReturnType<MainDish["getPrice"]> {
      return originalGetPrice() + additionalPrice;
    }

    return base;
  }
}

const withChicken: AddToOrder = withExtra(5);
const withMushrooms: AddToOrder = withExtra(1);
const withPork: AddToOrder = withExtra(3);
//制作装饰器的接口
接口OrderAdditionMaker{
(附加价格:编号):AddToOrder
}
//装饰函数
接口AddToOrder{
(底座:主盘):主盘
}
const with extra:OrderAdditionMaker=函数(additionalPrice:number){
返回函数(基:MainDish):MainDish{
const originalGetPrice:MainDish[“getPrice”]=base.getPrice.bind(base);
base.getPrice=function():ReturnType{
return originalGetPrice()+额外价格;
}
返回基地;
}
}
鸡肉常量:AddToOrder=withExtra(5);
蘑菇常数:AddToOrder=withExtra(1);
猪肉常量:添加到订单=额外(3);

装饰图案 好的,这就是我们的工作——你们可以把你们的对象包装成另一个,用额外的行为来装饰它们。这解决了复杂的依赖层次结构的问题。你已经经历过了,但只是为了说明一下——假设你经历过

class Rament {}
class RamenWithPork extends Ramen {}
class RamenWithChicken extends Ramen {}
class RamenWithMushrooms extends Ramen {}
如果您有
RamenwithChickendMushroom
,会发生什么?你是扩展鸡肉拉面
还是蘑菇拉面
还是仅仅是拉面?如果你有
拉面,里面有猪肉、牛肉和鸡肉,那该怎么办?首先,你能记得这个班的名字吗?如果你一天后坐下来,你能记得是猪肉、鸡肉和蘑菇还是猪肉、蘑菇和鸡肉吗?第二,如何在类层次结构中对其进行建模

这里是decorator模式的用武之地-您可以创建如下decorator:

然后可以与任何食物一起使用。这里的
界面附加功能是为了方便起见。它有助于保持依赖关系层次结构的重点和实用性——
HasPrice
有点太模糊了——任何东西都可能有价格,但通过
OrderAddition
我们确切地知道这是什么类型的。另一种调用它的方法是
OrderDecorator
——它有点枯燥,但更具描述性,可以立即调用所使用的设计模式

使用类 因此,以下是使用装饰器时代码的外观:

interface MainDish { //renaming it to be more descriptive
    getPrice(): number;
}

class Ramen implements MainDish {
    getPrice() {
        return 5;
    }
}
class Spaghetti implements MainDish {
    getPrice() {
        return 10;
    }
}

//decorators would need to do the same as the object they decorate, 
//so the decorator implements the MainDish interface
interface OrderAddition extends MainDish {} 

abstract class AbstractOrderAddition implements OrderAddition {
  protected base: MainDish;

  constructor(base: MainDish) {
    this.base = base;
  }

  abstract getPrice(): number;
}

class WithChicken extends AbstractOrderAddition {
    getPrice() {
      return this.base.getPrice() + 5
    }
}

class WithMushrooms extends AbstractOrderAddition {
    getPrice() {
      return this.base.getPrice() + 1
    }
}

class WithPork extends AbstractOrderAddition {
    getPrice() {
      return this.base.getPrice() + 3
    }
}
这将允许您执行以下操作:

let order: MainDish = new Ramen();
order = new WithPork(order);
order = new WithMushrooms(order);

使用装饰函数 然而,这是装饰师的高度正式用法。在JavaScript中,您可以简化其中的一些功能,并且仍然保持相同的想法。您可以使用装饰器作为函数来修改给定的实例,而不是使用类:

interface OrderAdditionMaker{
  (additionalPrice: number) : AddToOrder
}

interface AddToOrder {
  (base: MainDish) : MainDish
}

const withChicken: AddToOrder = function withChicken(base: MainDish): MainDish {
  //take a reference of the original
  const originalGetPrice: MainDish["getPrice"] = base.getPrice.bind(base);

  //overwrite the `getPrice` method
  base.getPrice = function(): ReturnType<MainDish["getPrice"]> {
    return originalGetPrice() + 5;
  }

  return base;
}
接口OrderAdditionMaker{
(附加价格:编号):AddToOrder
}
接口AddToOrder{
(底座:主盘):主盘
}
const with chicken:AddToOrder=函数with chicken(基:主菜):主菜{
//参考原文
const originalGetPrice:MainDish[“getPrice”]=base.getPrice.bind(base);
//覆盖“getPrice”方法
base.getPrice=function():ReturnType{
返回originalGetPrice()+5;
}
返回基地;
}
通过使用,这可以进一步概括为更具功能性的路由,以便您可以轻松派生所有装饰器函数:

//interface for making decorators
interface OrderAdditionMaker{
  (additionalPrice: number) : AddToOrder
}

//decorator function
interface AddToOrder {
  (base: MainDish) : MainDish
}

const withExtra: OrderAdditionMaker = function (additionalPrice: number) {
  return function (base: MainDish): MainDish {
    const originalGetPrice: MainDish["getPrice"] = base.getPrice.bind(base);
    base.getPrice = function (): ReturnType<MainDish["getPrice"]> {
      return originalGetPrice() + additionalPrice;
    }

    return base;
  }
}

const withChicken: AddToOrder = withExtra(5);
const withMushrooms: AddToOrder = withExtra(1);
const withPork: AddToOrder = withExtra(3);
//制作装饰器的接口
接口OrderAdditionMaker{
(附加价格:编号):AddToOrder
}
//装饰函数
接口AddToOrder{
(基础