- Unity Certified Programmer:Exam Guide
- Philip Walker
- 1912字
- 2021-06-18 18:30:06
Overview of design patterns
At the beginning of this book, I mentioned that I will cover as much of Unity as possible, even though it is expected that you have been using Unity for at least 2 years before taking the exam. With regard to the fundamentals of programming, we will obviouslybe applying C# code. So, I expect that you are familiar with things such as functions, methods, if statements, classes, inheritance, polymorphism, and so on. I will explain what I'm doing and what you should be doing for each bit of code I present, but I won't be going through the basics of each segment of code.
Design patterns are typical solutions to problems you are likely going to come across, and if you have a pattern that can solve, then you should use it. Creating applications yourself with your own workflow is great, but if you can explain an issue to another programmer using design pattern terms, it shows that you know what you are talking about and if they are a good programmer, they'll likely know what you are talking about as well. The more patterns you know, the more flexible and standardized your code will be, and you are likely going to need more than one pattern. Otherwise, you'll be forcing your code down a structure that might not suit it and this will just cause problems.
The batch of 23 design patterns that are considered to be the foundation of all patterns was created by the gang of four. If you want to check out who the gang are and all of their 23 patterns, then go to https://www.packtpub.com/gb/application-development/hands-design-patterns-c-and-net-core. All of these patterns are divided into three categories—creational, structural, and behavioral:
- Creational:These patterns are designed to deal with the creation of objects—how and where an object is made.
- Structural:These patterns are built to show the relationships between entities.
- Behavioral:These patterns are designed to deal with how objects communicate with each other.
Ideally, after you pass your exam, try and visit more patterns. Get used to them as it will help you with your future roles. If you are interested in learning more about C# and design patterns, I recommend reading Hands-On Design Patterns with C# and .NET Core (https://www.packtpub.com/application-development/hands-design-patterns-c-and-net-core). This book isn't based on Unity but on C# .NET core, which means it contains coding libraries that overlap with Unity's. Unity contains elements of .NET and the more advanced you become as a programmer, the more you will inevitably start dipping into .NET. However, that is beyond the scope of this book. Let's return to our overview of some of the design patterns that you may be questioned on to compare in the exam. The first pattern is Builder, so let's check it out.
Builder
The first design pattern from the gang of four is the Builder design pattern. This design is typically used to create alterations on an object instead of repeating code. For example, if you have a car, you might want to install a different engine, paint it a different color, or install a sat-nav. The Builder design takes care of these alterations.
The following diagram shows how the Builder design pattern works:

Let's now move on to the next design pattern—Singleton—where we can have a control point from which the majority of your code sends and receives data.
Singleton
The Singleton design pattern isn't really much of a pattern as such, but more a common practice that some programmers love, or hate, or both! I'll explain why shortly.
The Singleton pattern acts as the core location that code will likely come from and go to. There is only one type of Singleton script; it exists in your Unity scene and never gets removed. If it does get removed or it doesn't exist, then one—and only one—is instantiated. You can use the Singleton pattern for a manager type of object that overlooks a game or it could hold what level the player is on, how much time is left in the level, what types of enemies will be used in this level, and so on. It's a central common point that the game will not want to forget or have multiple versions of. Like all design patterns, it makes sense why it's called Singleton because there should be only one of its type.
So, this sounds like a good design pattern. However, it is argued that a Singleton pattern holds too much control over the rest of the project's code and can also jeopardize other design patterns, especially if you have a system that depends on things being in a particular order. Also, it goes against the SOLID principles—the guide on how code should be treated—which I'll cover later on in this chapter. The single responsibility principle, in short, means a script shouldn't contain more than what it's originally built for. As you can imagine, a Singleton pattern can easily get complicated as it carries multiple responsibilities. The success of design patterns is heavily dependent on what a designer feels comfortable with; it also depends on what is required for the project. In any case, Singleton is still a popular pattern and we will use it in this project.
Coming back to the definition of Singleton, we can describe it as a pattern that ensures a class has only one instance and provides a global point of access to it.
The following diagram shows how the Singleton design pattern works:

Let's move on to the next design pattern—Abstract Factory—which focuses on making a mold of common traits that can be given extra features later.
Abstract Factory
The Abstract Factory pattern is designed to cover common traits that multiple objects share. For example, if I wanted to make enemies attack your player, I want all the enemies to have a health bar and I also want them to take damage from your player. With Abstract Factory, I can create a mold, so no matter what enemy is created, they will have these two properties, instead of having to create them each time for each enemy. This design makes things easier and more uniform for your project.
The following diagram shows how the Abstract Factory design pattern works:

