3

这可能有点主观,但我想听听您对我目前情况的看法。我有一个用于序列化/反序列化对象的类。

public class MyClass
{
    public static string ToXmlString( MyClass c ) { /*...*/ }
    public static MyClass FromXmlString( string xml ) { /*...*/ }
}

我只喜欢这种方法,因为它将两个功能保持在同一水平。但是,我的目标是避免使用静态方法(在可行的情况下)。我也觉得我可能违反了 SRP,但这个对象的主要目标是它可以从 xml 字符串中序列化/反序列化。

在这种情况下使用静态方法有什么想法吗?我应该只制作ToXmlString非静态的,但留下FromXmlString静态的吗?我应该创建一个只处理 MyClass 序列化的新类吗?

编辑:

我在这里讨论的类是一个简单的传输对象。它用于从第三方工具保存/恢复值。

谢谢!

4

6 回答 6

2

FWIW 我认为序列化是一个问题,应该与您的其他班级分开,尤其是如果您的班级是业务类型。

开发组件时的一般规则是确保它只解决少数问题并将业务问题与技术问题分开。

如果以后您需要从数据库或二进制格式管理序列化怎么办?

您可能会以越来越多的技术方法(SaveToDB、LoadFromDB、ToBinaryStream、FromBinaryStream...)结束,这些方法会使您的类变得混乱并使其越来越难以维护,从而隐藏其主要目的(例如业务)。

于 2010-08-16T16:58:40.903 回答
1

C# 和 Java 的标准库中的约定是To__方法是实例方法,From__方法是静态的(根据需要)。例如:ToString()是一个实例方法。

于 2010-08-23T21:16:38.510 回答
0

如果您想要标准序列化(XML 与否),则序列化/反序列化方法都不应是静态的。

在 MyClass 中,您应该重新定义“writeObject”和“readObject”以替换您的默认序列化方法。这是关于这些方法的Sun 教程。

如果您不想要“标准序列化”,那么使用静态方法对我来说很好。静态 util 方法不是异端。

PS:这不是问题,但是如果你想要 WML 序列化,你可以使用XStream API

于 2010-08-16T16:55:15.857 回答
0

详细说明 Benoit 的回答,这是一个示例,其中正在序列化的类定义了序列化行为(我没有写这个):

// : c12:SerialCtl.java
// Controlling serialization by adding your own
// writeObject() and readObject() methods.
// From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002
// www.BruceEckel.com. See copyright notice in CopyRight.txt.

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SerialCtl implements Serializable {
  private String a;

  private transient String b;

  public SerialCtl(String aa, String bb) {
    a = "Not Transient: " + aa;
    b = "Transient: " + bb;
  }

  public String toString() {
    return a + "\n" + b;
  }

  private void writeObject(ObjectOutputStream stream) throws IOException {
    stream.defaultWriteObject();
    stream.writeObject(b);
  }

  private void readObject(ObjectInputStream stream) throws IOException,
      ClassNotFoundException {
    stream.defaultReadObject();
    b = (String) stream.readObject();
  }

  public static void main(String[] args) throws IOException,
      ClassNotFoundException {
    SerialCtl sc = new SerialCtl("Test1", "Test2");
    System.out.println("Before:\n" + sc);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    ObjectOutputStream o = new ObjectOutputStream(buf);
    o.writeObject(sc);
    // Now get it back:
    ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
        buf.toByteArray()));
    SerialCtl sc2 = (SerialCtl) in.readObject();
    System.out.println("After:\n" + sc2);
  }
}

请注意使用瞬态来描述不会被序列化的字段。

于 2010-08-16T17:02:43.993 回答
0

我认为在静态与实例方面分离补充方法并不太糟糕,因为框架偶尔会这样做(例如,String.Split / Join)。

但话虽如此,我认为尽量减少使用静态方法的目标并不是一个好主意。要避免的是静态可变状态,而不是静态方法。仅对其参数而不是静态变量进行操作的静态方法,简直太棒了。

纯静态函数比实例方法更易于维护,因为实例方法不会以明显的方式通信它可以改变哪些实例字段。通过遵循不维护任何静态状态的规则,可以依靠静态方法仅对其参数进行操作,从而可以更好地预测该方法在应用程序中的作用。这在多线程时尤其重要。

由于 ToXmlString 方法被应用于定义它的类的实例,因此其中一些注意事项不适用。它可以很容易地以不正当的方式更改传递给它的对象的状态,因为它可以访问实例的所有私有成员。但我只是想说,作为一般规则,静态方法不是问题。

于 2010-08-16T17:14:11.770 回答
0

您可以定义一个带有 XMLReader 的构造函数(如果您真的坚持,也可以定义一个字符串)。这样做的主要优点是它允许您在类中拥有更强大的不变量,并通过使用readonly.

于 2010-08-16T17:16:45.680 回答