статический метод фабрики вопрос! - PullRequest
0 голосов
/ 05 апреля 2011

на этом сайте говорится, что новый объект не создается каждый раз, что приводит к эффективности, но, как я вижу, объект создается каждый раз в статическом методе.

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

http://www.javapractices.com/topic/TopicAction.do?Id=21

так почему статические фабричные методы так эффективны?

не пишет что-то вроде этого: Object obj = new Object такой же, как если бы я делал Object obj = Someclass.GetObj ();

class Someclass
{
   public static Object GetObj()
   {
     return new Object
   }
}

Кэширование существует, но в любом случае создается новый объект ...

Ответы [ 6 ]

3 голосов
/ 05 апреля 2011

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

  • лучшее именование метода
  • возвращение подклассов

Для этого в Effective Java естьтак что продолжайте и читайте это.В любом случае, эту книгу необходимо прочитать.

Обновление: как я уже сказал, объект можно кэшировать.Но это зависит от реализации.Тот, который вы показываете, не кэширует их.Тот, который показывает Питер, кеширует их.У вас есть такая возможность.С конструктором - нет.

1 голос
/ 05 апреля 2011

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

http://www.allapplabs.com/java_design_patterns/factory_pattern.htm

Заводской шаблон обычно не используется для кэширования объектов. Шаблон Singleton определен для обеспечения создания только одного экземпляра объекта.

1 голос
/ 05 апреля 2011

Они более гибкие - например, если входные параметры для нового объекта недопустимы, вы можете вернуть нулевую или некоторую реализацию нулевого объекта (= экземпляр, который ничего не делает, но не нарушит ваш код с помощью NullPointerException), или, как уже упоминалось ранее, вы можете кэшировать созданные экземпляры. Еще одно преимущество использования фабричных методов перед конструкторами - вы можете называть их как угодно, что может быть более читабельным, если есть несколько конструкторов с большим количеством необязательных параметров.

РЕДАКТИРОВАТЬ: если вы хотите использовать только один экземпляр, вы можете использовать эту простую фабрику:

class Someclass{
  private static Object o=new Object();

  public static Object getObj(){
    return o;
  }
}
1 голос
/ 05 апреля 2011

Когда вы используете new Object(), новый объект должен быть создан.

Если вы используете статическую фабрику, она может по желанию создать новый объект или повторно использовать существующий.

Простой пример - использование Integer.valueOf(int) вместо new Integer(int). Статическая фабрика имеет кэш маленьких целых чисел и может сохранить значительную часть целых чисел. Для некоторых случаев использования это могут быть все используемые целые числа. В последнем случае всегда создается новый объект, который является относительно неэффективным.

0 голосов
/ 05 апреля 2011

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

Например, представьте, что вам нужно написать класс, который загружает некоторые данные из URL

public class WavAudio {
      private byte[] raw;
      private static HashMap<String,WavAudio> cache;
      private WavAudio(byte[] raw){
          this.raw=raw;
      }
      public static loadFromUrl(String someUrl){
          //If data has been loaded previously we don't have to do this more (faster..)
          if (cache.containsKey(someUrl))
               return cache.get(someUrl);
          //Else we'll load data (that would take some time)
          InputStream ires=(new URL(someUrl)).openStream();    
          ByteArrayOutputStream baos=new ByteArrayOutputStream();
          byte[] raw = new byte[4096];          
          int nBytesRead;
          while ((nBytesRead = ires.read(raw, 0, raw.length))>0)
          baos.write(raw, 0, raw); 
          byte[] downloaded=baos.toByteArray();
          WavAudio curr=new WavAudio(raw);
          cache.put(someUrl,raw);
          return raw;
      }      

      public static void main(String[] args){
          WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1");
          SomePlayer.play(wav); //the first melody is playing
          WavAudio wav=WavAudio.loadFromUrl("http://someUrl_2");
          SomePlayer.play(wav); //the second melody is playing
          //won't be downloaded twice
          WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1");
          SomePlayer.play(wav);
      }
}
0 голосов
/ 05 апреля 2011

Идея в том, что вы используете их в качестве стратегии.Если позже вы захотите реализовать кэширование, вы просто измените этот метод и добавите его туда.Сравните это с «новым Bla ()», разбросанным по всему коду, и попыткой реализовать кеширование для класса Bla.

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

Таким образом, нет никакого преимущества в использовании "new Bla ()" вместо заводских методов вообще.

...