Sizin web uygulamanızı oluşturmanız için bir çok kod ve proje yapısı mevcuttur ve az ya da çok düşünerek bu mimarileri kullanabilirsiniz. Ama genel desenleri kullanmak genellikle daha iyi fikirdir, çünkü kodunuzun daha temiz olmasını ve diğer geliştiriciler tarafından daha kolay anlaşılmasını sağlar.
En çok kullanılan “design pattern”lerden birisi Factory Pattern’dir. Bu desende, bir sınıf basitçe kullanmak istediğiniz nesneyi oluşturur. Aşağıda bir örnekle bu deseni açıklayalım:
Bu kod bir Automobile nesnesini oluşturmak için bir factory kullanıyor. Kodunuzu bu şekilde kullanmanızın iki muhtemel yararı vardır. Birincisi, ilerde Automobile sınıfınızın ismini değiştirdiğinizde isim değişikliğini sadece Factory sınıfında yapmanız yeterli olacaktir. İkincisi, karmaşık işler yapan obje oluşturduğunuzda bütün işi factory sınıfında yapabilirsiniz, her seferinde işlemleri tekrarlamak yerine sadece yeni bir instance oluşturmanız yeterli olacaktır.
Factory desenini kullanmak her zaman gerekli değildir. Örnek kod gereksiz karmaşıklık ekleyen çok basit bir factory örneğidir. Oldukça büyük ve karmaşık projelerde factory kullanarak kendinizi bir çok sorundan koruyabilirsiniz.
When designing web applications, it often makes sense conceptually and architecturally to allow access to one and only one instance of a particular class. The singleton pattern enables us to do this.
The code above implements the singleton pattern using a static variable and the static creation method getInstance()
.
Note the following:
__construct
is declared as protected to prevent creating a new instance outside of the class via the new
operator.__clone
is declared as private to prevent cloning of an instance of the class via the clone
operator.__wakeup
is declared as private to prevent unserializing of an instance of the class via the global function unserialize()
.getInstance()
with the keyword static
. This allows the subclassing of the class Singleton
in the example.The singleton pattern is useful when we need to make sure we only have a single instance of a class for the entire request lifecycle in a web application. This typically occurs when we have global objects (such as a Configuration class) or a shared resource (such as an event queue).
You should be wary when using the singleton pattern, as by its very nature it introduces global state into your application, reducing testability. In most cases, dependency injection can (and should) be used in place of a singleton class. Using dependency injection means that we do not introduce unnecessary coupling into the design of our application, as the object using the shared or global resource requires no knowledge of a concretely defined class.
With the strategy pattern you encapsulate specific families of algorithms allowing the client class responsible for instantiating a particular algorithm to have no knowledge of the actual implementation. There are several variations on the strategy pattern, the simplest of which is outlined below:
This first code snippet outlines a family of algorithms; you may want a serialized array, some JSON or maybe just an array of data:
By encapsulating the above algorithms you are making it nice and clear in your code that other developers can easily add new output types without affecting the client code.
You will see how each concrete ‘output’ class implements an OutputInterface - this serves two purposes, primarily it provides a simple contract which must be obeyed by any new concrete implementations. Secondly by implementing a common interface you will see in the next section that you can now utilise Type Hinting to ensure that the client which is utilising these behaviours is of the correct type in this case ‘OutputInterface’.
The next snippet of code outlines how a calling client class might use one of these algorithms and even better set the behaviour required at runtime:
The calling client class above has a private property which must be set at runtime and be of type ‘OutputInterface’ once this property is set a call to loadOutput() will call the load() method in the concrete class of the output type that has been set.
The front controller pattern is where you have a single entrance point for you web application (e.g. index.php) that handles all of the requests. This code is responsible for loading all of the dependencies, processing the request and sending the response to the browser. The front controller pattern can be beneficial because it encourages modular code and gives you a central place to hook in code that should be run for every request (such as input sanitization).
The model-view-controller (MVC) pattern and its relatives HMVC and MVVM lets you break up code into logical objects that serve very specific purposes. Models serve as a data access layer where data is fetched and returned in formats usable throughout your application. Controllers handle the request, process the data returned from models and load views to send in the response. And views are display templates (markup, xml, etc) that are sent in the response to the web browser.
MVC is the most common architectural pattern used in the popular PHP frameworks.
Learn more about MVC and its relatives: