Revize daee0ce8
Přidáno uživatelem Ondřej Váně před asi 4 roky(ů)
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/LongOrNonExistentFeedbackLoopsDetectorImpl.java | ||
---|---|---|
53 | 53 |
|
54 | 54 |
/** |
55 | 55 |
* Postup detekce: |
56 |
* A) |
|
57 |
* 1) najít všechny aktivity, které by mohli představovat zákaznické demo (název bude obsahovat substring) |
|
58 |
* 2) zjistit průměrnou délku iterací |
|
59 |
* 3) zjistit počet iterací |
|
60 |
* 4) nejprve porovnat s počtem iterací => iterace a nalezené aktivity by se měly ideálně rovnat (mohou být menší i větší ale né o moc menší) |
|
61 |
* 5) u každých dvou po sobě jdoucích aktivitách udělat rozdíl datumů a porovnat s průměrnou délkou iterace => rozdíl by se neměl moc lišit od průěrné délky iterace |
|
62 |
* 6) pokud u bodu 4) dojde k detekci máleho počtu nalezených aktivit (tým nedělá aktivity na schůzky a může zaznamenávat pouze do wiki) |
|
63 |
* 7) najít všechny wiki stránky a udělat join kdy se měnily (může být použita jedná stránka pro více schůzek) s příslušným názvem |
|
64 |
* 8) udělat group podle dne |
|
56 |
* 1) najít všechny aktivity, které by mohli představovat zákaznické demo (název bude obsahovat substring) |
|
57 |
* 2) zjistit průměrnou délku iterací |
|
58 |
* 3) zjistit počet iterací |
|
59 |
* 4) nejprve porovnat s počtem iterací => iterace a nalezené aktivity by se měly ideálně rovnat (mohou být menší i větší ale né o moc menší) |
|
60 |
* 5) u každých dvou po sobě jdoucích aktivitách udělat rozdíl datumů a porovnat s průměrnou délkou iterace => rozdíl by se neměl moc lišit od průěrné délky iterace |
|
61 |
* 6) pokud u bodu 4) dojde k detekci máleho počtu nalezených aktivit (tým nedělá aktivity na schůzky a může zaznamenávat pouze do wiki) |
|
62 |
* 7) najít všechny wiki stránky a udělat join kdy se měnily (může být použita jedná stránka pro více schůzek) s příslušným názvem |
|
63 |
* 8) udělat group podle dne |
|
65 | 64 |
* |
66 | 65 |
* @param project analyzovaný project |
67 | 66 |
* @param databaseConnection databázové připojení |
src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/detecting/detectors/NinetyNinetyRuleDetectorImpl.java | ||
---|---|---|
10 | 10 |
|
11 | 11 |
import java.util.ArrayList; |
12 | 12 |
import java.util.List; |
13 |
import java.util.Map; |
|
13 | 14 |
|
14 | 15 |
public class NinetyNinetyRuleDetectorImpl extends AntiPatternDetector { |
15 | 16 |
|
... | ... | |
27 | 28 |
/** |
28 | 29 |
* SETTINGS |
29 | 30 |
*/ |
31 |
private static final double MAX_DIVISION_RANGE = 1.2; |
|
32 |
private static final double MIN_DIVISION_RANGE = 0.8; |
|
30 | 33 |
|
31 | 34 |
@Override |
32 | 35 |
public AntiPattern getAntiPatternModel() { |
... | ... | |
43 | 46 |
this.sqlQueries = queries; |
44 | 47 |
} |
45 | 48 |
|
49 |
/** |
|
50 |
* Postup detekce: |
|
51 |
* 1) pro každou iteraci udělat součet stráveného a odhadovaného času přes všechny aktivity |
|
52 |
* 2) udělat podíl strávený čas / odhadovaný čas |
|
53 |
* 3) pokud všechny výsledky podílů budou v rozsahu 0.8 - 1.2 => vše ok |
|
54 |
* 4) pokud budou některé výsledky mimo rozsah, tak se najde iterace s nejhorším výsledkem |
|
55 |
* 5) od této iteraci by měl být výsledek podílů mít klesající tendenci |
|
56 |
* tato časová řada by měla mít klesající tendenci |
|
57 |
* |
|
58 |
* @param project analyzovaný project |
|
59 |
* @param databaseConnection databázové připojení |
|
60 |
* @return výsledek detekce |
|
61 |
*/ |
|
46 | 62 |
@Override |
47 | 63 |
public QueryResultItem analyze(Project project, DatabaseConnection databaseConnection) { |
64 |
|
|
48 | 65 |
List<ResultDetail> resultDetails = new ArrayList<>(); |
49 |
return new QueryResultItem(this.antiPattern, false, resultDetails); |
|
66 |
List<Double> divisionsResults = new ArrayList<>(); |
|
67 |
boolean isAllInRange = true; |
|
68 |
|
|
69 |
List<List<Map<String, Object>>> resultSets = databaseConnection.executeQueriesWithMultipleResults(project, this.sqlQueries); |
|
70 |
for (List<Map<String, Object>> rs : resultSets) { |
|
71 |
for (Map<String, Object> map : rs) { |
|
72 |
Double resultDivision = (Double) map.get("timeDivision"); |
|
73 |
// some divisions can by null |
|
74 |
if (resultDivision == null) { |
|
75 |
continue; |
|
76 |
} |
|
77 |
divisionsResults.add(resultDivision); |
|
78 |
// if is one division is out of range set boolean to false |
|
79 |
if (resultDivision > MAX_DIVISION_RANGE || resultDivision < MIN_DIVISION_RANGE) { |
|
80 |
isAllInRange = false; |
|
81 |
} |
|
82 |
} |
|
83 |
} |
|
84 |
|
|
85 |
if (isAllInRange) { |
|
86 |
resultDetails.add(new ResultDetail("Conclusion", "All divisions of estimated and spent time are in range")); |
|
87 |
return new QueryResultItem(this.antiPattern, false, resultDetails); |
|
88 |
} |
|
89 |
|
|
90 |
return new QueryResultItem(this.antiPattern, true, resultDetails); |
|
50 | 91 |
} |
51 | 92 |
} |
src/main/webapp/queries/long_or_non_existent_feedback_loops.sql | ||
---|---|---|
22 | 22 |
select COUNT(id) as 'numberOfIterations' from iteration where superProjectId = @projectId; |
23 | 23 |
/* Average iteration length */ |
24 | 24 |
select avg(abs(dateDiff(iteration.endDate, iteration.startDate))) as 'averageIterationLength' from iteration where superProjectId = @projectId; |
25 |
/* Avoid error in sql execution */ |
|
26 |
|
|
27 | 25 |
/* Select number of iterations which contains at least one feedback activity */ |
28 | 26 |
select count(*) over () as 'totalCountOfIterationsWithFeedbackActivity' from workUnitView as wuv where wuv.projectId = @projectId and (wuv.name like "%schůz%zákazník%" OR wuv.name like "%předvedení%zákazník%" OR wuv.name LIKE "%zákazn%demo%" OR wuv.name like "%schůz%zadavat%" OR wuv.name like "%inform%schůz%" OR wuv.name like "%zákazn%" OR wuv.name like "%zadavatel%") group by wuv.iterationName order by wuv.activityEndDate; |
29 | 27 |
/* Select all activities for feedback loop with last modified date as end date */ |
src/main/webapp/queries/ninety_ninety_rule.sql | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
Anti-pattern name: Ninety-Ninety Rule |
3 | 3 |
|
4 |
Description: The first 90 percent of the code represents the first 90 percent of development time. The |
|
5 |
remaining 10 percent of the code represents another 90 percent of development time. |
|
6 |
Then decide on a long delay of the project compared to the original estimate. |
|
7 |
The functionality is almost done, some number is already closed and is only waiting |
|
8 |
for one activity to close, but it has been open for a long time. |
|
9 |
|
|
10 |
Detection: In each iteration, find out how much time the activities were estimated and how much time |
|
11 |
they actually took. During the iterations, the estimates and time spent on activities should equal. |
|
4 | 12 |
*/ |
13 |
|
|
14 |
/* Init project id */ |
|
15 |
set @projectId = ?; |
|
16 |
/* Select all activities for each iteration and sum estimated time and spent time */ |
|
17 |
select iterationName, sum(estimatedTime) as 'estimatedTime', sum(spentTime) as 'spentTime', sum(spentTime)/sum(estimatedTime) as 'timeDivision' from workUnitView where projectid = @projectId group by iterationName order by iterationName; |
Také k dispozici: Unified diff
Ninety ninety first implementation ready