Aspects are originally introduced to capture cross-cutting concerns among classes. Often this cross-cutting concerns ends up being non-functional requirements.
USING CLASSPECTS FOR INTEGRATING NON-FUNCTIONAL AND FUNCTIONAL REQUIREMENTS Tegegne Marew, Doo Hwan Bae Division of Computer Science, Korea Advanced Institute of Science and Technology, Daejon 305-701, Korea {tegegnem, bae}@se.kaist.ac.kr
ABSTRACT
ture non-functional requirements. In this paper, we suggest an approach on how to capture the NFRs identified by the NFR Framework as aspects so that NFRs can be integrated easily with FRs during software development. The rest of the paper is organized as follows. Section 2 introduces the two works our research is based upon. In Section 3, we discuss the the approach for integrating NFRs to FRs followed by Section 4 for discussion on the approaches that are similar with ours. Finally, Section 5 summarizes this paper and explains what we are going to expand on this research.
Aspects are originally introduced to capture cross-cutting concerns among classes. Often this cross-cutting concerns ends up being non-functional requirements. We can use Softgoal Interdependency Graphs(SIG) to systematically analyze and design non-functional requirements. In this paper, we propose a set of rules that could be used to capture the information in SIGs as classpects. Then the classpects thus generated are integrated with the classes that encapsulate functional requirements. As a result, any further life cycle of the software development not only captures the functional but also the non-functional requirements. KEY WORDS Non-Functional Requirments, Classpects, NFR FrameWork
2 Background The concepts in this paper closely depend on ideas contained in two works which we discuss in this section. The first is the NFR Framework to help us capture the NFRs of a given system. The other work we discuss is classpects [8] which tries to combine the concept of class with the the concept of aspect. The NFR Framework is a qualitative approach for eliciting and analyzing NFRs. It treats NFRs as softgoals that need to be satisficed instead of satisfied. SIG, Softgoal Interdependency Graph, plays a central role in viewing and analyzing NFRs. In this paper, we utilize the fact that the NFR Framework decomposes NFR along both topic, what kind of NFR it is, and parameter, the entity in the system the NFR is applied to as shown in Figure 1. The AND/OR decomposition of NFRs suggested by the NFR Framework also is used to capture NFRs as aspects. One of the important features of the NFR Framework is the management of the interdependencies between different NFRs. The dependencies can be one of make, hurt, break, help, and undetermined. The Framework also have guidelines on how to combine these different contributions. The other research work we use in our work is the notion of classpects [8]. Their motivation is to leverage the advantages of both class and aspects. We employ their approach because it significantly improves the compositionality of aspect modules, expanding the program design space from the two-layered model of AspectJ-like languages to include hierarchical structures. By allowing the join points of aspects be named in the method-join point binds, aspects not only can advise base classes but other aspects. From the example below, we can see the joinpoint, Exception-
1 Introduction Requirements in software engineering are traditionally classified as functional requirements (FR) and Nonfunctional requirements (NFR). The analysis and design of FRs has got a lot of attention from the early days of software engineering. On the other hand, NFRs like performance, security, usability and correctness often are incorporated, if they are ever included, into the final system as after thought (first build the FRs and then add the NFRs if you can). Still, complex and expensive systems has failed miserably because of improper management of quality attributes (NFRs)[1, 2, 3]. A number of researches have been conducted on the analysis of NFRs. Even though there are a number of different approaches for dealing with NFRs, the Non Functionality Requirement Framework [4, 5, 6] has been the relatively successful approach as it has been the basis of many of the other approaches and has the most case studies conducted to validate it. The NFR framework, discussed further in [7], is supposed to work in parallel with other FR analysis methods like OOA even though the original developers of NFR Framework didn’t provide much detail on how to accomplish such objective. Aspect-oriented software development has been originally introduced to offer a higher separation of concerns than provided by OOP by capturing cross-cutting concerns as aspects. Often this cross-cutting concerns turn out to be NFRs. Therefore, aspects has been often used to cap-
518-075
142
Creating SIG
Performance (Account)
Synthesising Classpects from SIG
Space (Account)
Response Time (Account) Descovering Classes for the Classpects
Figure 1. Performance can be decomposed, along topic, to space and time requirements Integrating the Classes and the Classapects
Handler, is named. Therefore, if another classpect want to advice this joinpoint, there is no problem of identifying ExceptionHandler.
Figure 2. An approach for integrating NFRs with FRs
cla ss Exception { pointcut exception ( ) : execution (∗ ∗(..))&& ! within ( ExceptionHandler ) ; s t a t i c a ft er exception ( ) : ExceptionHandler ( ) ; p u b l i c void ExcpetionHandler ( ) { /∗ Handle t h e e x c e p t i o n ∗/ } }
• the parameter: the object or entity the non-functional requirement applies to • the decomposition of a non-functional requirement either on its topic or its parameter In this section, we will discuss the rules for creating aspects from a SIG one by one. We use the textual form of SIG as suggested by [6] to discuss the rules but the corresponding graphs can be seen in Figure 3 .
3 The Approach
• A1(B) AND A2(B) SATISFICES A(B)
The general approach we propose for integrating nonfunctional requirements and functional requirements is given in Figure 2. The first step, creating SIG, is already discussed elsewhere[4, 5, 6]; therefore, we are not going to discuss it here. Instead, The ”synthesizing classpects from SIG” phase is where we are going to concentrate. At this stage, we use rules that are discussed in to transform the SIG to a set of classpects that can easily be integrated with the classes that capture the FR. At this stage, the classpects are very much skeletal in that the actual classes they advise and the advises they make are not completely discovered. To accomplish that objective, we need to discover the classes that the classpects are supposed to advise. We do that at phase 3 of the the approach. Once we discover such classes we need to fill out the actual advises the classpects give to those classes along with filling out additional information required for integration.
3.1
We create three classpects: A1, A2 and A. A advises B while A1 and A2 advices A. At first glance, it may seem A1 and A2 should advice B. However, that would lose the information A is refined into A1 and A2. We can preserve the information if we ensure A1 and A2 advise A instead of B. Note that even if A is a NFR and B is an object which may be captured as class, since we use classpects, both A and B are finally implemented as classpects. • A(B1) AND A(B2) SATISFICES A(B) Here an entity B in the system is decomposed into B1 and B2. This situation occurs often as a result of – When B1 and B2 are subclasses of B. For instance an account can be subclassed into goldaccount and regularaccount – When B1 and B2 refer to (deals with) different attributes of B. This is called decomposition via attributes.
From SIG to Aspects
Of the different information contained in SIGs, we will use the followings to synthesis aspects from a SIG. They are:
– When B1 and B2 are mutually exclusive subsets of B or in other words B is conceptually coarse grained entity in the system which later
• the topic: name of the non-functional requirement
143
is decomposed into independent classes. For instance, system refereing to the whole software system later decomposed into memory, cpu, etc. Here we don’t expect B to actually exist as a class in the final software code and thus cannot be advised.
(1)
A1(B) A2(B) A(B) (2)
A(B1)
Since we don’t have the class diagrams at the time we are analyzing the SIG, we cannot decide which case actually applies except use our best judgement.
A(B2)
A(B)
(3)
A1(B) (4)
A2(B)
A(B)
A(B1)
A(B2)
Figure 3. The different cases of the rules
If we decide it is the first case, we only need one classpect A that advises B. Since B1 and B2 are subclasses of B, the advise of A to B applies to them automatically.
4 5 6 7 8 9 10 }
If it is the second case, we need three classpects A, A1 and A2. We have to remember B1 and B2 are part of B as they deal with different attributes of B at code level. We make classpect A1 to advise A, but the advise is about the attributes of B dealt by B1. In the same manner, classpect A2 should advise A on the attributes that are dealt by B2. Finally, classpect A should advise B. The example below will illustrate this particular case.
} p u b l i c void s a f t e y f u n ( ) { i n f o r m f a c i l i t y manager } b e f o r e e x e c u t i o n { ( p u b l i c ∗Room . ∗ ( ∗ ) ) && r e t u r n s ( r e t ) && a r g s ( ) : ca ll safetyFun ( ) ;
p u b l i c c l a s s SafeRoomMalOI{ SafeRoomMal srm ; p u b l i c SafeRoomMalOI ( SafeRoomMal srm ) { t h i s . srm = srm ; } p u b l i c void s a f t e y f u n ( ) { a l l c e i l i n g l i g h t s on and i n f o r m u s e r } before execution ( public ∗ safeRoomMal . ∗ ( ∗ ) ) && r e t u r n s ( r e t ) && a r g s ( ) : ca ll safetyFun ( ) ; }
In the third case, since we don’t have B at the code level (because it is represented by the independent (mutually exclusive) B1, and B2), we need the classpect A to directly advise B1 and B2. • A1(B) OR A2(B) SATISFICES A(B) Here one of A1 or A2 is chosen to advise A while A advises B. This seems redundant as A1 or A2 can directly advise B but in that case the relation between A1 or A2 and A is lost in the code. • A(B1) OR A(B2) SATISFICES A(B)
p u b l i c c l a s s SafeRoomMalMD{ SafeRoomMal srm ; p u b l i c SafeRoomMalMD ( SafeRoomMal srm ) { t h i s . srm = srm ; } p u b l i c void s a f t e y f u n ( ) { inform user and s e t room a s o c c u p i e d } before execution ( public ∗ safeRoomMal . ∗ ( ∗ ) ) && r e t u r n s ( r e t ) && a r g s ( ) : ca ll safetyFun ( ) ; }
This is similar to case 2. Therefore, we have three cases (but the second case doesn’t make sense for “OR” decomposition and we haven’t come across it on the case study we have performed so far and thus we don’t discuss it here). In the first case, classpect A advises B. We don’t need to know which of B1 or B2 is chosen to refine B. In the third case we care since B actually doesn’t exist at a code level. If it is B1, then classpect A will be made to advise B, otherwise A will advise B2. We can see the application of such rules using Figure 4. Here the white clouds represent softgoals and the shaded clouds represent operationalization. The decomposition of the root is via attributes. The skeletal classpect code generated looks like
In the classpect SafeRoomMal, lines 2-4 describe the constructor which designate a Room class (here we are not sure if there is a room class in the functional requirement but we use it as first approximation) as one of its own attributes. This helps the classpects to access the attributes of Room if there is a need to do so. In lines 5-7, we have the method that advices the class Room and in lines 8-10 we have the crosscut specifications describing which methods and when (before, after, around) the advice occurs. The
p u b l i c c l a s s SafeRoomMal{ 1 2 3
A(B)
Room rm ; p u b l i c SafeRoomMal ( Room rm ) { t h i s . rm = rm ;
144
;; ;; ;; ;; ; ;;;
the objects they have identified early on. The reason being to use the same term used in FR, the NFR analyst should understand what the FR analyst meant to say by that term and see if that is exactly what he (the NFR analyst) also wants to model.
Safety (Room. Malfunction)
Safety (Room. Malfunction.OI)
All ceiling lights on
Safety (Room. Malfunction. Motion Detector)
inform user
inform facility manager
• Start with use cases and consider the classes that collaborate to implement the use case. Often a specific NFR can be seen as if it applies to a particular use case(s) since use cases are used for functional decomposition and the quality of each functionality is captured by a specific NFR. For instance, if we have a use case withdrawal, an FR, in an ATM system, we can easily see security, an NFR, is a required quality. Once we identify the use case, we can investigate the classes in the sequence diagram that implements the use case to see which class(es) the NFR should be applied to.
set room as occupied
Figure 4. An example used to show the application of the rules
• Using the requirement document. Usually, a specific NFR is usually mentioned along side with the entities it applies to. If those entities are later decided to be realized as classes, then the classpect that realizes the NFR can be applied to those classes.
important characteristics of this code are: • It is skeletal. The actual arguments of the methods and their bodies is not yet filled. We just have inserted text messages based on the operationalizations in the methods of the classpects. Actually how that is implemented, obviously, depends on the class that is advised. Besides, we decided every method in the Room class is advised by SafeRoomMal. This may be changed after going through the methods of Room.
In our example,Figure 2, the Room class actually exists in the class diagram and thus the skeletal code of classpect SafetyRoomMal doesn’t change.
3.3
• It preserves the the hierarchical structure of the SIG. The first class, SafeRoomMal, corresponds to the root of the SIG. It advises a class called Room which we hope is one of the classes in the design document for the functional requirements. If that is not the case, we have to figure out which class this classpect advise (that is the topic of the next phase). If we look at the second and third classes which represent the children of the root, they all advice SafeRoomMal. This is according to rule 2. Since the two softgoals deal with different attributes of room (one about lights and the other about motion detector).
3.2
Integrating Classpects with Classes
At the final stage, we have to integrate the classpects we synthesized from the SIG in the second phase and the classes we determined to be advised by these classpects in the third phase. In the SIG, the leaves of the tree structure are operationalizations. These are captured in the body of the methods of the classpects as we saw in phase two. But, the information required to realize these methods is not completely available in the classpects. For instance, in the classpect SafeRoomMalOI the advice is all ceiling lights on. Clearly to realize such objective, we need to have attributes/accessor methods that allow us to manage ceiling attributes. Such information (being functional requirement related) is available in the Room class we identified in phase two. This is the time to utilize the design specification of Room to find about its attributes and methods. The class diagram of Room is shown in Figure 5. Now using the information from the class diagram we fill out the skeletal code. When we fill out the code we have to realize one important difference between the information contained in the SIG and UML diagrams. In UML diagrams, we don’t have implementation details. Yet, in the SIG, operationalization nodes capture implementation details. Since NFRs are quite general and there realization is quite independent of the particular application we are developing, it is possible to incorporate the information at the SIG (now in the classpects) to the functional design documents. If that is not desirable, the implementor can fill out
Discovering Classes
Once we synthesized the classpects for the NFRs identified in the SIG, we need to find which classes in the functional requirement the identified classpects apply to (advise). There are a number of approaches to achieve this objective. These include • For both NFR and FR requirement elicitation use the same vocabulary. Used by [9], this method ensures the parameters of the NFRs in the SIG are also used in the FR elicitation. Unfortunately, this approach requires both FR and NFR analysts to precisely know
145
the skeletal classpects himself/herself. Here we decided to ill out the classpects at the design level. The result is Room
p u b l i c c l a s s SafeRoomMal{ 1 Room rm ; 2 p u b l i c SafeRoomMal ( Room rm ) { 3 t h i s . rm = rm ; 4 } 5 p u b l i c void s a f t e y f u n ( ) { 6 p r i n t l n ( ‘ ‘ T h i s room ”+ rm . i d + ‘ ‘ has a malfunction ” ) ; 7 } 8 b e f o r e e x e c u t i o n { p u b l i c ∗ Room . ∗ ( ∗ ) ) 9 && r e t u r n s ( r e t ) && a r g s ( ) : 10 c all safetyFun ( ) ; }
+id : Integer +lights : sequence(idl) +user : String +occupied : Boolean +fm : String +lightintensity : Byte +setLightIntensity() +occupied() : boolean +setOccupied() +lightIntensity() : Byte +turnLights(in light : Single)
p u b l i c c l a s s SafetyRoomMalOI { SafetyRoomMal srm ; p u b l i c SafeRoomMalOI ( SafeRoomMal srm ) { t h i s . srm = srm ; } p u b l i c void s a f t e y f u n ( ) { f o r a l l i i n srm . rm . l i g h t s { srm . rm . t u r n O n L i g h t s ( i ) ; } p r i n t l n ( ‘ ‘ T h i s room ”+ srm . rm . i d + ‘ ‘ has a malfunction ” ) ; } before execution { public ∗ safeRoomMal . ∗ ( ∗ ) ) && r e t u r n s ( r e t ) && a r g s ( ) : ca ll safetyFun ( ) ; }
Figure 5. The class diagram of Room
In the classpect SafeRoomMal we don’t need to do much to incorporate all the information required. We just need to write a println (assuming java is used as implementation code). In the case of SafeRooMalOI, we have to do a little more (for turning on the lights) using the methods in the room class.
ber of researches. The non-functional requirement framework (NFR-Framework), discussed in section 2, often is the spring board for most of such researches including ours. [9] discusses how non-functional requirements elicited by NFR-Framework can be incorporated into UML diagrams specifically use case, class, sequence, and collaboration diagrams. Their work needs a developer to use a common vocabulary for both functional and non-functional requirement analysis. From the SIG, they use the common vocabulary feature to find which classes are related to which softgoals. Once they identified the relation, they add appropriate methods on the class diagrams to realize the softgoals. The first difference with our work is that they don’t use aspects to realize NFRs. This, in our opinion, is a serious draw back as NFRs are cross-cutting concerns. Moreover, the design document they produce doesn’t preserve the information conveyed by the SIG. We achieve such objective by using the rules we developed and the classpects that are used to realize the NFRs. [10] describes how we can start from soft goals and discover aspects. They use goal-oriented requirement analysis for both functional and non-functional requirement analysis. In our work, we don’t introduce new analysis technique for functional requirements as object oriented analysis is a widely accepted analysis technique. It is not always easy to use functional requirements discovered by goal-oriented analysis for designing classes and their relationship. Besides, even if we discover aspects from SIGs using the approach, there are no guidelines on how to find the classes these aspects advise. Moreover, the approach doesn’t preserve the hierarchical information SIGs provide.
4 Related Work
5 Conclusion
Systematic inclusion of non functional requirements to the functional requirement analysis has been a topic of a num-
We have presented an approach for integrating NFR to FR analysis. We used the widely accepted Non-Functional Re-
p u b l i c c l a s s SafeRoomMalMD{ SafeRoomMal srm ; p u b l i c SafeRoomMalMD ( SafeRoomMal srm ) { t h i s . srm = srm ; } p u b l i c void s a f t e y f u n ( ) { p r i n t l n ( ‘ ‘ T h i s room ”+ srm . rm . i d + ‘ ‘ has a malfunction ” ) ; srm . rm . s e t O c c u p i e d ( ) ; } before execution { public ∗ safeRoomMal . ∗ ( ∗ ) ) && r e t u r n s ( r e t ) && a r g s ( ) : ca ll safetyFun ( ) ; }
146
quirement Framework to capture the NFRs. Then, we synthesized classpects from the SIG using the rules we developed and found the classes they advise in the design documents particularly class diagrams. Once we identified the classes, we filled out the remaining code for the classpects. Therefore, we included the classpects which represent the NFRs into the class diagrams which originally include only the functional requirements. We plan to extend and fine tune our approach to fully integrate NFRs and FRs. First, we are carrying out case studies to validate our approach. Second, we will investigate if we need to add additional rules or modify existing ones. Third, we are going to compare and contrast the relative merits of different approaches for finding the classes the classpects refer to. Fourth, we will try to find the best way to capture the operationalizations in the SIG as methods or attributes in the classpects. Our ultimate goal will be to provide a framework with specific practical guidelines for incorporating NFRs into FRs.
Acknowledgments This work was supported by the Ministry of Information & Communication, Korea, under the Information Technology Research Center (ITRC) Support Program.
References [1] K.K. Breitman, J.C.S.P. Leite, and A. Finkelstein, The World’s Stage: A Survey on Requirements Engineering Using a Real-Life Case Study, J. the Brazilian Computer Soc., 6(1), July 1999, 13-38. [2] A. Finkelstein and J. Dowell, A Comedy of Errors: The London Ambulance Service Case Study, Proc. Eighth Int. Workshop Software Specification and Design,1996, 2-5. [3] D.R. Lindstrom, Five Ways to Destroy a Development Project, IEEE Software, 1993, 55-58,. [4] L. Chung, Representing and Using Nonfunctional Requirements: A Process Oriented Approach,PhD thesis, Dept. of Computer Science, Univ. of Toronto, June 1993, also Technical Report DKBSTR- 91-1 [5] L. Chung and B. Nixon, Dealing with Nonfunctional Requirements: Three Experimental Studies of a Process-Oriented Approach, Proc. 17th Int. Conf. Software Eng., 1995, 24-28, . [6] L. Chung, B. Nixon, E. Yu, and J. Mylopoulos, Non-Functional Requirements in Software Engineering(Kluwer Academic, 2000). [7] J. Mylopoulos, L. Chung, and E. Yu., From object-oriented to goal-oriented requirements analysis, Communications of the ACM, 42(1), Jan. 1999, 31-37, . [8] H. Rajan and K. J. Sullivan, Classpects: Unifing Aspect- and Object-Oriented language design, ICSE 05, 59-68. [9] Cysneiros,L.M. and Leite, J.C.S.P., Non-Functional Requirements: From Elicitation to Conceptual Model, IEEE Transactions on Software Engineering, May 2004. [10] Y. Yu, J.C.S.P. Leite, J. Mylopoulos. From goals to aspects: discovering aspects from requirements goal models., Proceedings of the 12th IEEE International Requirements Engineering Conference (RE’04). 2004, 38-47, .
147