Design Patterns Apply On Soccer Engine
2016-03-20 23:39
591 查看
Design Your
Soccer Engine, and Learn How To Apply Design Patterns
(Observer, Decorator, Strategy and Builder Patterns) - Part I and II
![](http://www.codeproject.com/script/Membership/ProfileImages/{0C8813F7-34FA-4734-B085-8E07BB012691}.jpg)
Anoop
Madhusudanan, 9 Jan 2007 CPOL
![]() ![]() | 4.76 (156 votes) |
|
using patterns
Download source files - 212 Kb
Contents
Part IIntroduction
Introduction
To This Article
An
Overview Of Design Patterns
Architecting
Your (Simple) Football Engine
Identifying
Entities
Identifying Design Problems
Identifying
Patterns To Use In Your Football Engine
1:
Addressing Design Problems
Related With The 'Ball'
2:
Addressing the design problems
related with 'Team' And 'TeamStrategy'
3:
Addressing the design problems
related with 'Player'
4:
Addressing the design problems
related with 'PlayGround'
Part II
Applying
The Observer Pattern
Understanding
The Observer Pattern
Adapting
The Observer Pattern
Conclusion
![](http://www.codeproject.com/KB/architecture/applyingpatterns/Part.jpg)
Part I
Solution Architect: "But you can use patterns"Dumb Developer: "Yes, But can I get it as an ActiveX control?"
Introduction
Introduction To This Article
This article is expected toIntroduce patterns to you in a simple, human readable (?) way
Train you how to really 'Apply' patterns (you can learn patterns easily, but to apply them to solve a problem, you need real design skills)
Provide you a fair idea regarding the contexts for applying the following patterns - Builder, Observer, Strategy and Decorator (well, they are few popular design patterns)
Demonstrate you how to apply the Observer pattern, to solve a design problem
In this entire article, you will go through the following steps
You will model a very simple football game
engine
You will identify the design problems
in your football game engine
You will decide which patterns to use for solving your design problems
You will then actually use the observer pattern, to solve one of your design problem.
As a prerequisite
You may need to get some grip on reading and understanding UML diagrams
Using The Code
The related zip file includes the code, UML designs
(in Visio format) etc. After reading this article, you may download and extract the zip file - using a program like Winzip - to play with the source code.
An Overview Of Design Patterns
Even with out much knowledge about design patterns, designersand developers tend to reuse class relationships and object collaborations to
simplify the design process.
In short, "A Design pattern
consists of various co-operating objects (classes, relationships etc)". They provide
solutions for common design problems.
More than anything else, they offer a consistent idiom for designers
and programmers to speak about their design.
For example, you can tell a friend that you used a 'Builder' pattern for addressing some designspecifications
in your project.
A consistent classification of patterns for common design problems
are provided by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides [also known as the Gang of Four (GOF)]. The Gang of Four (GOF) patterns are generally considered the foundation for all other patterns.
The basic principle of using patterns is reusability. Once a problem is address some way, you are not really expected to re-invent the wheel if you properly understand the concept of pattern centric software engineering. Here are some important points to remember
about design patterns.
A Design Pattern
is not code. It is in fact an approach or a model that can be used to solve a problem.
Design Patterns
are about design and
interaction of objects and they provide reusable solutions for solving common design problems.
A Design Pattern
is normally represented with the help of a UML diagram.
Some real hands on experience with patterns may provide you a better idea!!
Architecting Your (Simple) Football Engine
You are working with a popular computer game developing company, and they made you the Solution Architect of one of their major projects - a Soccer (Football)Game Engine (Nice, huh?). Now, you are leading the process of designing
the entire Football game engine, and suddenly you have a lot of design considerations,
straight away. Let us see
How you identify the entities in your game system,
How you identify the design problems,
and
How you apply patterns to address your design specifications.
Identifying Entities
First of all, you need to identify the objects you use in your game engine.For this, you should visualize how the end user is going to use the system. Let us assume that the end user is going to operate the game in the following sequence (let us keep things simple).
Start the game
Select two teams
Add or remove players to/from a team
Pick a play ground
Start the game
Your system may have a number of PlayGrounds in it, a number of Teams etc. To
list a few real world objects in the system, you have
Player who play the soccer
Team with various players in it
Ball which is handled by various players.
PlayGround where the match takes
place.
Referee in the ground to control the game.
Also, you may need some logical objects in your game engine, like
Game which defines a football game,
which constitutes teams, ball, referee, playground etc
GameEngine to simulate a number of games at a time.
TeamStrategy to decide a team's strategy while playing
So, here is a very abstract view of the system. The boxes represent classes in your system, and the connectors depicts 'has' relationships and their multiplicity. The arrow head represents the direction of reading. I.e, a GameEngine has (can simulate) Games.
A Game has (consists of) three referees, one ball, two teams, and one ground. A team can have multiple players, and one strategy at a time.
![](http://www.codeproject.com/KB/architecture/applyingpatterns/basic_system.gif)
Fig 1 - High level view
Identifying Design Problems
Now, you should decideHow these objects are structured
How they are created
Their behavior when they interact each other, to formulate the design specifications.
First of all, you have to write down a minimum description of your soccer engine, to identify the design problems.
For example, here are few design problems
related to some of the objects we identified earlier.
Ball
When the position of a ball changes, all the players and the referee should be notified straight away.
Team and TeamStrategy
When the game is in progress, the end user can change the strategy of his team (E.g., From Attack to Defend)
Player
A player in a team should have additional responsibilities, like Forward, Defender etc, that can be assigned during the runtime.
PlayGround
Each ground constitutes of gallery, ground surface, audience, etc - and each ground has a different appearance.
So now, let us see how to identify the patterns, to address these design problems.
Identifying Patterns To Use
Have a look at the design problemsyou identified above (yes, do it once more). Now, let us see how to address these problems using design patterns.
1: Addressing the design problems
related with the 'Ball'
First of all, take the specifications related to the ball. You need to design aframework such that when the state (position) of the ball is changed, all the players and the referee are notified regarding the new state (position) of the ball. Now, let us generalize the problem
Specific Design Problem:
"When the position of a ball changes, all the players and the referee should be notified straight away."
Problem Generalized: "When a subject (in this case, the ball) changes, all its dependents (in this case, the players) are notified and updated automatically."
Once you have such a design problem,
you refer the GOF patterns - and suddenly you may find out that you can apply the 'Observer' pattern to solve the problem.
![]() Observer Pattern: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. |
2: Addressing the design problems
related with 'Team' And 'TeamStrategy'
Next, we have to address the specifications related to the team and team strategy. As we discussed earlier, when the game is in progress, the end user can change the strategy of his team (E.g., From Attack to Defend). This clearly means that we need to separatethe Team's Strategy from the Team that uses it.
Specific Design Problem: "When
the game is in progress, the end user can change the strategy of his team (E.g., From Attack to Defend)"
Problem Generalized: "We need to let the algorithm (TeamStrategy) vary independently from clients (in this case, the Team) that use it."
Then, you can chose the 'Strategy' pattern to address the above design problem.
![]() Strategy Pattern: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it. |
3: Addressing the design problems
related with 'Player'
Now, let us address the design specificationsrelated to the player. From our problem definition, it is clear that we need to assign responsibilities (like forward, defender etc) to each player during run time. At this point, you can think about sub classing (i.e, inheritance) - by creating a player class,
and then inheriting classes like Forward, Defender etc from the base class. But the disadvantage is that, when you do sub classing, you cannot separate the responsibility of an object from
its implementation.
I.e, In our case, sub classing is not the suitable method, because we need to separate the responsibilities like 'Forward', 'Midfielder', 'Defender' etc from the Player implementation. Because, a player can be a 'Forward' one time, and some other time, the
same player can be a 'Midfielder'.
Specific Design Problem: "A
player in a team should have additional responsibilities, like Forward, Defender etc, that can be assigned during the runtime."
Problem Generalized: "We need to attach additional responsibilities (like Forward, Midfielder etc) to the object(In
this case, the Player) dynamically, with out using sub classing"
Then, you can chose the 'Decorator' pattern to address the above design problem.
![]() Decorator Pattern: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub classing for extending functionality |
4: Addressing the design problems
related with 'PlayGround'
If you take a look at the specifications of Ground, we see that a ground's appearance is decided by various sub units like gallery, surface of the ground, audience etc. The appearance of the ground may vary, according to these sub units. Hence, we need toconstruct the ground in such a way that, the construction of the ground can create different representations of the ground. I.e, a ground in Italy may have different gallery structure and surface when compared to a ground in England. But, the game engine may
create both these grounds by calling the same set of functions.
Specific Design Problem: "Each
ground constitutes of gallery, ground surface, audience, etc - and each ground has a different appearance."
Problem Generalized: "We need to separate the construction of an object (ground)
from its representation (the appearance of the ground) and we need to use the same construction process to create different representations."
![]() Builder Pattern: Separate the construction of a complex object from its representation so that the same construction process can create different representations. |
![](http://www.codeproject.com/KB/architecture/applyingpatterns/Part.jpg)
Part II
Solution Architect: "I asked you to learn about patterns"Dumb Developer: "Yes, now I can develop a football engine
using patterns"
Solution Architect: "Huh? What do you mean? !@@#!"
Applying Observer Pattern
In this section, we will have a closer look at the observer pattern, and then we will apply the pattern to solve our first design problem.If you can remember, our first design problem
was,
"When the position of a ball changes, all the players should be notified straight away."
Understanding the Observer Pattern
The UML class diagram of the observer pattern is shown below.![](http://www.codeproject.com/KB/architecture/applyingpatterns/observer.gif)
Fig 2 - Observer Pattern
The participants of the pattern are detailed below.
Subject
This class provides an interface for attaching and detaching observers. Subject class also holds a private list of observers. Functions in Subject class are
Attach - To add a new observer to the list of observers observing the subject
Detach - To remove an observer from the list of observers observing the subject
Notify- To notify each observer by calling the
Updatefunction
in the observer, when a change occurs.
ConcreteSubject
This class provides the state of interest to observers. It also sends a notification to all observers, by calling the Notifyfunction in its super class (i.e, in the Subject class). Functions in
ConcreteSubjectclass
are
GetState - Returns the state of the subject
Observer
This class defines an updating interface for all observers, to receive update notification from the subject. The Observer class is used as an abstract class to implement concrete observers
Update - This function is an abstract function, and concrete observers will over ride this function
ConcreteObserver
This class maintains a reference with the subject, to receive the state of the subject when a notification is received.
Update - This is the overridden function in the concrete class. When this function is called by the subject, the
ConcreteObservercalls
the
GetStatefunction of the subject to update the information it have about the subject's state.
Adapting the Observer Pattern
Now, let us see how this pattern can be adapted to solve our specific problem. This will give you a better idea.![](http://www.codeproject.com/KB/architecture/applyingpatterns/BallObserver.gif)
Fig 3 - Solving Our First Design Problem
When we call the
[b]SetBallPosition[/b]function of the ball to set
the new position, it inturn calls the
Notifyfunction defined in the Ball class. The Notifyfunction iterates all
observers in the list, and invokes the
Updatefunction in each of them. When the Updatefunction is invoked, the observers
will obtain the new state position of the ball, by calling the
GetBallPositionfunction in the Foot ball class.
The participants are detailed below.
Ball (Subject)
The implementation of Ball class is shown below.Hide Copy Code
' Subject : The Ball Class Public Class Ball 'A private list of observers Private observers As new System.Collections.ArrayList 'Routine to attach an observer Public Sub AttachObserver(ByVal obj As IObserver) observers.Add(obj) End Sub 'Routine to remove an observer Public Sub DetachObserver(ByVal obj As IObserver) observers.Remove(obj) End Sub 'Routine to notify all observers Public Sub NotifyObservers() Dim o As IObserver For Each o In observers o.Update() Next End Sub End Class ' END CLASS DEFINITION Ball
FootBall (ConcreteSubject)
The implementation of FootBall class is shown below.Hide Copy Code
' ConcreteSubject: The FootBall Class
Public Class FootBall
Inherits Ball
'State: The position of the ball
Private myPosition As Position
'This function will be called by observers to get current position
Public Function GetBallPosition() As Position
Return myPosition
End Function
'Some external client will call this to set the ball's position
Public Function SetBallPosition(ByVal p As Position)
myPosition = p
'Once the position is updated, we have to notify observers
NotifyObservers()
End Function
'Remarks: This can also be implemented as a get/set property
End Class ' END CLASS DEFINITION FootBall
IObserver (Observer)
The implementation ofIObserverclass is shown below. This class provides interface specifications for creating
Concrete Observers.
Hide Copy Code
' Observer: The IObserverClass
'This class is an abstract (MustInherit) class
Public MustInherit Class IObserver
'This method is a mustoverride method
Public MustOverride Sub Update()
End Class ' END CLASS DEFINITION IObserver
Player (ConcreteObserver)
The implementation of Player class is shown below. Player is inherited fromIObserverclass
Hide Shrink
![](http://www.codeproject.com/images/arrow-up-16.png)
Copy Code
' ConcreteObserver: The Player Class
'Player inherits from IObserver, and overrides Updatemethod
Public Class Player
Inherits IObserver
'This variable holds the current state(position) of the ball
Private ballPosition As Position
'A variable to store the name of the player
Private myName As String
'This is a pointer to the ball in the system
Private ball As FootBall
'Update() is called from Notifyfunction, in Ball class
Public Overrides Sub Update()
ballPosition = ball.GetBallPosition()
System.Console.WriteLine("Player {0} say that the ball is at {1},{2},{3} ", _
myName, ballPosition.X, ballPosition.Y, ballPosition.Z)
End Sub
'A constructor which allows creating a reference to a ball
Public Sub New(ByRef b As FootBall, ByVal playerName As String)
ball = b
myName = playerName
End Sub
End Class ' END CLASS DEFINITION Player
Referee (ConcreteObserver)
The implementation of Referee class is shown below. Referee is also inherited fromIObserverclass
Hide Copy Code
' ConcreteObserver: The Referee Clas
Public Class Referee
Inherits IObserver
'This variable holds the current state(position) of the ball
Private ballPosition As Position
'This is a pointer to the ball in the system
Private ball As FootBall
'A variable to store the name of the referee
Private myName As String
'Update() is called from Notifyfunction in Ball class
Public Overrides Sub Update()
ballPosition = ball.GetBallPosition()
System.Console.WriteLine("Referee {0} say that the ball is at {1},{2},{3} ", _
myName, ballPosition.X, ballPosition.Y, ballPosition.Z)
End Sub
'A constructor which allows creating a reference to a ball
Public Sub New(ByRef b As FootBall, ByVal refereeName As String)
myName = refereeName
ball = b
End Sub
End Class ' END CLASS DEFINITION Referee
Position Class
Also, we have a position class, to hold the position of the ball.Hide Copy Code
'Position: This is a data structure to hold the position of the ball Public Class Position Public X As Integer Public Y As Integer Public Z As Integer 'This is the constructor Public Sub New(Optional ByVal x As Integer = 0, _ Optional ByVal y As Integer = 0, _ Optional ByVal z As Integer = 0) Me.X = x Me.Y = y Me.Z = Z End Sub End Class ' END CLASS DEFINITION Position
Putting It All Together
Now, let us create a ball and few observers. We will also attach these observers to the ball, so that they are notified automatically when the position of the ball changes. The code is pretty self explanatory.Hide Shrink
![](http://www.codeproject.com/images/arrow-up-16.png)
Copy Code
'Let us create a ball and few observers
Public Class GameEngine
Public Shared Sub Main()
'Create our ball (i.e, the ConcreteSubject)
Dim ball As New FootBall()
'Create few players (i.e, ConcreteObservers)
Dim Owen As New Player(ball, "Owen")
Dim Ronaldo As New Player(ball, "Ronaldo")
Dim Rivaldo As New Player(ball, "Rivaldo")
'Create few referees (i.e, ConcreteObservers)
Dim Mike As New Referee(ball, "Mike")
Dim John As New Referee(ball, "John")
'Attach the observers with the ball
ball.AttachObserver(Owen)
ball.AttachObserver(Ronaldo)
ball.AttachObserver(Rivaldo)
ball.AttachObserver(Mike)
ball.AttachObserver(John)
System.Console.WriteLine("After attaching the observers...")
'Updatethe position of the ball.
'At this point, all the observers should be notified automatically
ball.SetBallPosition(New Position())
'Just write a blank line
System.Console.WriteLine()
'Remove some observers
ball.DetachObserver(Owen)
ball.DetachObserver(John)
System.Console.WriteLine("After detaching Owen and John...")
'Updating the position of ball again
'At this point, all the observers should be notified automatically
ball.SetBallPosition(New Position(10, 10, 30))
'Press any key to continue..
System.Console.Read()
End Sub
End Class
Running the project
After running the project, you'll get the output as![](http://www.codeproject.com/KB/architecture/applyingpatterns/output.gif)
Conclusion
Patterns can be classifiedWith respect to purpose.
With respect to scope.
With respect to purpose, patterns are classified to Creational, Structural and Behavioral. For example,
The Observer pattern we just learned is a behavioral pattern (because it help us model the behavior and interactions of objects)
The Builder pattern is a creational pattern (because it details how an object can
be created in a particular way) and so on.
Here is the complete classification diagram.
I hope this article
May help you to understand how to use design patterns.
May help you some way to apply patterns in your projects
May help you to give a brief talk about patterns to your friends
![](https://codeproject.global.ssl.fastly.net/script/Forums/Images/smiley_smile.gif)
And finally, if you have strokes in your head (a sign of great programmers
![](http://www.codeproject.com/script/images/smiley_smile.gif)
) - I'll recommend
an Art Of Living Part I workshop for you (See http://www.artofliving.org/courses.html ). It is an
interactive workshop of 18 hours spread over 6 days. As it did for me, I hope that it may help you to find the right balance between your work and life - to improve the clarity of your mind, and to improve the quality of your life. You can get in touch with
them here - http://www.artofliving.org/centers/main.htm
Some Other Articles I wrote:
Toread Second Part Of This Article, Click Here >>
Also, here is an article about Applying Provider Pattern - http://www.codeproject.com/useritems/providerframework.asp
Here are some other popular articles I wrote.. You may refer them to see some patterns in action.
![](https://codeproject.global.ssl.fastly.net/script/Forums/Images/smiley_smile.gif)
BrainNet Neural Network Library - Part I To
3 - Learn Neural Network Programming step by step And Develop a Simple Handwriting Detection System
If you want to understand VB code better, try reading this article I wrote..
VB.NET Tutorial - Learning VB.NET in a very easy
manner.
Also, you can visit my own website at http://amazedsaint.blogspot.com/ for
more articles, projects and source code
Also, you may view my tech-bits blog , download
my opersource projects , or even have look at my intuitions blog
Thanks a lot
![](https://codeproject.global.ssl.fastly.net/script/Forums/Images/smiley_smile.gif)
History
"History may make you realize that life is just a play"Nov 07,2005 - Prepared this article for publishing
License
This article, along with any associated source code and files, is licensed under TheCode Project Open License (CPOL)
相关文章推荐
- iOS定位原理和使用建议(转)
- Android中设置按钮监听事件
- Android——Activity恢复用户用EditText输入的数据
- Swift语言学习笔记(3)
- Android——保存和恢复用户状态
- Android菜鸟App开发,第一个App(第一天)
- 关于APP分层简单框架思路
- QQ也可以和微信一样只能共同好友见评论
- Retrofit2的简单应用与封装
- 线程间通信 1全局变量2当前主对话框指针3发消息方式4 AfxBeginThread的返回值(为CWinThread类型的指针)5AfxGetApp
- Android进阶之线程池
- JNI的使用和注意事项
- Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant)
- Android 应用界面开发笔记 自定义控件与Handler -待更新
- Android5.x 新控件之RecyclerView使用总结
- iOS中Cookie的使用
- 一个强大的Android模拟器Genymotion
- android捕获ListView中每个item点击事件
- android 中theme.xml与style.xml的区别
- APP的启动