• No se han encontrado resultados

2. Violencia escolar

2.1.2. Raíces de la violencia.

Martin has defined the Dependency Inversion Principle (DIP) (Martin, 1994), which states that “high level modules should not depend upon low level modules. Both should depend upon abstractions”. This means a class should depend on an abstract type rather than on a concrete class. However, these abstract types still have to be instantiated using concrete classes. There are several ways to instantiate a concrete class and pass it to the client class exhibiting DIP. One possible solution to locate and utilise implementation classes is a J2EE pattern called service locator1. Fowler (2004) has discussed the benefits of using service locators to avoid instantiation problems. He suggests to create a service locator, which has knowledge about a service and its implementations and use the service locator along with a registry to locate and instantiate implementation types. In our previous work, we have used the service locator pattern to achieve modularity in object-oriented programs (Shah et al., 2012).

5.2.3 Static Members Inlining

The inlining technique is primarily used by the Java compiler for the optimisation of program execution, it is also known as constant folding (Muchnick, 1997). This type of inlining is limited to static and final values and string constants, where calls to constants are replaced with their values by the compiler. Inlining is also used as a refactoring technique where fields, methods and classes are inlined into a client class for the purpose of optimisation or for removing a dependency. For example, in order to remove a dependency, Feathers (2004) has suggested a refactoring called extract and override callin which the method signature of the invoked method (causing a dependency relation) is copied into the client class and a subclass of the client implements and returns a mock value for testing.

Tsantalis and Chatzigeorgiou (2009) have investigated classes to identify move method refactorings. According to the authors, moving fields and methods within classes may play an important role in achieving low coupling and high cohesion. They propose a novel method for the identification of Feature Envy problems in programs. The Feature

1http://www.oracle.com/technetwork/java/servicelocator-137181.html

Envy problem occurs in programs where a method frequently accesses features of a class other than the one in which it exits (Fowler, 1999). The authors introduce a concept of distance between software artefacts, such as fields, methods and classes, which identifies refactoring opportunities. In order to determine the impact of such refactorings an Entity Placement metric is used to identify whether classes are placed correctly in a system. The approach suggested is not fully automated and requires the judgement of system developers to apply relevant refactorings.

Object inlining is a similar technique, where a dependency to an object is removed by inlining its members (Dolby, 1997; Dolby and Chien, 2000). By using this tech- nique calls to newobject creations (constructor invocations) can be minimised. This minimisation ofnewcreations may improve the performance of a system (Ben Asher et al., 2012). For example, we can inline some of the members (that a class X depends on) of a class Y to class X. This would break the dependency from class X to Y. The indirect access to fields and methods in class X would also be replaced by the direct access. However, it is likely that we may create redundancy in the code if a class Z also depended on the same members of class Y which were inlined to class X. Object inlining may significantly change the meaning of classes. Similarly, when members of two classes are merged into a single class, it may also negatively affect the understand- ability of source code. Due to these reasons we restrict to inlining static members, where we move the required static members of the target class to the source class and leave a delegate method in the target class.

5.3

Algorithm

An overview of the refactoring algorithm is given below:

1. Build the dependency graph from the bytecode of a program.

2. Use the Guery engine (ver 1.3.5) to compute the set of SCD, STK, AWD and DEGINH instances (Dietrich et al., 2012).

3. Compute a list of edges (class dependencies) sorted by score ranking based on their participation in all types of antipattern instances.

4. Parse the program’s source code into ASTs.

5. Check preconditions to determine whether a dependency can be removed or not. 6. If the preconditions are satisfied, apply the refactoring on the program’s ASTs.

7. Evaluate postconditions to check whether the applied refactoring has introduced any errors.

8. If postconditions are satisfied, update the program’s source code. Otherwise, rollback the ASTs to their previous states.

9. Repeat the process until all antipatterns instances are removed or a certain num- ber of iterations are performed (MAXis 50 in our case).

The detailed refactoring process is shown in figure 5.1.

!!

!

!

!

!

!

"#$%&'()*)&'! +,$%-)'.! ! "&/*%&'()*)&'! +,$%-)'.! ! 0$12%*&#$(!! "#&.#23! 0&4452%-! 0$6$2*!7'*)4! !"#!! ")%-!8$9*!:).,; <%&#$(!+2'()(2*$! =664>! 0$12%*&#)'./! 0$?$%*! @A2472*$! 0$12%*&#)'./! +&33)*!*&! <&7#%$!+&($! "#&.#23B/!! =<C/! 0$12%*&#$(! <&7#%$!+&($! ='*)62**$#'! D$*$%*)&'! ! E#).)'24!! "#&.#23! F&#-)'.!+&6>!

Figure 5.1:Automated Refactoring Process