Можно ли скрыть статический метод? - PullRequest
3 голосов
/ 19 августа 2010

У меня есть абстрактный класс каталога следующим образом.Он имеет статический метод OpenCatalog (), который используется для возврата конкретного конкретного каталога в зависимости от типа предоставленного местоположения.Как только он определил тип каталога, он вызывает определенный метод OpenCatalog () правильного конкретного типа каталога.Например, у меня может быть реализация Catalog, которая хранится в базе данных SQL, или другая, которая хранится в файловой системе.См. Код ниже.

public abstract class Catalog
{
    public static ICatalog OpenCatalog(string location, bool openReadOnly)
    {

        if(location is filePath)
        {
            return FileSystemCatalog.OpenCatalog(string location, bool openReadOnly);
        }
        else if(location is SQL server)
        {
            return SqlCatalog.OpenCatalog(string location, bool openReadOnly);
        }
        else
        {
            throw new ArgumentException("Unknown catalog type","location");
        }
    }

    ...

}

public abstract class FileSystemCatalog:Catalog
{

    public static new ICatalog OpenCatalog(string location, bool openReadOnly)
    {
        //Deserializes and returns a catalog from the file system at the specified location
    }

    ...

}



public abstract class SqlCatalog:Catalog
{

    public static new ICatalog OpenCatalog(string location, bool openReadOnly)
    {
        //creates an returns an instances of a SqlCatalog linked to a database
        //at the provided location          
    }

    ...

}

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

Ответы [ 3 ]

2 голосов
/ 19 августа 2010

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

public class CatalogFactory {
  public ICatalog CreateCatalog(string location, bool openReadOnly)
  {

    if(location is filePath)
    {
        return OpenFileCatalog(string location, bool openReadOnly);
    }
    else if(location is SQL server)
    {
        return OpenSqlCatalog(string location, bool openReadOnly);
    }
    else
    {
        throw new ArgumentException("Unknown catalog type","location");
    }
  }
  FileSystemCatalog OpenFileCatalog(string location, bool openReadOnly) {
    return new FileSystemCatalog{/*init*/};
  }
  SqlCatalog OpenSqlCatalog(string location, bool openReadOnly) {
    return new SqlCatalog{/*init*/};
  }

}
1 голос
/ 19 августа 2010

Вы на самом деле не скрываете это, потому что вы всегда можете сделать

Catalog.OpenCatalog(...);

Если вы хотите версию базового класса. Фактически, статические методы связаны с определенным классом и не являются виртуальными. Это просто приятное удобство, что вы можете вызывать статические методы, определенные в базовом классе производного класса.

0 голосов
/ 19 августа 2010

Я никогда не находил аргумента против использования частных / внутренних статических методов в терминах "запаха кода".

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

internal static ShippingRateType ToShippingRateType(this ProviderShippingRateType rateType) { }
...