Compliance with BEM specifications - specifications

Does this code violate the BEM specification or is it a "mix?
<button class="corp-info__button-read-more button">Read More</button>
It's the class button that interests me.

In principle it's not a problem. However:
You might want to place the button class (it seems to define the more general styles) first and corp-info__button-read-more second (seem to represent the more specific styles).
Always order bem classes from general to specific in your class attribute.
Also maybe you want (although it's advice you didn't ask for) to distinguish between corp-info__button and a respective modifier corp-info__button--read-more.
In orthodox BEM a single dash has no semantic meaning, therefore --read-more is simply a modifier name.

Related

How to define a class whos only role is to perform an action

This is a question about the definition of a class.
Of course I have read the endless examples on the Internet of what should be called a class. I have read that it is all the verbs and nouns that make up a thing. I understand the concept of a car class with properties like size, colour, and methods like drive
I also understand the idea that a class should have only one responsibility and adhere to the other SOLID principles
My problem relates to a program I have developed.
The responsibility of the program is to extract all the similar words from a document. It is therefore not a 'noun' like a car or animal but a verb type class I suppose.
In order to do this the program iterates through a folder of text files, extracts all the text, splits the text up by line and then 20 characters, compares each of the chunks in one file to all of the others by similarity, keeps only the words that are similar between two files, cleans the words to get rid of various characters and then added the words to a text file and repeats this for all the files in the folder.
So I have one responsibility for the class and I have written methods for each of the phrases between the commas.
Having read more about class design then it could to me that some of these methods might be classes in their own right. If a class is defined by having a single responsibility then presumably I could define more classes instead of these methods. E.g. why don't I have a class to find word similarity with only one method....
So my question is how do I define a class on a single responsbility basis if a method also has a single responsibility and the class doesn't define a thing but more of an action. What are the boundaries of what defines a class?
Please no...'Have you read'...because I have read them all. A simple explanation with a well illustrated example (conceptual example is fine)
The term "single responsibility" is very nebulous. I find it much easier to think of it in terms of cohesion and coupling. In short, we have to get things that tend to change together (i.e. are strongly cohesive) into one class and things that don't (i.e. are loosely coupled) into separate classes.
In practice that means things that tend to work with the same "data" belong to the same class. This can be easily enforced if data does not leave the object. Even more pragmatically that means avoiding "getter" methods that return data from an object.
Regarding your problem. You're saying it's not a noun, but only because you don't think of it that way. What is your "business logic"? To collect SimilarWords from a Document. Both are nouns. Your phrases are all about what steps should be taken. Rethink your application in terms of what things are involved and what actions those things would be able to do for you.
Here is a short/incomplete design for the things you describe:
public interface Folder {
public SimilarWords extract();
}
Meaning: I want to extract SimilarWords from a Folder.
public interface TextFile {
public void chunk(Consumer<Chunk> chunkConsumer);
}
Meaning: TextFile chunks the text.
public class Comparison {
public Comparison(TextFile file1, TextFile file2);
public SimilarWords extract();
}
Meaning: Two TextFiles are compared where the SimilarWords come from. You didn't use the word "Comparison" explicitly, I made that up.
And of course SimilarWords need to be added together for all file pairs (?) and then written to some output:
public interface SimilarWords {
public SimilarWords add(SimilarWords other);
public void writeTo(OutputStream output);
}
So that would be a proper OO design. I didn't catch all the details of your domain, so this model may be not exactly what you want, but I think you get the point.
Let's think a little about both your problem, problems in general, and SRP.
SRP states that a class should be concerned with one thing. This doesn't mean exactly to have a single method that does only one thing.
Actually this can be applied outside OOP too: a function should do only a single thing.
Now imagine your program has to implement 200 features. Imagine they are so simple that a single function is enough to implement any feature. And suppose you are using only functions. By the same principle you have to write (at least) 200 functions. Now this is not so great as it looks. First you program structure looks like an endless list of micro-sized pieces of code. Second if they are micro-sized, they can't do much by themselves (this is not bad per see). As you suspected a feature doesn't usually map to a single function in real world. Third if they do almost nothing, they have to ask everything to someone else. Or someone is doing that somewhere else. So there is some place where a function, or a class, is calling all the others. That place centralizes a lot of knowledge about the system. It has to know about everything to be able to call everyone. This is not good for an architecture.
The alternative is to distribute the knowledge.
If you allow those functions or classes to do a little more, they ask less things to others, some of those things are solved locally. Let me guess. As all this classes are in the same application, some of them are related to each other. They can form a group and collaborate. Maybe they can be the same class, or inherit from others. This reduces communication paths. Communication becomes more local.
Comunication paths matter. Imagine there are 125 persons in your company, and the company needs to take collective decisions. Would you do a 125 people meeting, or you group people say in 5 groups, each with 5 teams of 5 people and have small meetings instead, and then the team and group leaders meet themselves? This is a form of hierarchy or structure that helps things.
Can you imagine the fan-in and fan-out in the new structure? 5/5/5 is much better than 1/125.
So this is about a trade-off. You are exchanging communication paths by responsabilities. What you want in the end to have a reasonable architecture, with knowledge distributed evenly.

