根据两个子类型更改另一个类的对象状态的类

时间:2013-11-07 15:12:19

标签: design-patterns

这是一个家庭作业问题。

我有以下问题:我需要创建一个系统,根据房东的类型和房客的类型,模拟房东对房客征税或收费的方式。房东可以是低级房东(管理一个蹩脚的公寓楼),一个中产阶级房东(管理一个马马虎虎的建筑)和一个高级房东(管理一流的建筑)。租户可以是不负责任的租户(支付延迟数月)或负责任的租户(按时付款)。

根据房东的种类有固定的关税,根据房客的类型和房东的类型给予罚款或者福利:不负责任的房客将被收取额外费用,负责人将获得一些提前或任何其他方式支付的奖金,但这仅适用于他住在由高级房东或中产阶级房东管理的建筑物中。租户应该有一个属性,存储它必须支付的租金。

我用这种方式描述了这个问题:

  • 一个房东抽象类,具有以下从中继承的具体类:高级,低级和中级。
  • 租户抽象类,有不负责任和负责任的具体后裔。

我的问题是如何实施一种方法来为租户收费?我提出了以下内容:Landlord类定义了一个名为chargeTheTenant()的虚拟方法,该方法接受Tenant类的参数并根据租户的类型对其进行收费。问题是,为此,我必须使用反射来找出Landlord类具有哪种租户,并且我被告知我必须尝试不使用反射,并且我应该搜索设计模式来解决这个问题。

在这种情况下,我应该考虑采用哪种设计模式来避免使用反射?

由于

2 个答案:

答案 0 :(得分:0)

在这种情况下,租户抽象类可能是过度抽象的标志。如果您只使用方法 IsIrresponsible ()的单个租户类,则房东可以直接根据此方法的返回做出决策。

如果您坚持使用抽象租户类,只需将 IsIrresponsible ()函数设为虚拟。并始终在 IrresponsibleTenant 子类中返回true,并在 ResponsibleTenant 子类中返回false。但我个人认为这不值得。

答案 1 :(得分:0)

这是战略模式的一个场景。无论如何,它是这样的(C#领先)

public interface IChargeRent
{
      void Chanrge(Tenant tenant);
}

public class HighClassPropertyRentCollector:IChargeRent
{
     //we assume this object contains or it gets the tarrifs

     public void Charge(Tenant tenant)
     {
          if (tenant.IsIrresponsible) { //apply penalty
              }
             else{ //whatever }
     }
}


public class MiddleClassPropertyRentCollector:HighClassPropertyRentCollector {}

public class LowClassPropertyRentCollector:IChargeRent
{
     public void Charge(Tenant tenant) {

      }
 }

   public interface ICanChargeRent
   {
       PropertyClassType PropetyLevel {get;}
   }

   public class Landlord:ICanChargeRent { }

 //in another class
 public static IChargeRent GetRentCollector(ICanChargeRent ll)
 {
       //switch on PropertyLevel and instantiate the corresponding rent charger
  }
目前,中层地主与高级地主的行为相同,这就是我继承高级地主的原因,然而这可能会改变,因此每个地主都有明确的租金收费策略。同样对于低级别的房东来说。

如果有某种方法可以确定租户的质量,那么每个人都会注入一项能够提供这种功能的服务。而且由于租金收费行为是封装自己的类,您可以更改它而无需更改房东。

我的解决方案与您的建议不同的原因是,收取租金并不是定义房东的一部分(是的,我知道它听起来如何),而是房东的用例。毕竟,如果房东雇用物业经理并告诉他收取租金,房东的定义是否会改变?没那么多。

即使在这种情况下,我写的99%的代码也没有改变。您只需要在从Landlord中删除接口时使PropertyManager实现ICanChargeRent。如果我们了解有关该域的更多详细信息,我们可以提出一个更易于维护的解决方案(需要更少的更改)。