I actively work with @salesforce platform in my current project, so have to write code via Apex language (not Legends)
That's why I'm reading the book "Apex Design Patterns" by @jitendrazaa and @ToAnshulVerma and want to share some goods (maybe only for myself to keep in mind)
Factory method p. (Virtual Constructor) - a concept of delegating the creation of similar types of classes.
Abstract factory p. (Kit) - a families producer of related objects without specifying their concrete classes. It unites a number of factory methods.
Factory method & Abstract factory schemas
Singleton. It’s needed to work with some limited or costly resource as only one class instance (getInstance () and a private constructor). Useful to set up connection with DB for example. But don’t use singleton class in global context, better to use it on low layers.
Next creational pattern is "Builder" that is used to instantiate an object of a complex class using the step-by-step approach and return a constructed object at once.
Schema
Table to compare Builder👷 with Abstract Factory 🏭
Share a little UML with Builder class for creating objects for testing in #Salesforce Apex (create = insert to DB in test mode, build = exists during transaction only).
Interesting thing is a chain 🔗 of Builder and Factory patterns
Prototype p. is about creating a new object on the basis of an existing object of the same type. We control how data is copied or shared with a new object.
"There is one more approach frequently followed by Salesforce developers to clone a complete Apex class, which is by serializing it as JSON and then deserializing it back to an approach Apex class type," said authors and it has a place to be
Good, now we can discuss Structural Patterns 🧱
Façade p. is used to convert complex classes into simplified classes or interfaces with a number of methods where groups of classes are either wrapped into one class that knows the logic of a complex process.
The problem for the client is a too complicated and waste logic to launch.
"Code work with a set of objects that belong to a library or framework. Ordinarily, we need to initialize all of those objects, keep track of dependencies, execute methods in the correct order, and etc"
The façade is widely used in API development to provide easier client interaction
Adapter p. adapts one interface to another. Two incompatible classes should interact with each other, without those classes knowing about each other's implementation.
2 types - object adapter (only one third-party library) and runtime adapter (dynamically created object of adapter interface by i.e. a factory)
Both the facade and adapter p. use the wrapper class. However, the adapter p. is used to allow interactions between the exciting systems. but the facade p. is used to create a new simplified interface.
The Bridge p. decouples an abstraction from its implementation so both parts can be changed independently.
In the ^ example CoreFramework class consists of a reference to the Theme class.
Bridge VS Adapter
"The adapter p. works for the existing code; however, in the bridge p. we design it from the beginning".
Bridge VS Strategy
"The strategy p. is meant for runtime polymorphism. The bridge p. is a structural p. where the code changes frequently and its implementation is decoupled from its abstraction"
Composite p. helps interact uniformly with a part as well as a part-whole hierarchy (an object and a group of objects). “In OOP with a part-whole relationship, an object has its own life cycle and can be part of the other object.”
This p. uses the concept of the Liskov substitution principle, "where objects in an app should be replaced by instances of their child implementations without altering the correctness of a program".
The Decorator p. adds additional functionality to the existing objects at runtime to achieve a single objective. The idea is composition (or aggregation) can be most beneficial than inheritance in some cases.
Good illustration with a pizza as example - newthinktank.com/2012/09/decora…
The Flyweight p. improves the memory usage using shared objects.
After discussing about how to create objects or structure our code to enhance its modularity and reusabilyty, we can focus on communication between objects and keep them losely coupled at the same time - behaviour p. 👋
Chain of responsibility p. follows the launch and leave design with a single execution path, allowing more than one object to process the request.
Oh, so nice image quality 👍
How our validators work
Command p. is used to create an instance of operation, thereby enabling it to be passed and queued. The p. separates a requestor from a reciever so that reciever can invoke the processor without knowing the requestor.
"The point here is what 👐 is to be done and when ⏰ to do it. A requestor knows what is to be done and provides the info to a reciever. A reciever just knows when it has to be done and invokes the process appropriately"
The Interpreter p. helps in designing a code structure to interpret a languague by deviding the languague into various grammatical constructs.
Наконец, читаю "Чистый код" Боба Мартина; в этом треде буду добавлять моменты из книги, которые оказались для меня концептуально новыми и которые я хотел бы применить в своем коде
Keep calm and code on
Супер правило! но в условиях скрама и строгих сроков по проекту все же нужно хладнокровно расставлять приоритеты между рефакторингом и новой функциональностью.
Либо можно поработать на выходных и в пн порадовать коллег мердж реквестом 🤪
Хоть Intellij пытается подписывать сигнатуру вызываемого метода, но согласен, что предложенный подход к перегрузке конструкторов добавляет как ясности в точке вызова, так и гибкости в коде класса создаваемого объекта