Donc, quand vous essayez de vous éduquer pour le principe de la responsabilité unique, vous rencontrerez probablement des définitions comme "Une méthode devrait faire une seule chose." et "Une classe devrait être juste une raison de changer". Et puis il y a toujours des tas d'exemples de jouets commeComprendre le principe de la responsabilité unique avec ce vrai code
class Dog {
String bark() {
return "Woof";
}
}
Mais je trouve qu'il est très difficile d'appliquer ce principe dans l'entreprise de développement d'applications.
Nous avons une application où nous avons "Éléments du projet", "Activités" et "Employés". Un employé aura plusieurs activités et une activité peut avoir un élément de projet.
Certains employés sont affectés à tous les éléments du projet, d'autres seulement à un groupe. Un élément de projet peut être supprimé d'un employé et de nouveaux peuvent être affectés. L'employé peut seulement ajouter de nouvelles activités avec des éléments de projet qui lui sont assignés. Si aucun élément de projet n'est affecté, cela signifie que tous sont disponibles.
Un client de nous avait une exigence, ils voulaient voir une liste des éléments de projet favoris lors de l'ajout de nouvelles activités. Peu importe comment un employé fait la promotion d'un élément de projet, il s'agit d'une vue différente.
Les éléments favoris du projet doivent être classés par des règles intéressantes. Cela dépend du travail total calculé des activités où un élément de projet favori existe, il ne tient compte que des 60 derniers jours. Au moins, il est une exigence concrète ..
Il était de mon devoir de mettre en œuvre, et voici la mise en œuvre, j'ai:
public List<ProjectElement> getFavoriteProjectElementsSortedDescendingByTotalWorkHoursInLast60Days(Employee owner) {
// All Favorite Project Elements of Owner
final List<ProjectElement> favoriteProjectElementsOfOwner
= (List<ProjectElement>) (List<?>) favoriteBusinessObjectHelper.getAllFavoriteObjectsForBusinessObjectType(BusinessObjectType.PROJECT_ELEMENT.toInt());
// Activities by Favorite Project Elements
final List<Activity> favoriteProjectElementActivitiesForLast60Days
= activityFinder.findByInProjectElementsForLastGivenDates(owner, favoriteProjectElementsOfOwner, 60);
// Create a Map with Favorite Project Element - Calculated Work
final Map<ProjectElement, Long> projectElementTotalWorkMap = new HashMap<ProjectElement, Long>();
for (Activity activity : favoriteProjectElementActivitiesForLast60Days) {
final ProjectElement activityProjectElement = activity.getProjectElement();
if (!projectElementTotalWorkMap.containsKey(activityProjectElement)) {
projectElementTotalWorkMap.put(activityProjectElement, 0L);
}
final long calculatedWork = activity.getCalculatedWork();
final long totalCalculatedWork = projectElementTotalWorkMap.get(activityProjectElement) + calculatedWork;
projectElementTotalWorkMap.put(activityProjectElement, totalCalculatedWork);
}
// Sort the Map by value descending
final Map<ProjectElement, Long> sortedProjectElementTotalWorkMap
= InnboundSortTool.sortByValueDescending(projectElementTotalWorkMap);
// We do not want to show owners Favorite Project Element in the sidebar, if the Project Element is not available
// for Employee anymore.. See the comments at the end of the file.
final Set<ProjectElement> allowedProjectElementsForOwner = owner.getExplicitlyAssignedOnlyActiveProjectElements();
final ArrayList<ProjectElement> projectElementsSorted = new ArrayList<ProjectElement>();
for (ProjectElement projectElement : sortedProjectElementTotalWorkMap.keySet()) {
if (allowedProjectElementsForOwner.size() == 0) { // This means Employee does not have any restrictions, all Project Elements are available to him.
projectElementsSorted.add(projectElement);
} else { // If Employee has assigned Project Elements, we must check if the Favorite Project Element is assigned to him..
if (allowedProjectElementsForOwner.contains(projectElement)) {
projectElementsSorted.add(projectElement); // If yes, add it to list, if no simply continue the loop without adding.
}
}
if (projectElementsSorted.size() == 20) {
break; // 20 is an arbitrary value, we do not want to show too many Favorite Project Elements in the UI.. Limit by 20.
}
}
return projectElementsSorted;
}
Whoa, qui est une grande méthode, mais il fait le travail terminé. Mais ça ne fait pas une chose, n'est-ce pas? Mais si chaque méthode ne fait qu'une chose, qui va faire le tout?
Ai-je introduire une classe d'aide et tout délégué à la cette classe et commencer à appeler:
final Map<ProjectElement, Long> projectElementTotalWorkMap = helper.CreateprojectElementTotalWorkMap();
helper.removeUnassignedFavoriteProjectElementsFromEmployee();
etc? Mais puis-je présenter un assistant à Helper lui-même? Où finit-il même? Quand je commence refactoring comme ça, je finis par avoir des méthodes extrêmement inutiles qui il suffit d'appeler d'autres méthodes, et cette classe ressemblera à ceci:
List<ProjectElement> favoritesList;
favoritesList = helper.doThis();
favoritesList = helper.doThat();
favoritesList = helper.sort();
return favoritesList;
Dois-je comprendre pas ce principe du tout? Je suppose que non, alors voici la question, comment dois-je réparer cette méthode afin qu'elle adhère à "SRP"?
Oui, certainement utile, merci. Mais encore, juste déplacer 5 lignes de code à une méthode privée? Probablement je suis celui qui est incapable de comprendre le concept (ou l'avantage) qui va avec .. –
@KorayTugay Vous avez raison de dire que cela semble inutile et comme un travail supplémentaire parfois. Cependant la puissance de ceci pour moi vient quand j'ai de nouveaux membres dans mon équipe qui ont besoin de comprendre le code. S'ils ont besoin de comprendre la situation dans son ensemble, ils pourront simplement regarder ces fonctions d '«orchestration». Ce n'est que lorsque les choses tournent mal qu'elles doivent aller plus loin, et ensuite, espérons-le, elles seront en mesure de déterminer où chercher. Il est également très intimidant et surchargé cognitif de regarder une grande fonction. Une bonne lecture serait Clean Code par Robert Martin. – Reasurria