整个程序使用的公共静态数据

时间:2011-11-08 23:19:22

标签: oop decoupling coupling

代码示例是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接口的类耦合以概括数据集以供将来代码重新使用使用。鉴于应用程序,我几乎可以肯定这个代码永远不会被重用。如果没有这些额外的接口和抽象,就最终用户而言,该程序的工作方式将完全相同,但对我来说,这代表了更少的麻烦和开发时间。

您如何看待这个?您是否认为花费所有额外时间来编写接口和概括以确保类在可能的情况下解耦是合理的,尤其是当您看不到稍后在其他地方使用的类时?

3 个答案:

答案 0 :(得分:1)

如何使用singleton pattern提供方法或只读属性来获取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);
    }
}

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

答案 1 :(得分:1)

不要为之烦恼。认真。

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

你在问题​​中明确表示你认为松散耦合过度,你可以证明为什么。因此,不要使用它。

答案 2 :(得分:0)

嗯,你的文本中有一个很大的假设:程序中总会只有一个数据集。你确定这种情况会一直持续吗?有一段时间,文字处理器一次只能容纳一个文本。今天,能够同时打开多个文件是标准的。如果第一个Web浏览器一次只能打开一个网页,我也不会感到惊讶。今天没有人会使用不能同时打开多个页面的网络浏览器。我认为在某种程度上你可以说它只会在程序中只有一个,它是非常罕见的。实际上,我唯一可以创建全局对象或单例的是对象工厂。

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