Почему имеет Создать метод вместо того, чтобы использовать “новый”?

В вашем AndroidManifest.xml указан неверный тег. Вы используете android:Label в:

<service
    android:name=".KarakalpakKeyboard"
    android:Label="KarakalpakKeyboard"
    android:permission="android.permission.BIND_INPUT_METHOD"
    >

это опечатка. Следует android:label:

<service
    android:name=".KarakalpakKeyboard"
    android:label="KarakalpakKeyboard"
    android:permission="android.permission.BIND_INPUT_METHOD"
    >
11
задан Michael Prewecki 19 May 2009 в 05:51
поделиться

17 ответов

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

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

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

И, конечно же, это неотъемлемая часть шаблона Singleton.

15
ответ дан 3 December 2019 в 01:13
поделиться

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

    public void Example()
    {
        var person = new Person
                         {
                             GivenName = "John",
                             FamilyName = "Smith",
                             Address = new Address
                                           {
                                               Street = "Wallace",
                                               Number = 12
                                           },
                             PhoneNumbers = new List<PhoneNumber>
                                                {
                                                    new PhoneNumber
                                                        {
                                                            Number = 1234234,
                                                            AreaCode = 02
                                                        },
                                                    new PhoneNumber
                                                        {
                                                            Number = 1234234, AreaCode = 02
                                                        }
                                                }
                         };
    }

    internal class PhoneNumber
    {
        public int AreaCode { get; set; }

        public int Number { get; set; }
    }

    internal class Address
    {
        public int Number { get; set; }

        public string Street { get; set; }
    }

    internal class Person
    {
        public Address Address { get; set; }

        public string GivenName { get; set; }

        public string FamilyName { get; set; }

        public List<PhoneNumber> PhoneNumbers { get; set; }
    }
}
0
ответ дан 3 December 2019 в 01:13
поделиться

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

Также @Rashmi Pandit написал:

   public static User CreateByCredentials(string uid, string pwd)
    {
       ....
    }

    public static User CreateById(int id)
    {
    ...
    }

В своем ответе вы не можете просто использовать перегруженные конструкторы с разными сигнатурами методов вместо создание двух разных методов создания?

0
ответ дан 3 December 2019 в 01:13
поделиться

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

Как сделать в C #

1
ответ дан 3 December 2019 в 01:13
поделиться

Это также обычно используется, когда вы хотите, чтобы фреймворк, класс или какая-либо другая конфигурация определяли ГДЕ на самом деле будет создан объект. Когда вы используете подход нового конструктора, он создается локально. Если вы используете этот подход, он потенциально может быть создан удаленно через вызов службы и возвращен и т. Д. Это подход, примененный Рокки Лхотка в структуре CSLA .

0
ответ дан 3 December 2019 в 01:13
поделиться

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

1
ответ дан 3 December 2019 в 01:13
поделиться

Статический конструктор также является хорошим способом дать более явные имена вашему конструктору. Это также может быть полезно для параметра по умолчанию

, например: Myclass.create (); вместе с новым Myclass (defaultParam1, defaultParam2 ...)

Джошуа Блох говорит об этом в эффективном Java (пункт 1)

1
ответ дан 3 December 2019 в 01:13
поделиться

Many of the other answers have covered specific occasions where this idea may be useful. The idea of encapsulating instance creation is used in many IoC frameworks such as Spring, Castle and so on. The idea is that by centralizing instance creation, you can customize the configuration of your application to use different set of objects. A common example is logging. By changing the configuration, you can tell your logger factory to produce different instances of your logging classes according to the situation.

If applied this idea can lead to very loosely coupled systems, that may easily be changed after deployment or even at runtime. However, the complexity increases as you have another level of indirection.

1
ответ дан 3 December 2019 в 01:13
поделиться

Кроме синглтонов, наличие «статического фабричного метода», такого как MyClass.Create , может быть полезно, если человек, реализующий MyClass.Create может захотеть вернуть подкласс MyClass ... например, во время тестирования он может вернуть экземпляр подкласса MyClassWithExtraTestingFunctionality ... или, в зависимости от параметра конфигурации, экземпляр подкласса MyClassBeingRemotedOverTheNetwork ...

1
ответ дан 3 December 2019 в 01:13
поделиться

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

Но если у вас нет явной причины для этого, не делайте этого.

1
ответ дан 3 December 2019 в 01:13
поделиться

