Class Naming, Should I ,name a class and make an attribute or put that attribute into the classes name - class-design

I'm trying to understand the considerations people use to name classes. What are the ways in which you decide between the following.
student = Student.new(:smart)
vs simply using
student = SmartStudent.new
Edit:
I guess there is really no right or wrong answer its just the way I need to decide what I am modeling.

In general I like to name classes at the most general form of the noun that they represent. So in your example the noun is Student. smart is an adjective describing that noun. the adjective represents a Student's intelligence. so my attrribute would be intelligence.
That way I could have:
Bill = new Student
Bill.intelligence = smart
Bob = new Student
Bob.intelligence = stupid

You should ask your self: does the student's attributes make a student really different from another?
If not and if it is possible, I'd suggest you to use the first solution you proposed. Generally is simpler that deploying a hierarchy of student types (see composition vs inheritance), because if your student types grow, then your student classes may proliferate making difficult to proper handle all of them.
On the other hand, if a Smart student class has a really custom behavior, and you want to use method overriding and stuff like that to perform operations on that classes instead of checking each time the student type of that particular class, then inheritance could be an option. I would stay away from that.
You should give us more details for a correct answer. Can't say simple yes or no to your question, because it depends on your design.
EDIT:
consider also this point: can a student have more than an attribute? If that's the case you should definitively used the first approach, other could be impossible (or at least tricky) modeling a student type that has more than one attribute (example: smart and fat).

Related

ERD diagram conversion into UML diagram

