当“喜欢组合超过继承”时生成传递代码 [英] Generating pass-through code when "preferring composition over inheritance"

查看:115
本文介绍了当“喜欢组合超过继承”时生成传递代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

假设我正在将手机建模为常规手机和PDA的组合。它是一种多重继承场景(手机是一个手机,而它是一种 PDA)。由于C#不支持多重继承,所以这几乎需要一些组合。另外,假设我有其他的理由赞成组合。

Let's say I'm trying to model a cell phone as a combination of a regular phone and a PDA. It's sort of a multiple inheritance scenario (a cell phone is a phone, and it is a PDA). Since C# doesn't support multiple inheritance, this pretty much calls for some kind composition. Plus, let's say that I have other reasons to favor composition anyway.

我一直想知道的事情:是否有任何工具会产生所有不可避免的通行证,通过代码自动?

让我用一些实际的代码说明我的例子:

Let me flesh out my example with some actual code:

接口

public interface IPhone
{
    public void MakeCall(int phoneNumber);
    public void AnswerCall();
    public void HangUp();
}

public interface IPda
{
    public void SendEmail(string[] recipientList, string subject, string message);
    public int LookUpContactPhoneNumber(string contactName);
    public void SyncWithComputer();
}

实施:

public class Phone : IPhone
{
    public void MakeCall(int phoneNumber) { // implementation }
    public void AnswerCall() { // implementation }
    public void HangUp() { // implementation }
}

public class Pda : IPda
{
    public void SendEmail(string[] recipientList, string subject, string message) { // implementation }
    public int LookUpContactPhoneNumber(string contactName) { // implementation }
    public void SyncWithComputer() { // implementation }
}

CellPhone类

public class CellPhone : IPhone, IPda
{
    private IPhone _phone;
    private IPda _pda;

    public CellPhone(IPhone phone, IPda pda)
    {
        _phone = phone;
        _pda = pda;
    }

    public void MakeCall(int phoneNumber)
    {
        _phone.MakeCall(phoneNumber);
    }

    public void AnswerCall()
    {
        _phone.AnswerCall();
    }

    public void HangUp()
    {
        _phone.HangUp();
    }

    public void SendEmail(string[] recipientList, string subject, string message)
    {
        _pda.SendEmail(recipientList, subject, message);
    }

    public int LookUpContactPhoneNumber(string contactName)
    {
        return _pda.LookUpContactPhoneNumber(contactName);
    }

    public void SyncWithComputer()
    {
        _pda.SyncWithComputer();
    }
}

编写CellPhone类是乏味且错误的-prone:

所有这个类真的都是作为电话 Pda 类。输入所有这些传递语句(如 _phone.MakeCall(phoneNumber); ),实际上并不需要人为的努力。

All this class really does is act as a conduit for the Phone and Pda classes. There is really no reason human effort should be required to type out all these pass-through statements (like _phone.MakeCall(phoneNumber);). It's just exposing the public interface of a couple member fields.

问题


  1. 有没有一个工具(最好是免费:)),可以避免我从容易出错的写入传递方法的细节?我知道我可以使用VS自动生成存根,但这只能让我一半的方式。

  1. Is there a tool (preferably free :)) that will save me from the error-prone tedium of writing pass-through methods? I'm aware that I can automatically generate the stubs using VS, but this only gets me half the way there.

你可以评价可行性和可取性吗这样的功能?是否值得提出建议,微软添加这种类型的代码生成?如果我这样做,你会不会呢?如果没有,您有什么反对意见?

Can you rate the feasibility and desirability of such a feature? Would it be worth putting in a suggestion to Microsoft to add this type of code generation? Would you upvote it if I did? If not, what objections do you have?

修改

每个人似乎都在说同样的事情:为什么我不做 _phone _pda 进入公共属性?我反对这是违反最不知情的原则。我的 CellPhone 类的客户端应该只是做一个手机的东西,不用要弄清楚哪些功能是 Phone 功能,它们是 Pda 功能。这创建了额外的依赖关系,使得CellPhone界面的功能不那么明显。

Everyone seems to be saying the same thing: Why don't I just make _phone and _pda into public properties? My objection to this is that it violates the "principle of least knowledge". The client of my CellPhone class should just do the things a cell phone does, it shouldn't have to deal with figuring out which features are Phone features and which are Pda features. This creates additional dependencies and makes the features of the CellPhone interface less obvious.

另外,不要仅仅关注这个例子。如果我正在编写适配器怎么办?它可能包含几个只是传递的接口成员,但它也可能包含一些具有独特实现的独特成员。我相信有很多情况下,传递代码是一件好事,我只是不喜欢写。

Also, don't focus just on this example. What if I were writing an adapter? It might contain several interface members that are just pass-throughs, but it might also contain some unique members with unique implementation. I believe there are many cases where pass-through code is a good thing, I just don't like writing it.

推荐答案

是的,您可以使用辉煌的VS加载项生成方法, ReSharper

Yes, you can generate the methods using the brilliant VS add-in, ReSharper

选择从代码生成菜单中生成委托方法选项(使用默认快捷方式Alt-Insert)。

Choose the "generate delegating methods" option from the code-generation menu (Alt-Insert with the default shortcut scheme).

你有一个类,实现一个接口,其中包含一个实现相同接口的字段,R#将为您提供生成传递代码的选项。它也可以与任意数量的接口一起使用。

Where you have a class that implements an interface, containing a field that implements the same interface, R# will give you an option to generate the pass-through code. It can work with any number of interfaces, too.

这篇关于当“喜欢组合超过继承”时生成传递代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