【问题标题】:Pass an Object, Inherit it or use direct method传递一个对象,继承它或使用直接方法
【发布时间】:2012-03-28 02:00:48
【问题描述】:

我是 C# 和 OOP 场景的新手,并且正在构建有助于我更好地理解 OOP 概念的基础架构。这是我做的一个项目,用来测试我的课堂知识。有人可以检查一下并向我解释什么是更好的方法以及为什么?

以下是我的 C# 程序中的对象:

  • deskClerk [具有返回客户对象的 addCustomer 方法。]
  • 订购
  • 库存
  • 客户
  • 实用程序
  • 陈列室 [包含客户、库存和订单列表 - 所有列表 私人的。 Showroom 也有 addCustomer 方法]

我希望deskClerk 对象将客户添加到Showroom 对象。为此,我有以下选择:

  1. 我可以将 Showroom 对象传递给deskClerk,然后使用 Showroom 中的 addCustomer 方法来添加客户。
  2. 我可以直接将 Customer 添加到 Showroom,因为 Showroom 对象已经具有 addCustomer 方法。
  3. 我可以从 Showroom 继承deskClerk 对象,在这种情况下 DeskClerk 将能够使用 Showroom 的 addCustomer 方法。

我的问题是:

  • 以上三个选项中哪一个逻辑合理?
  • Showroom 是否应该有 addCustomer 方法?陈列室 应该只是 Stock、Customer 和 Order 列表的存储对象,对吧?

【问题讨论】:

  • 您能详细介绍一下您要解决的现实问题吗?什么是 DeckClerk、Customer 和 Showroom 类?办公桌文员做什么的?展厅是做什么的?为什么它必须了解客户、库存和订单?客户、库存和订单有什么关系?
  • 这是汽车展厅的软件模型,汽车展厅肯定会有一个负责日常销售的“deskClerk”,以及一个可以评估销售情况的“StoreManager”等等。deskClerk需要的方法有限只访问他有权访问的字段。

标签: c# oop inheritance object encapsulation


【解决方案1】:

您必须弄清楚客户是否可以在不参与陈列室的情况下存在,以及是否可以在不参与陈列室的情况下浮动。

如果是这种情况,我会做这样的事情

public class Showroom {
    public DeskClerk Clerk { get; private set; }
    public List<Customer> Customers { get; set; }
    [...]
}

如果没有陈列室,前台文员将没有多大用处,因此在其构造函数中将陈列室设置为依赖项:

public class DeskClerk {
    private ShowRoom { get; set; }
    public DeskClerk(ShowRoom showRoom) {
        ShowRoom = showRoom;
    }
    public Customer AddCustomer(Customer customer) {
        //do stuff with customer object
        ShowRoom.Add(customer);
        return cutomer;
    }
}

不要认为有 2 个地方可以添加客户是正确的,但 DeskClerk 仍然应该有责任这样做。

但是,可能误解了您的问题 :-) 希望对您有所帮助!

【讨论】:

  • 感谢您的解决方案我最终使用了这个。如果您想了解我这样做的原因,请阅读我对@Fuex 解决方案的评论 :)
【解决方案2】:

我喜欢你解决问题的方法。所以阅读你的问题:

  • 每个选择都有合理的逻辑,因此您的选择取决于
    你想如何构造你的对象以及你想如何使用它们。作为一名程序员,我建议您使用第二个或第三个。

  • 是的,Showroom 可以有一个 addCostumer 方法,在这种情况下,如果你想使用第二个或第三个选项,如果你想将一个 Costumer 添加到存储中,它必须有一个 addCostumer 方法。

这里使用第三个选项是我的示例代码:

class Stock { /*...*/ }
class Customer { /*...*/  }
class Order { /*...*/  }

class Showroom
{
    protected List<Stock> StockList;
    protected List<Customer> CustomerList;
    protected List<Order> OrderList;

    public Showroom()
    {
        StockList = new List<Stock>();
        CustomerList = new List<Customer>();
        OrderList = new List<Order>();
    }

    public virtual void addStock(Stock stock)
    {
        StockList.Add(stock);
    }

    public virtual void addCustomer(Customer customer)
    {
        CustomerList.Add(customer);
    }

    public virtual void addOrder(Order order)
    {
        OrderList.Add(order);
    }

    //...
}

class deskClerk : Showroom
{
    public deskClerk()
    {
        CustomerList = new List<Customer>();
    }

    public override void addCustomer(Customer customer)
    {
        CustomerList.Add(customer);
    }

    //...
}

所以我可以给你推荐另一件事:

每次您使用对象时,都会为每个对象分配他的角色和任务,然后每个选择都取决于您要使用的逻辑。选择一个你认为可以工作并且非常适合你想使用它的环境。

【讨论】:

  • 感谢您的解决方案,我最终没有从陈列室继承deskClerk,因为即使没有陈列室,deskClerk 也没有用,但deskClerk 能够为“任何”陈列室工作。例如,电视遥控器和电视,电视遥控器能够与任何电视一起工作(忽略 IR 协议),因此从电视继承它会破坏制作 TVRemote 的通用目的。然而,在 TVRemote 的构造函数中使电视成为依赖项会更合适,这样遥控器就会知道要为哪台电视工作。 :)
  • 是的,你的推理无可挑剔,但在这种情况下,谈到我的代码,deskClerk 可能只是一个实用程序。使用您的代码的人可以直接使用Showroom
猜你喜欢
  • 2016-03-26
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-11
  • 2023-01-24
  • 2018-10-04
  • 1970-01-01
相关资源
最近更新 更多