Более формально его обычно называют Заменить конструктор фабричным методом

Вы хотите делать больше, чем простую конструкцию при создании объекта.

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

Я бы порекомендовал книгу Рефакторинг: Улучшение дизайна существующего кода (Фаулер)

2
ответ дан 3 December 2019 в 01:13
поделиться

Вы правы. Это не шаблон Singleton. Это заводской узор.

Использование Create () вместо new дает позволяет вам давать осмысленные имена методам, тем самым давая пользователю больше ясности

Возьмите это, например:

public class User
{
    public int id;
    public string userName;
    public string password;
    public string role;

    private User() { }

    public static User CreateByCredentials(string uid, string pwd)
    {
        User user = new User();
        user.userName = uid;
        user.password = pwd;
        return user;
    }

    public static User CreateById(int id)
    {
        User user = new User();
        user.id = id;
        return user;
    }

}

У этого подхода есть два преимущества:

  1. Мы можем вернуть нулевой объект, что невозможно сделать с помощью конструктора (это может быть полезно или не во всех случаях.)
  2. Если существует много разных способов создания объекта, это дает вам возможность предоставить больше значимые имена функций. В этом примере у вас есть User.CreateByCredentials (строковое имя пользователя, строковый пароль) и User.CreateById (int id). Вы можете выполнить те же функции с помощью перегрузки конструктора, но редко с той же ясностью.
3
ответ дан 3 December 2019 в 01:13
поделиться

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

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

http://en.wikipedia.org/wiki/Factory_pattern

Billy3

2
ответ дан 3 December 2019 в 01:13
поделиться

Другая причина, продемонстрированная статическим методом Guid.NewGuid (), заключается в том, что тип является структурой. В этом случае среда CLR требует, чтобы конструктор без параметров по умолчанию создал новый экземпляр со всеми полями, инициализированными значениями по умолчанию. В случае Guid это означает:

Guid g = new Guid ();

будет Guid.Empty. Очевидно, вам нужна возможность создать новый Guid, который будет рандомизирован, поэтому метод Guid.NewGuid () - способ сделать это.

3
ответ дан 3 December 2019 в 01:13
поделиться

Это не синглтон ... Create будет возвращать один и тот же экземпляр каждый раз, если бы он был.

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

public static MyClass Create()
{
    if(OS == Windows)
        return new MyDerivedClassForWindows();
    else if(OS == Linux)
        return new MyDerivedClassForLinux();
    etc....
}
8
ответ дан 3 December 2019 в 01:13
поделиться

Это хороший способ заставить MyClass быть окончательным, если вы используете частный конструктор. Таким образом, подклассы не могут быть созданы, потому что их конструктор не может получить доступ к конструктору super.

Еще одно преимущество - когда у вас есть один параметр для конструктора. Затем вы можете назвать создание с помощью эмуляции именованных аргументов:

public static MyClass createWithDays(int days) {
...
}

Теперь сравните new MyClass (5) с MyClass.createWithDays (5)

1
ответ дан 3 December 2019 в 01:13
поделиться

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

Одноэлементный шаблон

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

public class MySingletonClass
{
    private MySingletonClass currentInstance = null;

    public MySingletonClass CreateInstance()
    {
         if (currentInstance == null)
         {
              currentInstance = new MySingletonClass();
         }
         else
         {
              return currentInstance;
         }
    }
}

Factory Pattern

Factory Pattern - прекрасная возможность абстрагироваться от создания конкретных классов; например, предположим на мгновение, что у вас есть некоторый XML, и в зависимости от того, какой узел (NodeA, NodeB или NodeC) вы видите в XML, у вас есть другой класс, который будет его обрабатывать. Пример:

public class MyXmlProcessorFactory
{
    public static IMyXmlProcessor GetMyXmlProcessor(XmlDocument document)
    {
         XmlNode rootNode = document.DocumentElement;

         if (rootNode.SelectSingleNode("NodeA") != null)
         {
              return new NodeAMyXmlProcessor();
         }
         else if (rootNode.SelectSingleNode("NodeB") != null)
         {
              return new NodeBMyXmlProcessor();
         }
         else if (rootNode.SelectSingleNode("NodeC") != null)
         {
              return new NodeCMyXmlProcessor();
         }
         else
         {
              return new DefaultMyXmlProcessor();
         }
    }
}
4
ответ дан 3 December 2019 в 01:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: