I am designing my game with Entity/Component concepts of GameplayKit in iOS 9, for ShootComponent, should define bullet/missile as Entity?
Reason for Yes:
separate logic from its parent, e.g. playerTank or enemyTank;
if not, TankEntity need distinguish whether its bullet collide with other Entities or itself.
Reason for No:
it is not actual entity in logic world, which is fired by my tank or enemy turret;
bullet always be shot and disappeared, so game need add/remove it now and then;
For your comments pls.
Finally decided to define bullet/missile as entity, so it acts as entity in contact test, rendering and other components.
I would have add it as a component for the entity using it.
So you will be able to make any entity fire bullet or missile.
Keep in mind that your entity should only act as a simple reference with no logic in it.
First lets read Adam Martins original description of his terms. It appears Apple got the idea of entities and components from Martin:
Entity: The entity is a general-purpose object. Usually, it only consists of a unique id.
Component: the raw data for one aspect of the object, and how it interacts with the world.
System: "Each System runs continuously (as though each System had its own private thread) and performs global actions on every Entity that possesses a Component or Components that match that Systems query."
Martin is just defining terms for doing compositional design, which is an alternative to inheritance that is more recombinable and flexible.
So entities are what you might recognize as instances of a class, but classes have been stripped of all their data and methods, which has been moved out into components - and the entities just delegate to the components.
So your missile... it would be an instance of a class in normal OO terms - an object, right? And a missile can behave in a variety of ways... it can seek out an enemy, it can fly straight ahead, it can speed up, etc. It also has properties that indicate if it's hit an enemy, properties for its total damage, health, and so on.
So the missile is an entity while these various methods / data would be components of the missile entity.
Martins approach is interesting, and there hasn't been as much focus on compositional design as there has been OO (for what reason I don't really know), so I can see why Apple would adopt it for a game framework like this.
But his ideas don't seem very well fleshed out. For example, usually in compositional design there is a delegation hierarchy, where objects will keep delegating up a chain until some data or method is found. At the top there's one meta-object that everything delegates to. In this way objects are both components and entities - they act as both the delegating and the delegated to. But Martins terms don't support this... his model is flat - there are only entities, and then components that can be added to them, but no delegation between entities and no meta-object.
Maybe he felt this flat design was appropriate for game development. I have my doubts... you seem to want some kind of hierarchical structure of objects. I would look for a way to mix in inheritance, or setup some kind of custom delegation hierarchy where objects could act as both entities and components. You might look to see if this is possible within that framework, or if it isn't just write your own.
Related
We want a chair class for a game.
How can we create this class so that it can work in another game too?
And by considering the solid principles.
Imagine for example, that we have 2 games: one is a poker game, another is a grand theft auto like game. In the poker game the class should have an id, playersited() : player , state : full , empty , reserved. I can think of these properties right now. But in the second game, the chair doesn't necessary need an id or a playersited() function. So how can I design this class that can be reused in another games?
You are looking for a generic game object that you could reuse in different games, but which might have different properties and different functions depending on the game.
Simple UML answer
If you're only looking at it from the UML perspective only, this design issue is simple: draw a class GameObject, put in it the properties and operations that you want to be common. Then in the model of your different games, just create a a specialisation using inheritance: PokerObject and GrandCloneObject in which you'd add the game specific properties and operations.
But this apparent simplicity would hide a lot of difficult points when you start to design links with other classes (reusable or not), and even more when you start to look at their interactions.
Limitations of such a generic design
In addition you want a SOLID design. The LSP will then reduce the reusability by forcing you to keep the reusable interaction between objects to rely only on common part.
If only 10% of the design is then really reusable in the end, and 90% is game specific, you'll gain no advantage and just make the code more complex by splitting classes artificially. Here I'd joint #kigiri's comment: "JUST DON'T"
A better approach
But if you're looking for is something really reusable at a higher scale, there is a solution if you look not at a Chair, "Weapon", "Item", but at a higher level of abstraction.
And here, I can only recommend you to read Mike McShaffry's Game Coding Complete book, that will introduce you a very powerful architectural pattern called the Entity Component System.
The Idea is to abandon deeply nested class hierarchies wiht very specific classes, but prefer a very flat model with:
Entities: these are the main objects used in the game, whatever the game is
Components: these are owned by the Entities, and represent either properties that an entity can have (e.g. LivePoints, Force, ...), or behaviors that the Entity shall have (e.g. renderFixedObject, soundWhenClicked, etc..).
This design allows to develop highly reusable objects allowing to add game specific components on the top of reusable entities and components.
I am trying to understand how to classify the classes as boundary/control/entity classes. I can understand boundary and entity classes although my understanding may not beperfect. Boundary is the classes which interacts with the user. So the classes used for the userinterface will be boundary classes. Entity class handles data. So entities I use in the ER diagram will be entity classes. But I understand nothing why control object is used. It is said that control object is used to encapsulate domain functionalities. What if the control classes are not used. Can you please explain me with example.I found some explaination but I am still confused.Why boundary should not interact directly with entity? There are also classes which are not boundary/control/entity. What are they?
Background
The Entity/Boundary/Control approach was introduced by Ivar Jacobson in 1992 as part of his use case driven Objectory development method.
At that time Jacobson used the terminology Entity/Interface/Control. The strange circle notation that you can find in relaction with ECB was already used in his books in 1992 and in 1994. By the way, the use case of his methods were integrated into UML and his development process was merged into RUP, when Rational acquired Objectory.
The idea behind his method was to adopt a very logic and formal and deductive analysis and design approach. It starts with identifying the systems behavioral requirement with use cases. Each link of use case to the outside world would then be represented as an interface object responsible for encapsulating completely the user interface.
Each use case would be represented as one or several control objects:
Control object: An object that encapsulates functionality of one or
several use cases - I.Jacobson in The Object Advantage, ACM Press, 1994
Finally the business objects managed by the system can be partly inferred from the use cases, and during the analysis.
Additional information
The fundaments of the Iconix process were introduced in 1999 as part of the book "Use Case Driven Object Modeling with UML" by Rosenberg & Stephen. Some additional robustness constraints were introduced, certainly to improve separation of concerns. For example, the direct link between entity and boundary is prohibited. Everything has to be channelled through control objects:
Control objects (which we usually call controllers because they often
aren't real objects), serve as the "glue" between boundary objects and
entity objects - D.Rosenberg, in the linked DDJ article.
They add a recommendation to clarify the intent :
Both boundary objects and entity objects are nouns, and controllers
are verbs.
Conclusion
So the principle is that the control object represents the business logic offered by use cases, interacting on one side with the boundaries, and on the other side with the entities. Control objects can't be invoked/accessed directly by the outside world.
If you would want to avoid the control objects, you would have a boundary objects with methods corresponding to the verbs/functions/use-cases that your system is supposed to provide. This wouldn't be according to the modern ECB, but perfectly valid according to Jacobson's original approach. Nevertheless your boundary would no longer comply with the single responsibility principle of a SOLID design.
Boundary interact with actors (e.g. users).
Entity classes represent data.
Control mediates between the boundary and the entities (e.g. executes an operation on the entities)
Source: http://www.cs.sjsu.edu/~pearce/modules/patterns/enterprise/ecb/ecb.htm
The control classes contain the business logic. It's the most important part of a system. While the boundary just controls whether the text is green or blue (very basically) and the entities control whether data is stored in text files or databases (also very basically) the control classes do all the business logic. What to change in the entity when the boundary send mouse/keyboard events an vice verse what to show from the entities in the boundary.
In many case, I need write a lot of class work with CRUD for some class. For example CRUD with pure object User, Book, Tag.
I usually make a directory named models, put all the CRUD classed into the models folder.
But I feel that the word model is not show essence. Is the word model well-defined in computer science? It means the pure object of User, or the means of CRUD of User?
I also use another name services for more complex logic, For example UserService may require other models than UserModel. But the word service is often conflict with some other case like an online service, backend service.
Are there any good names for the model and service in my case? BTW, I am most using Node.js; it may not conflict with the general conventions used in Node.js.
Ultimately, it will come down to what makes the code the most understandable both to you and to someone down the road who may have occasion to work on your code. If 'model' and 'services' convey the thought of what lies within in an obvious way to anyone coming in to the code, then they are probably fine. As far as standards, I don't know if there is a 'defined' set of names you have to use. In MVC, for example, you will use 'Models' as one of your folders in order to store all of the actual models you will be feeding your views, and this is understood in the MVC architecture that those names (Models, Views, Controllers) are the standard.
I agree with you that Model is a little ambiguous. Sometimes it is used to indicate domain objects such as User/Book/Tag, but sometimes it is used to indicate objects that deal with business logic, such as "Buying a book","Authenticating a user".
What's common to both uses is that "Model" is clearly separated from UI, that is handled entirely by the Views and the Controllers.
Another useful name is Entities. In Robert Martin's work on Object Oriented Design, he speaks of use-case-driven design, and distinguishes between three kinds of objects: Entity Objects, Interactor objects and Boundary objects.
Entity objects are useful in multiple use-cases. For example, in a book selling system, entities can be Book/User/Recommendation/Review.
Interactor objects implement use-cases, and they typically use multiple entity objects. For example, Purchase_Book/Login/Search_Books can be such objects.
Boundary objects are used for transferring data across module boundaries, and are used for building interfaces between parts of the system, which should be decoupled from one-another. For example, a controller may need to create a Purchase_Book object, and in order to create it, it needs to pass data about what book ID needs to be purchased, by what user ID, etc... and this data can be packed in a boundary object called Purchase_Request.
While Interactor and Boundary require more explanation, I find that the word Entities is meaningful and can be grasped intuitively without reading any explanation.
When you are developing an architecture in OO/DDD style and modeling some domain entity e.g. Order entity you are putting whole logic related to order into Order entity.
But when the application becomes more complicated, Order entity collects more and more logic and this class becomes really huge.
Comparing with anemic model, yes its obviously an anti-pattern, but all that huge logic is separated in different services.
Is it ok to deal with huge domain entities or i understand something wrong?
When you are trying to create rich domain models, focus entities on identity and lifecyle, and thus try to avoid them becoming bloated with either properties or behavior.
Domain services potentially are a place to put behavior, but I tend to see a lot of domain service methods with behavior that would be better assigned to value objects, so I wouldn't start refactoring by moving the behavior to domain services. Domain services tend to work best as straightforward facades/adaptors in front of connections to things outside of the current domain model (i.e. masking infrastructure concerns).
You can also put behavior in Application services, but ask yourself whether that behavior belongs outside of the domain model or not. As a general rule, try to focus application services more on orchestration-style tasks that cross entities, domain services, repositories.
When you encounter a bloated entity then the first thing to do is look for sets of cohesive set of entity properties and related behavior, and make these implicit concepts explicit by extracting them into value objects. The entity can then delegate its behavior to these value objects.
Since we all tend to be more comfortable with entities, try to be more biased towards value objects so that you get the benefits of immutability, encapsulation and composability that value objects provide - moving you towards a more supple design.
Value objects enable you to incorporate a more functional style (eg. side-effect-free functions) into your domain model and thus free up your entities from having to deal with the complexity of adding complicated behavior to the burden of managing identity and lifecycle. See the pattern summaries for entities and value objects in Eric Evan's http://domainlanguage.com/ddd/patterns/ and the Blue Book for more details.
When you are developing an architecture in OO/DDD style and modeling
some domain entity e.g. Order entity you are putting whole logic
related to order into Order entity. But when the application becomes
more complicated, Order entity collects more and more logic and this
class becomes really huge.
Classes that have a tendency to become huge, are often the classes with overlapping responsibilities. Order is a typical example of a class that could have multiple responsibilities and that could play different roles in your application.
Given the context the Order appears in, it might be an Entity with mutable state (i.e. if you're managing Order's commercial condition, during a negotiation phase) but if you're application is managing logistics, an Order might play a different role: and an immutable Value Object might be the best implementation in the logistic context.
Comparing with anemic model, yes its
obviously an anti-pattern, but all that huge logic is separated in
different services.
...and separation is a good thing. :-)
I have got a feeling that the original model is probably data-centric and data serving different purposes (order creation, payment, order fulfillment, order delivery) is piled up in the same container (the Order class). Can't really say it from here, but it's a very frequent pattern. Not all of this data is useful for the same purpose at the same time.
Often, a bloated class like the one you're describing is a smell of a missing separation between Bounded Contexts, and/or an incomplete Aggregate separation within the same bounded context. I'd have a look to:
things that change together;
things that change for the same reason;
information needed to fulfill behavior;
and try to re-define aggregate boundaries accordingly. And also to:
different purposes for the application;
different stakeholders;
different implicit models/languages;
when it comes to discover the involved contexts.
In a large application you might have more than one model, thus leading to more than a single representation of a single domain concept, at least for concepts that are playing many roles.
This is complementary to Paul's approach.
It's fine to use services in DDD. You will commonly see services at the Domain, Application or Infrastructure layers.
Eric uses these guidelines in his book for spotting when to use services:
The operation relates to a domain concept that is not a natural part of an ENTITY or VALUE OBJECT.
The interface is defined in terms of other elements in the domain model
The operation is stateless
For instance: link
Is the above Ok or it would be better to create more methods in Controller that handle the data that are sent/retrieved without the interaction between UI and the Entity?
In general when is it allowed (if it is) for a Boundary Class to interact with an Entity Class?
Depends on whether you want/need to stick religiously to the Boundary-Control-Entity pattern:
If yes (you do need to stick to the pattern): then no, the Boundary object can only speak to Control objects. See table at bottom of this page (also a good description of pattern).
If no: then yes it can!
That's not meant to be glib. It's questionable whether such strict separation is good design practice. It looks nice in pictures: Boundary, Control and Entity in nice horizontal layers with messages passing adjacent layers only.
The reality is rather different. Strict separation can lead to two problems:
A proliferation of pass-through methods. You allude to this. You end up with an amalgamation of methods on the controllers that do nothing more than pass through to the underlying entities.
Anaemic Entity classes. Rather than the Entities being home for data + behaviour, they become data containers only with all behaviour migrating out to controllers. That's not a good thing.
It's notable that in Domain Driven Design, Eric Evans recommends creating Services (akin to Controllers) only when the logic in question doesn't have a viable home in any of the Domain Classes (Entities).