4

我感觉我对界面的使用不正确。我知道接口是具体类必须遵守的合同。

因此,我将解释我要解决的问题,也许有人可以为我指明正确的方向。

我正在构建一个为任何请求返回页面的应用程序,我有三种页面类型,Cms、产品和类别。

这三个都必须实现以下接口:

public interface IPage
    {
        PageType PageType { get; set; }
        PageContent Content { get; set; }
        Meta Meta { get; set; }
    }

无论页面类型如何,都需要这些属性。

一个页面可能有额外的属性,具体取决于它们的类型,例如一个类别页面可能是这样的:

public class CategoryPage : IPage
    {
        public PageType PageType { get; set; }
        public PageContent Content { get; set; }
        public Meta Meta { get; set; }

        public List<Product> Products { get; set; }
    }

目前我有一个页面服务,它将为请求的 url 返回一个页面。

根据 PageType 它知道要返回什么类型的页面。

问题是 pageService 返回一个 IPage 以便它可以返回任何页面类型。

这是一个问题,因为并非我的所有具体都只实现了接口,在类别页面的情况下,它也有一个列表,正如您所期望的,除非我转换为具体类型,否则我无法访问。

但是有没有办法我可以返回一个通用的页面类型并让接收者知道它是什么具体的?

我确信我现在是如何做到这一点的并不是最好的方法,并且想要一些关于如何解决这个小问题的指导和建议。

谢谢

更新

我已经安顿好了演员表。

我确信必须有更好的方法来处理几个类使用一些基本属性但也实现它们自己的情况。当您从服务中获得这些类之一时,您需要知道您得到了什么,以便您可以使用相关属性..

或者也许我在这里尝试做的只是完全错误的,我需要采取另一种方法。我想我会继续我现在所拥有的,但要继续思考它。

更新 2

我已经改变了我这样做的方式,所以我不需要演员,我有一个 PageType 枚举,我用它来识别正在使用的页面的类型。

这与继承所有需要的 Ipage 相结合似乎是一个足够好的解决方案,并且不需要演员表。

4

4 回答 4

2

您始终可以使用is 关键字检查您引用的对象是否属于特定类型;

if(obj is Class1) {

也就是说,如果您的设计要求您了解具体类型,那么设计本身很可能有问题。如果类之间的行为存在差异,请在类内部实现差异,而不必强制它们在它们之外实现。

于 2012-01-28T16:55:31.827 回答
1

如果您的接收器必须知道具体类型,那么您没有正确使用接口。

如果您要返回一个页面,那么实际上没有任何理由知道它是什么类型的页面。我会Render在接口中添加一个方法,IPage这样接收者所要做的就是调用Render(),页面将处理其余的。

于 2012-01-28T16:52:29.460 回答
0

以下是检查从服务返回的接口是否是您的具体类型的两种方法。

        IPage page;
        if (page is CategoryPage)
        {
           // use type here
        }

        CategoryPage categoryPage = page as CategoryPage;
        if (categoryPage != null)
        {
          // use type here
        }
于 2012-01-28T16:59:34.897 回答
0

理想情况下,几乎不需要使用类型转换,特别是考虑到泛型的存在。然而,从实用的角度来看,有时使用类型转换比竭尽全力避免它们更好。

从某种意义上说,在可能需要使用某些对象中存在但其他对象中不存在的能力的情况下,拥有具有不同能力的对象(或将返回不同能力的工厂方法)的集合是不优雅的。当然可以这样说

  IInterfaceThatMayOrMayNotBePresent foo = bar as IInterfaceThatMayOrmayNotBePresent;
  如果 (foo != null)
    foo.MethodOfThatInterface();

但它有点代码味道。通常最好确定为什么需要使用列表中所有实例中不存在的方法,并确定更好的类设计是否有帮助。

例如,假设某些类型的对象想要在“Wowzo”发生时得到通知;其他类型无所谓。此外,人们希望有包含两种类型对象的列表,并且需要通知所有关心的项目。可以使用上述类型检查模式只通知那些需要它的项目,但可能有更有效的方法:可以定义两个接口:IAcceptWowzoNotificationsIActOnWowzoNotifications,后者继承第一个。实现第一个但不实现第二个的类预计会使用空方法实现 Wowzo 通知。如果列表中的每个项目都实现了 IAcceptWowzoNotifications,无论它是否对此类通知执行任何操作,简单地通知列表中的每个人都会比检查哪些项目需要通知更快。

请注意,这种方法并非完全没有成本。首先,因为没有提供接口来提供默认方法实现,所以实现的每个类型IAcceptWowzoNotifications都需要定义存根方法。此外,如果将一个项目放在列表中的唯一原因是向它发送 Wowzo 通知,并且如果通知列表中的每个人比将项目添加到列表中更频繁,那么最好检查是否itemsIActOnWowzoNotifications在将它们添加到列表之前实现,而不是盲目地将可能需要或可能不需要的项目添加到列表中。

接口继承层次结构非常强大,并且在许多情况下未被充分利用。接口实现不必担心哪些成员来自哪个祖先接口,这一事实使得拆分接口变得很容易,而且比拆分类所发生的麻烦要少得多。

于 2012-01-28T18:02:30.933 回答