Как я могу спроектировать свою библиотеку Java / C #, чтобы она оставалась двоичной совместимой в случае будущих изменений? - PullRequest
1 голос
/ 18 апреля 2011

Задача: Я проектирую библиотеку, которая будет использоваться разработчиками.

Цель: Мне нужно убедиться, что изменения в будущих версиях не повлияютсуществующие разработчики.

Пример:

Ситуация во время первого выпуска:

Существует один класс

public class ClassSample

{

String methodSample(String para1,String Para2, int Para3, String Para4);

}

Ситуация во время второго выпуска:

Требования:

Ответ methodSample может возвращать несколько значений.

В методе methodSample требуется больше параметров.

Решение: Одним из способов может быть просто добавить другой перегруженный метод, который будет иметь новые параметры и возвращать объект, а не встроенный тип данных.

Но проблема с вышеприведенным решением состоит в том, что у него будет слишком много перегруженных методов.в будущем слишком много параметров будет излишним.

Модифицированное решение 1:

void methodSample(Request request, Response response)

В каждом выпуске (очевидно, при необходимости) я буду изменять классы запросов и ответов, чтобы иметь новые дополнительные методы для получения / установкиценности.В этом случае возникнет проблема, так как внутри метода я не смогу различить, является ли вызывающий абонент версии 10 или версии 20.

Модифицированное решение 2:

void methodSample(AbsractRequest request, AbstractResponse response)

В каждом выпуске мы можем расширять производный класс, как Request200 расширяет Request100, расширяет AbstractRequest, аналогично для классов ответов.В этом случае я могу проверить внутри метода, является ли вызывающий объект версии 10 или версии 20, проверив типизацию экземпляра.

В итоге Модифицированное решение 2 выглядит хорошо для меня, что вы думаете?

Ответы [ 2 ]

1 голос
/ 17 августа 2011

Я понимаю, что это может быть немного поздно, но мысль может быть полезной для вас или кого-то еще.

В прошлом я создал SDK, который требовал управления версиями, и сделал что-то очень похожее на то, что я написал ниже, и это сработало.

Идея состоит в том, что все сообщения являются производными от абстрагированного класса, как вы предложили, но в вызывающем приложении прямо в начале есть статическая переменная. Все запросы затем просто устанавливают свойство Version, равное статическому. Этот способ указывается только один раз во всем приложении.

Когда вы добавляете новые версии, просто добавляйте в перечисление. На самом деле я использовал целое число и увеличил его, но я думаю, что Enum всегда более удобен в обслуживании.

Наслаждайтесь!

namespace SilverlightClassLibrary1
{
    public enum SDKVersions
    {
        NonSpecific = 0,
        Version100,
        Version200,
    }

    public abstract class RequestBase
    {
        public static SDKVersions SystemSDKVersion { get; set; }

        public SDKVersions RequestSDKVersion { get; set; }

        protected RequestBase()
        {
            this.RequestSDKVersion = RequestBase.SystemSDKVersion;
        }
    }

    public class SimpleDataRequest : RequestBase
    {
        public String Data { get; set; }
    }

    public class SimpleDataResponse
    {
        public String Response { get; set; }
    }

    public class SomeSDKFunctionality
    {
        public static void RandomSDKFunction(SimpleDataRequest request, out SimpleDataResponse response)
        {
            switch (request.RequestSDKVersion)
            {
                case SDKVersions.Version100:
                    //Legacy response
                    response = new SimpleDataResponse()
                               {
                                   Response = "Helo " + request.Data,
                               };
                    break;

                default:
                    //Fixed / Updated Response
                    response = new SimpleDataResponse()
                               {
                                   Response = "Hello " + request.Data + "!",
                               };
                    break;
            }
        }
    }
}

namespace MyExternalApplication
{
    public class Main
    {
        public void ApplicationEntryPoint()
        {
            //Specify a specific version you intend to use
            RequestBase.SystemSDKVersion = SDKVersions.Version100;

        }

        public void ButtonClickExample()
        {
            SimpleDataResponse response;
            SomeSDKFunctionality.RandomSDKFunction(new SimpleDataRequest()
                                                   {
                                                       Data = "James",
                                                   }, out response);
        }
    }
}
1 голос
/ 18 апреля 2011

Я бы пошел за Modified Solution 1, но с добавлением метода get / set Version в класс.

Ваша библиотека может использовать getVersion, чтобы узнать, какое поведение ожидает пользовательская программа

...