The next design pattern is Prototype. This is useful for creating clones of an existing object.
Prototype
This is another simple pattern that carries some similarities to the Abstract Factory pattern, except this pattern creates a clone of the object it's attached to. So, this is less of a factory and more like a daisy chain creating itself. Another way this could be looked at, without going into too much detail, is that it mimics Unity's own prefab system (https://docs.unity3d.com/Manual/Prefabs.html). With Unity's prefab system, you can drag and drop one game object to instantiate another. The difference with Prototype is that this is achieved through code and because of this, we could—if we wanted to—add even more code to make this pattern more intelligent compared to just instantiating an object alone.
A good example of using this design pattern is something such as an enemy spawner in a game. If we had a small army of the same enemies rushing to the player coming from the same point, then this would work well.
The following diagram shows how the Prototype design pattern works:

Let's move on to the next design pattern—Object Pool—which, this time, isn't from the gang of four but is worth mentioning as it is common and should be implemented when dealing with a large amount of game objects to save system resources.
Object Pool
This design pattern is more of a good practice tool, rather than an actual design pattern; however, it's recognized like one. Let's jump into an example to explain.
Imagine you are creating a game for a mobile device and you want your game to support as many types of mobile devices as possible, even the really old phones that aren't very powerful. Your game consists of lots of bullets being fired across the screen. A typical way of making bullets fire would be to instantiate them, and when they leave the screen or hit an enemy, the bullet plays an exploding animation, makes a sound, and then destroys itself as it isn't required anymore. This applies to every bullet fired. Well, what if I told you all that you needed was 10 bullets in total and none of these bullets would be destroyed? This is the idea behind Object Pool; the bullets can be outside the game view where the player can't see them. When the player fires the bullet, the first bullet is moved into position next to the player, then when the bullet makes contact, it plays its exploding animation, makes its sound, and moves off the screen with the other nine bullets. This saves your mobile device resources as it's only dealing with 10 bullets, or however many the player can fire on the screen, at once.
The following diagram shows how the Object Pool design pattern works:

Let's move on to the last design pattern, which is also not from the gang of four but again is common enough to talk about.
Dependency Injection
This pattern is oftenimplemented with general C# applications and website development where you have the option of using constructors to set up each class. Unity doesn't really like using these constructors (https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/constructors) due to inheriting monobehaviour (which comes automatically with every newly created Unity script— see https://docs.unity3d.com/ScriptReference/MonoBehaviour.html for more information). You can, of course, remove monobehaviour, but then you start losing a large amount of functionality with Unity. But the point of Dependency Injection is that you can have classes to do different things because they have received data from abstraction.
I have seen this design pattern mentioned in the exam, so I'll give you a brief overview of this design and its relationship with Unity from my perspective. Even though you will see more of an emulated version of the design, it would be good to mimic it for Unity projects. It's about understanding how far you can spread your code into separate dependencies, driving each class instead of clustering a bunch of properties into one script. The benefit of doing something like this introduces flexibility with your code without having a knock-on effect on other properties.
The following diagram shows how Dependency Injection simply supplies one object to another:

Elements of this design are implemented in the project and are referenced as a Dependency Injection pattern in practice.
This was a sample of all the many design patterns out there that can make you stand out from the rest of the Unity programmers. From my experience at university and from progressing through Unity programmer roles, these patterns aren't used enough. However, if you understand them (as you will in these projects), log them so you don't forget, and whenever you start or join a project, think of what patterns go into the roles you choose or are given. It's very tempting to just jump in and start coding, but this is where you might run into dead ends or oversized classes.
Let's move on and look at the SOLID principles of coding. I have mentioned them briefly a couple of times, so consider them a guideline to what makes a good programmer.
- 數(shù)據(jù)庫系統(tǒng)原理及MySQL應(yīng)用教程(第2版)
- Vue.js設(shè)計(jì)與實(shí)現(xiàn)
- The DevOps 2.3 Toolkit
- 潮流:UI設(shè)計(jì)必修課
- SQL學(xué)習(xí)指南(第3版)
- Ext JS Data-driven Application Design
- 機(jī)器人Python青少年編程開發(fā)實(shí)例
- oreilly精品圖書:軟件開發(fā)者路線圖叢書(共8冊(cè))
- Linux網(wǎng)絡(luò)程序設(shè)計(jì):基于龍芯平臺(tái)
- 碼上行動(dòng):用ChatGPT學(xué)會(huì)Python編程
- Qt5 C++ GUI Programming Cookbook
- OpenCV Android Programming By Example
- Manage Your SAP Projects with SAP Activate
- 計(jì)算機(jī)常用算法與程序設(shè)計(jì)教程(第2版)
- Python 3.8編程快速入門