2010-08-16 2 views
3

Это может быть немного субъективно, но я хотел бы получить информацию о моей текущей ситуации. У меня есть класс, который будет использоваться для сериализации/десериализации объекта.Сохранение кода на одном уровне при работе со статическими методами

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

Мне нравится этот подход, потому что он поддерживает две функции на одном уровне. Однако моя цель - избегать использования статических методов (когда это возможно). Он также чувствует, что я могу вилоровать SRP, но главная цель этого объекта заключается в том, что он может быть сериализован/десериализован из строки xml.

Любые мысли об использовании статических методов в этой ситуации? Должен ли я просто сделать ToXmlString нестатический, но оставить FromXmlString статическим? Должен ли я создать новый класс, который будет обрабатывать только сериализацию MyClass?

EDIT:

Класс, который я здесь обсуждение является простым объектом передачи. Он используется для сохранения/восстановления значений из инструмента thrid party.

Спасибо!

+0

Зачем статично? –

+1

Я избегаю статики по ряду мелких причин. 1) Легче перейти на IoC при необходимости 2) Разверните объекты через наследование 3) Избегайте деградации классов Бога с помощью методов OO ... –

ответ

2

FWIW Я думаю, что сериализация является проблемой, которая должна быть отделена от остальной части вашего класса, прежде всего, если ваш класс является бизнес-типом.

Общее правило при разработке компонента заключается в обеспечении того, чтобы оно касалось лишь нескольких проблем и отделяло проблемы бизнеса от технических.

Что делать, если позже вам необходимо управлять сериализацией из базы данных или двоичного формата?

Возможно, вы закончите все больше и больше технических методов (SaveToDB, LoadFromDB, ToBinaryStream, FromBinaryStream ...), которые загромождают ваш класс и затрудняют его поддержание, скрывая его основные цели (например, бизнес).

0

Если вы хотите стандартную сериализацию (XML или нет), то методы serialize/deserialize не должны быть статическими.

В MyClass вы должны переопределить «writeObject» и «readObject», чтобы заменить методы сериализации по умолчанию вашими. Вот Sun tutorial о методах тезисов.

Если вы не хотите «стандартную сериализацию», использование статических методов для меня отлично. Статические методы использования не являются ересью.

PS: это не вопрос, но если вы хотите сериализацию WML, вы можете использовать XStream API.

+2

«реальная сериализация»? Вы имеете в виду, что сейчас Джедод не «реален»? Существует множество вполне обоснованных причин не использовать стандартные механизмы сериализации. –

+0

Вы правы. «Стандартный» мир лучше, чем «реальный»: я редактировал свой пост, чтобы исправить это, спасибо. –

0

Уточняя ответ Бенуа, вот пример, в котором класс, который сериализации определяет поведение сериализации (я не пишу):

// : 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); 
    } 
} 

Примечание использование переходного процесса описывает поля, которые не будут сериализованная.

0

Я не думаю, что это слишком страшно для того, чтобы взаимодополняющие методы были разделены относительно статического или экземпляра, поскольку Framework делает это иногда (например, String.Split/Join).

Но, сказав это, я думаю, что цель минимизации использования статических методов - не очень хорошая идея. Вещь, которой следует избегать, - статическое изменяемое состояние, а не статические методы.Статический метод, который работает только по своим параметрам, а не по статическим переменным, является чистой удивительностью.

Чистая статическая функция может быть более ремонтопригодной, чем метод экземпляра, поскольку метод экземпляра не позволяет очевидным образом передавать поля экземпляров, которые он может мутировать. Следуя правилу о том, что статическое состояние не поддерживается, статический метод может быть использован только для работы с его параметрами, и, следовательно, роль метода в приложении может быть лучше предсказана. Это особенно важно при многопоточности.

Поскольку метод ToXmlString применяется к экземпляру класса, в котором он определен, некоторые из этих соображений не применяются. Он мог бы легко изменить состояние объекта, передаваемого ему незаметными способами, поскольку он может получить доступ ко всем частным членам экземпляра. Но я просто хочу сказать, что в качестве общего правила статические методы не являются проблемой.

0

Вы можете определить конструктор, который принимает XMLReader (или строку, если вы действительно настаиваете). Главное преимущество этого заключается в том, что он позволяет вам иметь более сильные инварианты в вашем классе и быть явным в отношении каких-либо неизменных членов с использованием readonly.

1

Соглашение в стандартных библиотеках для C# и Java состоит в том, что методы To__ являются методами экземпляра, а методы From__ являются статическими (по необходимости). Например: ToString() - это метод экземпляра.

Смежные вопросы