Обработка различных типов аргументов в подклассах с помощью единого интерфейса базового класса - PullRequest
3 голосов
/ 08 октября 2011

У меня есть фабрика, которая позволяет вам создавать некоторые вещи различного типа. Ценности каждой вещи происходят из разных источников и имеют разные типы. Я хочу, чтобы потребитель класса использовал один интерфейс getValue () и setValue () для выполнения важной работы в базовом классе. Я тоже хочу подклассы чтобы иметь возможность обрабатывать несколько различных типов аргументов. В настоящее время я делаю некоторые jiggery-pokery идентификации типов (см. Thing2) для обработки различных типов. Есть ли лучший способ сделать это?

Мой вопрос: я правильно здесь поступаю?

abstract class Thing {

    public static Thing thingFactoryCreationary(byte iClass) {
        // let's assume this is more sophisticated in real life.
        return iClass==1 ? new Thing1() : new Thing2();
    }

    final public Object getValue() {
        myImportantWorkFunction();
        return _getValue();
    }

    final public void setValue(Object oValue) {
        myImportantWorkFunction();
        _setValue(oValue);
    }

    private void myImportantWorkFunction() {
        // save the world here.
    }        

    abstract protected Object _getValue();
    abstract protected void _setValue(Object oValue);
}

class Thing1 extends Thing {
    private String msMyStringPropertyValue;
    protected String _getValue() {
        return msMyStringPropertyValue;
    }
    protected void _setValue(Object oValue) {
        msMyStringPropertyValue = oValue.toString();
    }
}

class Thing2 extends Thing {

    protected InputStream _getValue() {
        return new FileInputStream("/some/file/descriptor");
    }

    protected void _setValue(Object oValue) {
        InputStream oInStream = null;            
        if (InputStream.class.isInstance(oValue)) {
            oInStream =(InputStream)oValue;
        } else {
            if (File.class.isInstance(oValue)) {
                oInStream = new FileInputStream((File)oValue);
            } else {
                oInStream = new ByteArrayInputStream(oValue.toString().getBytes("UTF-8"));                
            }                                       
        }
        FileOutputStream oOutStream = new FileOutputStream("/some/file/descriptor");
        myFileStreamCopyFunction(oInStream, oOutStream);
    }

    private void myFileStreamCopyFunction(InputStream oInStream, OutputStream oOutStream) {
        // reading and writing is fundamental.
    }

}

Спасибо.

1 Ответ

2 голосов
/ 08 октября 2011

Да, это хороший способ.Возможно, вы можете указать с помощью дженериков принятый тип:

public abstract class Thing<S, G> {
    private G value;
    public void setValue(S object);
    public G getValue();
}
public class Thing1 extends Thing<String, String> {..}
public class Thing2 extends Thing<ResourceHolder, String> {..}

Где ResourceHolder - это простой компонент с геттерами и сеттерами для InputStream и File.S и G означают setter и getter - вы указываете, что вы ожидаете установить, и что ожидает клиент, когда он вызывает get

Таким образом, каждый подкласс может обрабатывать ровно один тип значения, ноэтот тип может содержать несколько вариантов.Таким образом, вместо рефлексии вы бы использовали простой null чек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...