1

代码示例是 C#,但这是一个一般的 OO 问题。

我知道根据 OO 规则,应尽量减少类耦合,成员应尽可能保持私有,等等。

考虑这个例子:

您正在编写一个深奥的程序,该程序具有某种数据集(我不是在谈论System.Data.DataSet),它实际上用于程序的各个方面。事实上,程序的存在基本上只是为了加载、显示、操作和保存数据集。此外,任何时候都只能加载一个数据集,并且在程序打开时加载。

如果我们严格遵循 OO 规则,我们将有

public void ShowSomeGraphs(IData data)
{
  // do stuff with data which implements IData
}

但是,例如,我们可能会将public static Data成员存储在 中Program

public void ShowSomeGraphs()
{
  // do stuff with Program.Data
}

一方面,我们用一个稍短的函数签名换取了大大增加的类耦合。另一方面,我们不再将 Data 参数传递给几乎每个函数,无处不在

正确的答案可能是:尽可能避免类耦合。本地数据变量只是指针,因此内存开销可以忽略不计,并且由于类是解耦的,它们可以在以后在其他地方使用。

虽然现实地说,Data 类的结构在不同的应用程序中可能会有显着的不同,所以你不能直接从这个程序中拉出一个类,然后把它放到其他地方而不做任何调整。以一种可以直接加入的方式编写类所需的额外时间和精力可能很难向利益相关者证明是合理的。

我现在正在研究这种程序,并且我使用了 OO-canon 方法:在需要的地方传递数据参数 我已经最小化了与 IData 接口的类耦合,以概括数据集以供将来代码重用。鉴于应用程序,我几乎可以肯定这段代码永远不会被重用。如果没有这些额外的接口和抽象,就最终用户而言,该程序的工作方式将完全相同,但对我来说将大大减少头痛和开发时间。

你怎么看待这件事?您是否认为花费所有额外的时间来编写接口和泛化以确保类在可能的情况下解耦是合理的,尤其是当您以后看不到在其他地方使用的类时?

4

3 回答 3

1

如何使用单例模式提供方法或只读属性来获取 IData 接口?这样,您只需耦合到一个非常薄的单例类,并且您与数据集的所有交互都是通过 IData 接口完成的。

(我肯定会避免紧密耦合。即使你不打算对这个应用程序做太多事情,你也会在开发过程中遇到一个问题,这将迫使你接触更多的代码,而不是通过一个界面。)

上面提出的单例解决方案的代码示例:

using System;

public class MyClass {
    public static void Main() {
        // simple usage:
        Console.WriteLine("From Main: " + Singleton.Instance.IMyData.GetData());
        // client code from another type:
        new ClientObj().DoWork();
        Console.ReadKey();
    }
}

public sealed class Singleton {
    // standard singleton stuff:
    private static readonly Singleton _instance = new Singleton();
    private Singleton(){}
    public static Singleton Instance {get { return _instance; }}
    // data interface stuff:
    private MyData _myData = new MyData();
    public IData IMyData {get { return _myData; }}
}

// the interface:
public interface IData {
    string GetData();
}

// concrete implementation of the data class
public class MyData : IData {
    public string GetData() {return "Hello World!";}
}

// example of a type using the singleton and the IData interface
public class ClientObj {
    public void DoWork() {
        IData data = Singleton.Instance.IMyData;
        string str = data.GetData();
        Console.WriteLine("From other obj: " + str);
    }
}

一些警告:上面的代码示例被完全剥离以显示单例和共享接口的概念。没有实现线程安全,没有数据对象的初始化等。

于 2011-11-08T23:25:17.347 回答
1

不要为此苦恼。严重地。

软件范例/模式可以帮助我们,而不是教条地遵循。

您在问题中明确表示您认为松散耦合过大,并且可以证明原因。因此,不要使用它。

于 2011-11-09T09:30:21.197 回答
0

好吧,您的文本中有一个很大的假设:程序中始终只有一个数据集。你确定这个条件会一直存在吗?曾经有一段时间,文字处理器一次只能保存一个文本。今天,能够同时打开多个文件已成为标准。如果第一个网络浏览器一次只能打开一个网页,我也不会感到惊讶。今天没有人会使用不能同时打开多个页面的网络浏览器。我认为那种你可以说在程序中肯定只有一个的对象是非常罕见的。事实上,我唯一会做一个全局对象或单例的就是对象工厂。

另一方面,为每个函数调用传递对象对我来说似乎也太过分了。因此我会选择中间立场:让对象记住那个“全局”对象,所以你只需要通过构造函数传递它。这将每个单个对象限制为一个 Data 对象,但如果您决定要在程序中轻松拥有多个 Data 对象,仍然可以。

于 2011-11-08T23:39:35.480 回答