Generative patterns

Available

3.1 Singleton

Singleton is a generic design pattern that guarantees that a single-threaded application will have a single instance of some class, and provides a global access point to this instance.

Very often, novice programmers like to assemble utility methods into some static class - a class that contains only static methods. This approach has a number of disadvantages - for example, you cannot pass a reference to an object of such a class, such methods are difficult to test, and the like.

As an alternative, a singleton class solution was proposed: a class that can have only one object. When attempting to create this object, it is only created if it does not already exist, otherwise a reference to an already existing instance is returned.

It is essential that it is possible to use an instance of the class, since in many cases wider functionality becomes available. For example, this class can implement some interfaces and its object can be passed to other methods as an implementation of the interface. What can not be done with a set of static methods.

Pros:

  • Methods are bound to an object, not a static class - you can pass an object by reference.
  • Object methods are much easier to test and mock.
  • An object is only created when needed: lazy object initialization.
  • Accelerating the initial launch of the program if there are many singles that are not needed for launch.
  • Alone can be further turned into a template-strategy or several such objects.

Minuses:

  • It becomes more difficult to control inter-thread races and delays.
  • It is difficult to write a multi-threaded “loner” “from the head”: access to a long-standing singleton, ideally, should not open a mutex. Better proven solutions.
  • A conflict between two threads over an unfinished single thread will result in a delay.
  • If the object is being created for a long time, the delay can interfere with the user or disrupt real time. In this case, it is better to transfer its creation to the stage of program initialization.
  • Special features are required for unit testing - for example, to put the library in “non-lonely” mode and completely isolate tests from each other.
  • A special tactic for testing the finished program is required, because even the concept of “the simplest launchability” disappears, because the launchability depends on the configuration.

3.2 Factory [Method]

A factory method is a generic design pattern that provides subclasses (classes-inheritors) with an interface for creating instances of a certain class. At creation time, descendants can determine which class to create.

In other words, this template delegates the creation of objects to the descendants of the parent class. This allows you to use not concrete classes in the program code, but to manipulate abstract objects at a higher level.

This pattern defines an interface for creating an object, but leaves it up to subclasses to decide which class to base the object on. A factory method allows a class to delegate the creation of subclasses. Used when:

  • the class does not know in advance which objects of which subclasses it needs to create.
  • a class is designed so that the objects it creates are specified by subclasses.
  • the class delegates its responsibilities to one of several helper subclasses, and it is planned to determine which class takes over these responsibilities.

3.3 Abstract Factory

An abstract factory is a generic design pattern that provides an interface for creating families of related or interdependent objects without specifying their concrete classes.

The pattern is implemented by creating an abstract class Factory, which is an interface for creating system components (for example, for a window interface, it can create windows and buttons). Then classes are written that implement this interface.

It is used in cases where the program must be independent of the process and types of new objects created. When it is necessary to create families or groups of related objects, excluding the possibility of simultaneous use of objects from different sets of these in the same context.

Strengths:

  • isolates specific classes;
  • simplifies the replacement of product families;
  • guarantees product compatibility.

Let's say your program works with the file system. Then to work in Linux you need LinuxFile, LinuxDirectory, LinuxFileSystem objects. And to work in Windwos, you need the WindowsFile, WindowsDirectory, WindowsFileSystem classes.

The Path class, which is created via Path.of(), is just such a case. Path is not really a class, but an interface, and it has WindowsPath and LinuxPath implementations. And what kind of object will be created is hidden from your code and will be decided at runtime.

3.4 Prototype

Prototype is a generative design pattern.

This pattern defines the kinds of objects that are created using a prototype instance and creates new objects by copying this prototype. It allows you to get away from the implementation and follow the principle of “programming through interfaces”.

An interface/abstract class at the top of the hierarchy is specified as the returning type, and descendant classes can substitute an heir that implements this type there. Simply put, this is the pattern of creating an object by cloning another object instead of creating it through a constructor.

The pattern is used to:

  • avoiding the additional effort of creating an object in a standard way (meaning using a constructor, since in this case the constructors of the entire object's ancestor hierarchy will also be called), when this is prohibitively expensive for the application.
  • avoid inheriting the object creator in the client application, as the abstract factory pattern does.

Use this design pattern when your program doesn't care how it creates, composes, and presents products:

  • instantiated classes are determined at run time, for example, using dynamic loading;
  • you want to avoid building class or factory hierarchies that parallel the product class hierarchy;
  • class instances can be in one of several different states. It may be more convenient to set the appropriate number of prototypes and clone them, rather than manually instantiating the class in the appropriate state each time.
1
Task
Module 3. Java Professional,  level 16lesson 2
Locked
Turnkey Universe
task4106
1
Task
Module 3. Java Professional,  level 16lesson 2
Locked
Personnel Forge
task4107
1
Task
Module 3. Java Professional,  level 16lesson 2
Locked
Personnel Factories
task4108
1
Task
Module 3. Java Professional,  level 16lesson 2
Locked
Prototypes
task4109
Comments (1)
  • Popular
  • New
  • Old
You must be signed in to leave a comment
null
Level 26 , Orlando, United States
24 July, 01:29
there's a typo in 3.3 (Windwos)