Offers is not included as a property of thing on Schema.org

I am reading up on Schema.org to be able to add the markup to a website I am working on. However, I'm already running into something I don't understand.
In the example for Product, it shows you should have a div whose itemprop is of type offers, but in the Product definition at http://schema.org/Product, I don't see offers as a property of Product at all.
If you look at http://schema.org/offers, it says offers is a property of Thing, but I don't see offers listed as a property of Thing at http://schema.org/Thing. What am I misunderstanding here?
Product does define the offers property. If you don’t see the offers property in the first table on that page (under the table heading "Properties from Product"), you are probably affected by a (known) bug. It typically works again when reloading the page later.
offers doesn’t have Thing as domain (but: AggregateOffer, CreativeWork, Event, MenuItem, Product, Service, Trip). If you are referring to the line "Thing > Property > offers", it doesn’t mean that the offers property is defined for/at Thing, it means that the offers property is a Thing. You can ignore that detail. What matters is the domain ("Used on these types") and the range ("Values expected to be one of these types") of a property.
It's perhaps worth highlighting the distinction between "types" and "properties". The vocabulary is a hierarchical taxonomy of the tangible and intangible things around us, which it calls types. In microdata, these use the itemtype attribute.
Properties describe the attributes of and relationships between the types, and in microdata use the itemprop attribute.
So, the type Product has the property offers (it's definitely there, you must be missing it1). A product can offer various things, one of which is the possibility of having some right to own or use it, which is described by the type Offer.
The property offers is indeed a property of Thing, but Thing is at the very top of the taxonomy, i.e. everything the ontology describes is a "thing", tangible or otherwise. So Thing is then broken down into more specific types of things:
Thing
- Intangible
-- Offer
-- Property
--- offers
So offers is a Thing like you and I are things — it's true, but we could be a lot more specific. In this case, offers is a property of the type Property, which in turn is a a more specific type of Intangible, which is a Thing.
1 Image of "offers" property under /Product:

What does slash before a Class name mean

A Class has slash at front and is an Abstract. I have seen derived attributes in class with slash at the beginning but I don't know what does it mean when we have slash before a Class name.
The only mention of a slash in front of a classifier name in the UML2 spec concerns interfaces of components. In ch. 8.3.1, p. 155:
Interfaces that are exposed by a Component and notated on a diagram, either
directly or through a port definition, may be inherited from a supertype
component. These interfaces are indicated on the diagram by preceding the name
of the interface by a forward slash.
This seems unlikely to be the case in your example however. So my best guess would be that it's some non-normative use. Apparently some people use a slash to indicate the classifier to be an interface. But again, that's non-normative - the correct presentation would be using the «interface» keyword.
I think you kind of answered this yourself. A slash in front of an attribute means that the attribute is derived. The value of a derived class is calculated from the value of other base classes in the diagram.
This is sometimes denoted by an operation like convertToDC():DerivedClass listed in the object to send information from the base class to the derived class.
Here's a little more information that might help you out.
A slash in front of a class name is imo not allowed by the UML spec. So this seems to be an error. You should ask the author of the diagram (or tool which created it) about the slash.
(Regarding the derived attributes you are correct. But they are not defined by the superclass but a computation rule.)

Should naming of methods within interfaces be concrete or abstract?

Often when I create new classes, I first create a new interface. I name the methods of my interface exactly as I would like them to behave. A colleague of mine prefers to have these method names being more abstract, ie: areConditionsMet(). The reason, he wants to hide the 'implementation details'.
IMO implementation details are different from the expected behavior. Could anyone perhaps give more insight. My goal is to reach a common ground with my colleague.
Your method names should describe what the method does, but not how it does it. The example you gave is a pretty poor method name, but it's better than isXGreatherThan1AndLessThan6(). Without knowing the details about what it should do, I would say that it should be specific to the problem at hand, but general enough that the implementation could change without affecting the name itself, i.e., you don't want the name of the method to be brittle. An example might be isTemperatureWithinRange() - that describes what I'm checking but doesn't describe how it's accomplished. The user of the method should be confident that the output will reflect whether the temperature is within a certain range -- whether this is supplied as an argument or defined by the contract of the class, is immaterial.
Interfaces should represent some behavior or capability and not the way it is to be accomplished. Users of interfaces should not be interested in the way a target is achieved, they just want to know its done.
Implementation issues should not be included within the name of methods for that exact reason. The name of the table updated as a result of this method or the technology used has nothing to do in your domain object's method's name.
However from your question it is hard to say what is the exact case at hand.
If you could provide more details perhaps i could provide an additional help.
The names of your interface methods should leave the user of the interface in no doubt about what the method proposes to do from a functional perspective. If the implementation matches that, well and good.
Based on your updated comments:
Sounds to me like you need two methods: isModified() and hasProperties(). Leave it up to the user (or higher layer) of the domain object to determine if a particular criteria is fulfilled.
An interface should also be designed with the view that after it is released it will never be changed. By saying isDomainObjectModifiedAndHasProperties() you are setting in concrete that this is the criteria of fullfilment (regardless of any future unforseen implementation).

Is the word "Helper" in a class name a code smell?

We seems to be abstracting a lot of logic way from web pages and creating "helper" classes. Sadly, these classes are all sounding the same, e.g
ADHelper, (Active Directory)
AuthenicationHelper,
SharePointHelper
Do other people have a large number of classes with this naming convention?
I would say that it qualifies as a code smell, but remember that a code smell doesn't necessarily spell trouble. It is something you should look into and then decide if it is okay.
Having said that I personally find that a name like that adds very little value and because it is so generic the type may easily become a bucket of non-related utility methods. I.e. a helper class may turn into a Large Class, which is one of the common code smells.
If possible I suggest finding a type name that more closely describes what the methods do. Of course this may prompt additional helper classes, but as long as their names are helpful I don't mind the numbers.
Some time ago I came across a class called XmlHelper during a code review. It had a number of methods that obviously all had to do with Xml. However, it wasn't clear from the type name what the methods had in common (aside from being Xml-related). It turned out that some of the methods were formatting Xml and others were parsing Xml. So IMO the class should have been split in two or more parts with more specific names.
As always, it depends on the context.
When you work with your own API I would definitely consider it a code smell, because FooHelper indicates that it operates on Foo, but the behavior would most likely belong directly on the Foo class.
However, when you work with existing APIs (such as types in the BCL), you can't change the implementation, so extension methods become one of the ways to address shortcomings in the original API. You could choose to names such classes FooHelper just as well as FooExtension. It's equally smelly (or not).
Depends on the actual content of the classes.
If a huge amount of actual business logic/business rules are in the helper classes, then I would say yes.
If the classes are really just helpers that can be used in other enterprise applications (re-use in the absolute sense of the word -- not copy then customize), then I would say the helpers aren't a code smell.
It is an interesting point, if a word becomes 'boilerplate' in names then its probably a bit whiffy - if not quite a real smell. Perhaps using a 'Helper' folder and then allowing it to appear in the namespace keeps its use without overusing the word?
Application.Helper.SharePoint
Application.Helper.Authentication
and so on
In many cases, I use classes ending with Helper for static classes containing extension methods. Doesn't seem smelly to me. You can't put them into a non-static class, and the class itself does not matter, so Helper is fine, I think. Users of such a class won't see the class name anyway.
The .NET Framework does this as well (for example in the LogicalTreeHelper class from WPF, which just has a few static (non-extension) methods).
Ask yourself if the code would be better if the code in your helper class would be refactored to "real" classes, i.e. objects that fit into your class hierarchy. Code has to be somewhere, and if you can't make out a class/object where it really belongs to, like simple helper functions (hence "Helper"), you should be fine.
I wouldn't say that it is a code smell. In ASP.NET MVC it is quite common.