让我了解面向对象的编程

时间:2010-05-17 20:13:30

标签: c# object oop

我是入门级.Net开发人员并使用它来开发网站。我从经典的asp开始,去年用一本简短的C#书跳上了船。 随着我的发展,我学到了更多,并开始看到来自经典的asp我总是使用C#像脚本语言。 例如,在我的上一个项目中,我需要在网络服务器上编码视频,并编写了像

这样的代码
public class Encoder
{
    Public static bool Encode(string videopath) {

        ...snip...

        return true;
    }
}

在搜索与我的项目相关的样本时,我看到有人这样做

public class Encoder
{
    Public static Encode(string videopath) {
        EncodedVideo encoded = new EncodedVideo();

        ...snip...

        encoded.EncodedVideoPath = outputFile;
        encoded.Success = true;

        ...snip...
    }
}

public class EncodedVideo
{
    public string EncodedVideoPath { get; set; }
    public bool Success { get; set; }
}

据我所知,第二个例子是面向对象的,但我没有看到使用EncodedVideo对象的意义。

我做错了吗?是否真的有必要在Web应用程序中使用这种代码?

10 个答案:

答案 0 :(得分:6)

有人曾经向我解释过OO作为汽水罐。

Soda can是一个对象,一个对象有很多属性。还有很多方法。例如..

SodaCan.Drink();

SodaCan.Crush();

SocaCan.PourSomeForMyHomies();

等...

理论上,OO设计的目的是编写一行代码,并在对象之间进行抽象。

这意味着Coder.Consume(SodaCan.contents);与你的问题有关。

编码视频与编码器不同。编码器返回编码视频。编码视频可以使用编码器,但它们是两个单独的对象。因为它们是服务于不同功能的两个不同实体,它们只是一起工作。

就像我吃苏打水一样,并不意味着我是一个汽水罐。

答案 1 :(得分:1)

这两个例子都不够完整,无法评估。第二个例子似乎比第一个例子更复杂,但不知道如何使用它很难说。

面向对象的设计是最好的,它允许你:

1)将相关信息和/或功能保存在一起(而不是使用并行阵列等)。

或者

2)利用继承和接口实现。

您的第二个示例可能是将数据更好地保存在一起,如果它返回EncodedVideo对象并且该方法的成功或失败需要在事后跟踪。在这种情况下,您将替换布尔“成功”变量和具有单个对象的路径的组合,清楚地记录两个数据的关系。

另一个例子没有涉及的另一种可能性是使用继承来更好地组织编码过程。您可以拥有一个基类来处理打开文件,复制数据等的“笨拙工作”,然后从该类继承您需要执行的每种不同类型的编码。在这种情况下,您的大部分代码都可以直接针对基类编写,而无需担心实际执行的编码类型。

答案 2 :(得分:0)

实际上第一个对我来说看起来更好,但不应该返回任何东西(或返回编码的视频对象)。

通常我们假设方法成功完成而没有异常错误 - 如果遇到异常错误,我们throw an exception

答案 3 :(得分:0)

面向对象编程基本上与组织有关。即使没有像C#这样的OO语言,您也可以以OO方式编程。通过将相关功能和数据组合在一起,可以更轻松地处理日益复杂的项目。

答案 4 :(得分:0)

你不一定做错了什么。什么范式最有效的问题是值得商榷的,并且不太可能有明显的赢家,因为有很多不同的方法来衡量“好的”代码,例如。可维护,可扩展,性能,可重用,模块化等。

没有必要,但在某些情况下它可能有用。查看各种MVC示例以查看OO代码。通常,OO代码具有可重复使用的优点,因此为一个应用程序编写的内容可以一次又一次地用于其他应用程序。例如,查看log4net,了解很多人使用的日志框架。

答案 5 :(得分:0)

您的结构OO程序的方式 - 您使用哪些对象以及如何安排它们 - 实际上取决于许多因素:项目的年龄,项目的总体规模,问题的复杂性以及一点点只是个人品味。

我能想到的最好的建议是将OO的所有理由包含在一个快速课程中,这是我学习设计模式的原因:“封装变化的部分”。 OO的值是重用将重复的元素而不编写其他代码。但显然你只关心将代码“包装”到对象中,如果将来实际上会重复使用或修改它们,那么你应该弄清楚可能会发生什么变化并从中创建对象。

在您的示例中,使用第二个设置的原因可能是您可以在程序中的其他位置重用EncodedVideo对象。无论何时你需要处理EncodedVideo,你都不关心“如何编码和使用视频”,你只需使用你拥有的对象并信任它来处理逻辑。如果编码逻辑很复杂并且可能会发生变化,那么封装编码逻辑也可能很有价值。然后,您将更改隔离到代码中的一个位置,而不是许多可能使用该对象的潜在位置。

(简而言之:您发布的特定示例不是有效的C#代码。在第二个示例中,静态方法没有返回类型,但我假设您打算让它返回EncodedVideo对象。)

答案 6 :(得分:0)

这是一个设计问题,所以答案取决于你需要什么,这意味着没有正确或错误的答案。第一种方法更简单,但在第二种情况下,您在EncodedVideo类中封装了编码逻辑,您可以轻松更改Encoder类中的逻辑(例如,基于传入的视频类型)。

答案 7 :(得分:0)

我认为第一个例子似乎更简单,除非我尽可能避免使用静态来提高可测试性。

public class Encoder
{
    private string videoPath; 

    public Encoder(string videoPath) {
        this.videoPath = videoPath;
    }

    public bool Encode() {

        ...snip...

        return true;
    }
}

答案 8 :(得分:0)

是否需要OOP?否。

OOP是个好主意吗?是。

你不一定做错了什么。也许有更好的方式,也许不是。

总的来说,OOP促进了模块化,可扩展性和易维护性。这也适用于Web应用程序。

在您的特定Encoder / EncodedVideo示例中,我不知道使用两个离散对象来完成此任务是否有意义,因为它取决于很多事情。

例如,EncodedVideo中存储的数据是否仅在Encode()方法中使用过?然后使用单独的对象可能没有意义。

但是,如果应用程序的其他部分需要知道EncodedVideo中的某些信息,例如路径或状态是否成功,那么拥有一个EncodedVideo对象是件好事。可以在应用程序的其余部分传递。在这种情况下,Encode()可以返回EncodedVideo类型的对象而不是bool,从而使该数据可用于您应用的其余部分。

答案 9 :(得分:0)

除非您想将EncodedVideo类重用于其他内容,否则(根据您提供的代码)我认为您的方法完全可以接受此任务。除非在EncodedVideo和Encoder类中有不相关的功能,否则它会形成一个应该拆分的大量代码,那么你并没有真正降低类的内聚性,这很好。假设您不需要重用EncodedVideo并且这些类具有内聚性,通过拆分它们可能会创建不必要的类并增加耦合。

请记住:1。面向对象的哲学可能是非常主观的,并且没有单一的正确答案,2。你可以随后重构:p