I have an ERD Diagram of an E-commerce with the following entities Product , Tag , ProductTag,Category and other entities of course.
I tried to convert it into class diagram as follows:
1- removed the id
2- converted the foreign key into object of the type i'm refering to(product_id converted into => product: Product)
my question is , is this good approach to follow on all my entities? does it like achieve the SOLID principle? I have a presentation in 2 days and I want to be very sure of what I have made , any comment or modification would be really enough .I also chose these tables because they represent one to many and many to many. thanks in advance.
Basically your approach is correct. It's just a couple of UML specifications you got wrong.
The label in the middle of the connectors is just the name of the connector. Unless you do some OCL wizardry this name is meaningless. There is a way to adorn it with a black triangle to show the reading direction. This sometimes helps business people to understand how classes are related to each other (see Fig. 11.27 on p. 202 of UML 2.5). But usually you would not use it.
The shared aggregation has no semantics (p. 110 of UML: Indicates that the Property has shared aggregation semantics. Precise semantics of shared aggregation varies by application area and modeler.). So leave the open diamond away. Composite (filled diamond) can be used to show responsibility (when I'm killed I will kill my composites first). Usually it adds too little to be really useful, it only heats up the futile composition-discussion.
The navigation-direction is incorrect. The AC in the middle sees both connected classes so it's shown without any arrow. If you have an additional (directed) association you place it as lone (extra) connector. In that case put role names towards any end. That makes navigation clearer than just a simple arrow. I for myself use arrows only on rough sketches on the drawing board.
P.S. Just noticing that you have operations in your classes that have the same name as the class and take one paramter being also the class. I would guess you intend to show a constructor here. In that case you would make it Classname():Classname and provide only the paramaters that are needed for the constructor. Else these opreations don't seem to make much sense. Similarly the CRUD operations seem to work on a list of 'itself' which is also probably not desired. You would have a collection class which handles the base class where these operation make sense. So to summarize: you would only add getter/setter operations for the (private) properties matching the columns from your table.
P.P.S.: As per Christophe's comment it's a good idea to adorn the class instantiation operation with a <<create>> stereotype which highlights its purpose. See p. 196 of UML 2.5:
This stereotype is part of the standard (see p. 677) and the table on p. 678 states:
Specifies that the designated feature creates an instance of the classifier to which the feature is attached.
On the modeling part of your question, there’s already a perfect answer. For the records, I’d nevertheless like to add a complementary answer on the SOLID part:
Single responsibility: your classes have more than one reason to change, because you may want to change Product for what it is (e.g. add more product-related attributes), but you may also want to change the class to add new getByXxx() operations to find products in the database based on other criteria, independently of what a product really is. SO it's not complying.
Open-closed principle: we cannot tell
Liskov substitution principle: in absence of inheritance, this is not relevant. Moreover, you couldn't tell without having precondition, postcondition and invariant constraints.
Interface segregation principe: is probably not compliant, because you impose an implicit interface that all inheriting class would have to provide, even if they don't need it (e.g. products not stored in a database). A first step in the right direction, would be to use an interface for the common database operations.
Dependency inversion: we cannot tell but probably it isn't , because update(), delete(),... probably depends on some database, so that you can't switch it to another database. With DIP, you'd inject the database in the class that use it, so that you could at any moment inject another database that offers the same interface.
You didn't ask, but your design seems to correspond to active records. If you want to go for a cleaner, more SOLID design, you should prefer factor out the database related code to either repositories or table data gateways.

UML attribute to association class or simple class?

I'm having a difficulty figuring out where to put the Level attribute. I want the employee to have a variety of skills which have different levels. For that purpose I made a many to many relationship which is implemented as an EmployeeSkill association class.
An example of said class is as follows: An employee named Jack might have a skill of Java which is level beginner, while he could also have a skill of C# which is advanced level. Should the level be saved in the EmployeeSkill association class or in the Skill class? I suspect it should be on the association class.
A property of the association class?
Your narrative with the Employee instance "Jack" being associated with Skill instance "Java" with a level of "beginner" shows that the skill is independent of the level, and the level is related to the combination of a given employee and a given skill.
To model accurately the semantic of this narrative, level should indeed be the property of the association class EmployeeSkill.
Could it be a property of the skills?
It would not be wrong to move level as a property of Skill. But the model would have a different semantic, since every Employee associated with a Skill would share the same level. This means that "Jack" being associated to a skill like "Java" but rather a skill like Elementary Java.
This alternative model makes it also less convenient to desperately search for all employees knowing about Neural network regardless of the level. And it would not be obvious for the system to see that elementary neural network is related to advanced neural network expertise and that Advanced java has little to do with Advanced javascript.
To have the same power of expression, the skills that are related but correspond to a different level would require an explicit association, which would make the model more cumbersome to use and fragile.
Remarks that are unrelated to your question
You seem to repeat the JobCategory's and the Country's attribute within Employee. This is confusing, as the associations already associate the class with another set of each of these attributes. Did you mean the redundant attributes to implement the associations and show the db table layout than the class? If so, you should disambiguate using some custom stereotypes. But I'd rather recommend to remove the redundant items and make a comment at the bottom of the diagram to explain that you implement associations.
I wonder if the multiplicities of the association between Skill and SkillCategory are not inverted (i.e. one category can have several skills and each skill is associated with only one category) ? Or that you meant a many-to-many association if skills can belong to several categories.
In the association class you use the prefix FK to highlight the foreign keys. Use <<FK>> to make it a custom stereotype (see may first remark about using stereotypes).
As qwerty_so pointed out in the comments, you use a nesting connector for the associations with enumerations. This is syntactically acceptable but does not mean what you think. This is meant to deal with namespaces. Just remove that circle-plus symbol to make it a normal association and it will mean what you think.

Deciding on class responsibility

I know this is an opinionated question. However it comes up often at work.
When creating methods it's often a struggle to know which class should be responsible.
e.g.
bool result = ProductService.CategoryHasSoldOutOfProducts(int categoryId)
vs
bool result = CategoryService.CategoryHasSoldOutOfProducts(int categoryId)
In my opinion, the CategoryService should be responsible, as the method is taking a categoryId and is specific to the Category.
Others at my work say the ProductService should be responsible as the method is dealing with if Products have sold out.
Just trying to develop a better understanding of service architecture and good process. I'm interested in other peoples explanations for why they would choose one over the other.
Thanks
Disclaimer - this is a purely IMHO answer. I am answering this in the spirit of having a design brainstorm.
Based on the OP, it seems the relationship between Category and Product is an optional one to many : Category (0..1) <--------> (*) Product.
Implementation wise, this means that the Category entity probably has a Container of Products, and the Product entity has a reference to a Category which may be NULL.
In this case, I agree with the decision to place CategoryHasSoldOutOfProducts under the responsibility of the Category entity. The method name clearly implies that the Category entity should be responsible for informing its API user on the status of its products.
There is another option, however: An association class/entity. The motivation behind this entity is to describe the relationship between two other entities.
In this case, you can have a functional association entity which we will call ProductContainment for the sake of this example.
ProductContainment will have no internal state, and will hold functions which are provided with Category and/or Product entities as parameters.
It is then the responsibility of the association entity to provide the implementation of functions which relate to how Category and Product relate to one another.
If you end up using ProductContainment - then CategoryHasSoldOutOfProducts should be one of its functions.
Since you're asking for opinions, here is mine:
(Disclaimer: That's probably something you cannot easily implement in the business world)
As you are using the term "class", I assume you want to have something object-oriented. The problem is, a service is nothing a valid object could be created from. Instead, it's just a namespace for functions.
Additionally it's very general. It's like calling a class "Manager". You can put possibly everything inside of it and this class has the potential to grow to have hundreds of functions.
My advice: Create small entities. Small enough to be created without the use of any setters, just by calling the constructor. If you notice your object needs more functionalities, create a decorator that is a little bit smarter and can do the work for you.
I would need a few more details about your environment to be more precise, but I guess in your case, you would have something like a Category class that contains products and knows when it's sold out. Just imagine you have a team of persons and everyone knows something. Ask the right guys to do the stuff and stay away from managers or services.

How to properly express references in immutable model in Scala?

Let's say I want an immutable model, a world. How one should model references?
case class World(people: Set[Person])
case class Person(name: String, loves: Option[Person])
val alice = Person("Alice", None)
val peter = Person("Peter", Some(alice))
val myWorld = World(Set(alice, peter))
println(myWorld)
Outputs:
World(Set(Person(Alice,None), Person(Peter,Some(Person(Alice,None)))))
But now we have two separate persons named Alice (in the people set and in the peter person).
What is the best practice(s) on approaching this referencing in an immutable model in Scala?
I thought about referencing strictly through ids, but it doesn't feel right. Is there a better way? (Also current implementation doesn't support recursion/circle like A loves B and B loves A.)
I think you have to distinguish between pure values, and things that have a notion of identity that survives state changes.
A person might be something in the latter category, depending on the requirements of your model. E.g. if the age of a person changes, it is still the same person.
For identifying entities over state changes, I don't think there is anything wrong with using some kind of unique identifier. Depending on your model, it might be a good idea to have a map from person id to person state at top level in your model, and then express relationships between persons either in the person state, or in a separate data structure.
Something like this:
case class Person(name: String, age: Int, loves: Set[PersonRef])
case class PersonRef(id: Long) // typesafe identifier for a person
case class World(persons: Map[PersonRef, Person])
Note that a person state does not contain the ID, since two persons with different IDs could have the same state.
A problem with this approach is that the world could be in an inconsistent state. E.g. somebody could love a person that does not exist in the world. But I don't really see a way around this.
I think it might be worth looking at scala libraries that are confronted with a similar problem. E.g.
diode has the concept of a reference to a value elsewhere in the model
scala graph allows to define custom node and edge types.
Although alice is printed two times, it only exists as one and the same value in your example. In general, you would introduce perhaps an id field that carries a unique identifier if you want to trace the mutation of an otherwise immutable object. But here, clearly, you only have one value.
For recursive references, see this question. For example, you could use a by-name parameter.
When modelling some application domain using immutable data structures, you should not use object identity to rely on anything. Just think about how you would update an immutable model: you would generate a modified copy which would have different identity, even if it represents the same "thing". How would you ensure, that you've set all references in your model to the new, modified copy?
Thus, you have to make identity explicit: ask yourself what is the identity of something, e.g. a unique id or a set of unique attributes, e.g. for a person name, date and location of birth an so on. (Be careful though, while the real date of birth of a person never changes, the one stored in your date model might because of an error in your data set).
Then use this information to point to an object from everywhere else.
Making identity explicit requires you to think about it when you build your data model. This might feel like an extra burden but in fact it avoid a lot of trouble later on.
For example, serialization will be easy, distribution will be easy, adding some kind of versioning support will be easy and so on.
As a rule you should only use references to the same information, if this information is just the same by coincidence. If you are pointing to the same "identity" and the information at both places has to be the same, use some explicit id.

When should i use properties instead of object references?

For example if i have an Author class and a book class independently. We all know an author writes a book.
What i would love to know when it's best to include the book as a reference object in the Author class or just include the book name?
The reason for this question ties mainly to flexibility and easy maintenance.
Update:
What design pattern should i read up that relate to this type of issue?
I would generally store the reference to the book, and the book object is therefore readily accessible from the author. If you store the property (name) in this scenario, then some questions are:
is the name unique ?
is it costly to retrieve the book from the author (e.g. do you have to go to the database) ?
If you don't want the whole book object in memory (perhaps storing all authors with all their books consumes huge amounts of resource), then perhaps you want a book placeholder object referenced from the author class. That placeholder would store the book's unique key and can retrieve the book upon demand. It may implement a book interface and thus be indistinguishable from the real book. The downside is that the book still has to be populated upon, or prior to, a request for info.
The name would be a very bad idea; it's quite possible for two different books to have the same title.
I'd use an object reference (inside some sort of collection, of course, since an author can write more than one book) - that's what they're for. This is certainly flexible and maintainable.
There may be exceptional circumstances where this causes problems, and only then would I consider keeping some sort of unique ID (in the case of books, the ISBN would be the prime candidate) instead of a reference.
It really depends if author is ever going to need access to book information beyond that of just the title. If really never, then ok maybe you only need the title as a String. However, if additional book info is likely to be needed, you need to think about how you are going to access that. In this case it probably makes sense to use a book class.
Having the book name inside the author object will create duplication if a book has many authors. If somehow you need to modify the book name then you will have to go through all the authors collection in order to determine where you need to change.
Having a single book object referenced by all its authors is much simple. Just change the book name in one place and that's all.
In don't think is it easy maintainable or flexible a structure with unneeded duplicates.
EDIT: With duplication of the name you can also get to inconsistencies. Just imagine what happens if a book's titles (with two authors) gets its name modified just for one author.
It depends on what you want to do with the information. Sometimes it might be easier to have your list of book names stored in the author, other times you might need the full book information (ISBN, publisher etc.)
In a database you would have an Author table with all of their details, and a book table with all details of the book, then probably a many-to-many relationship table to tie books to authors and vice-versa.
Oh, and properties / object references aren't really mutually exclusive. A property CAN be an object reference. It sounds more like you are asking if you should store the full obejct information or just the piece you might need immediately.
Option B. Avoid having such references - it will quickly render your program into a mess of dependencies. Keep the two concepts independent, and if you need, some higher-order abstraction to link between the two.
Your question is a part of a complex saga known as "object-relational mappings", there's a lot of material on design patterns for that on the web.
Object-oriented when each object has references to its best friends – not to their names. There are certain downsides to it, like: it is notoriously hard to keep track of back-references.
However, the problem calls for a more general solution than a best-practice pattern.
As long as you're using OO to design your application at all, I'd opt to be consistent and keep direct references to your objects.
It really depends on your domain. Most book store databases have some discrepancies between names of authors between books, and no information whether a given name is shared by more than one author. So in that a book would have a list of author names, and there would be no object identity mapped to that data.
On the other hand, if your domain is a publishing house, you have a very good idea which of the authors John Smith ( client number 19024982 ), J. Henry Smith ( client number 19024982 ) and John Smith ( client number 773829 ) are the same or different authors, and which books those two authors have created, and so using object references for author and book identity would be a good mapping of the domain.