Keywords

These keywords were added by machine and not by the authors. This process is experimental and the keywords may be updated as the learning algorithm improves.

1 Introduction

The way software will be produced in the next Future Internet era —according to given goals and by integration and compositions of existing services and components— calls for new formally grounded and formalized aspects and methods to support the conceptual modeling of system specifications.

Important issues concerning software architectures, design decisions, quality and goals evaluations are closely linked, anyway any formal definition is available to get relevant information and support in software modeling based on this set of features. In defining and modeling software systems a set of related but complex issues must be considered when composing pieces of reusable artifacts through design or architectural patterns driven by non functional requirements satisfaction.

In this paper we propose a formalization via a Fuzzy Description Logic for modeling architectural aspects of a software system. The formalism models architectural patterns and non-functional requirements about quality attributes where both the relationships among patterns and the set non-functional requirements are modeled together with their interactions. The framework we propose enables to represent and reason on mutual relationships among non functional requirements by means of fuzzy Description Logics (DL). The fuzzy version of DLs is needed in order to represent both ontological relations and factual ones. In the former case we may model that “portability and adaptability are directly proportionate” while “stability and adaptability are inversely proportionate”. For the latter we may represent that “the Adapter pattern has a high portability”. We see that the combination of ontological and factual knowledge allows a reasoning procedure to infer new information about a pattern. With reference to the previous example, we may infer that “the Adapter pattern has a high adaptability and a low stability”. In the framework we propose here we are allowed also to formally define that “a high adaptability implies a medium maintainability Footnote 1”. Once the knowledge about non functional requirements has been modeled via a formal language and encoded in a knowledge base, we need a tool to query and retrieve data related to a specific task. In our case, the task we propose to solve is the following: given a set of non functional requirements \(\mathcal {R} = \{r_1,\ldots ,r_n\}\), retrieve the minimal subset of patterns that better satisfies them. This means that we prefer patterns with a high value of a specific functional requirement \(r_i\) to those with a medium or low one. If there is no pattern with high value for \(r_i\), than we prefer patterns with a medium value to those with a low one. In such patterns, fuzziness is evident: in fact, terms such as high, medium and low can be defined in terms of fuzzy sets [29].

The remaining of this paper is organized as follows. In the next section we motivate our proposal. Section 3 describes the approach we use to model the ontology and defines a theoretical algorithm. Section 4 presents a case study to explain the proposed idea. Conclusions and future works close the paper.

2 Motivation

Since Anton Jansen and Jan Bosch [15] gave a modern definition of Software Architecture, several important issues concerning software architectures, design decisions, quality and goals evaluations have been dominating the scientific literature in this field as comprehensively and systematically provided by Tofan et al. [27]. Designing the software architecture of non-trivial systems belonging to several application domains, namely industrial automation, defense and telecommunication financial services, and so on, is not an easy task, and requires highly skilled and experienced people. Beyond these, new challenges in the design and in architectural models are derived from self-managing and self-adaptive capabilities that are typical of many modern and emerging software systems, including the industrial internet of things, cyber-physical systems, cloud computing, and mobile computing. The satisfaction of quality requirements and the appropriate options for future changes are among the major goals of software architectures, even more important than functional requirements. Quality goals often compete or even conflict with each other and with functional requirements. In defining and modeling software architecture through patterns, a challenging issue is also concerned with the number of different available decisions depending on the fact that patterns can cooperate, are composable, are complementary or exclusive with respect to a given problem [9, 19]. To solve the challenging problem of choosing a set of patterns, some structures have been proposed supported by pattern languages with a given syntax and style [5].

In self-adaptable models but also in classical software architectures, the link between architecture and design-time features modeling and the relationship between non-functional requirements, patterns and design decisions should be made more flexible. The idea is to provide an approach to more faithfully reproduce the existing relationships in order to formalize the extent to which they are guaranteed in the design of software architecture.

3 Problem Statement and Approach

In software design domain, a typical problem to solve is the following:

Given a set of requirements define the software design that (better) models the given requirements

In order to solve such a problem, adopted empirical approaches generally depend on the designer’s know-how and experience.

According to modern software production and modeling, mainly based on component integration and/or composition and according to the modern definition of software architecture [15], the above problem is that of finding the architectural model as a solution to a decision making problem. The architectural model can hence be defined using design or architectural patterns selected according to Non-functional Requirements (NRFs) satisfaction. The selection of the right NFRs may result crucial in the initial design of a software system. It may happen that the designer is looking for the best design solution given a set of non functional requirements and some problem areas and/or pattern families related to the system. Design patterns give proven solutions to recurrent problems based on typical situations. Therefore, they are a first attempt to formalize the knowledge about NFRs and to give a somewhat structured approach to their compliance in the software design [5, 6, 11].

With respect to the general problem stated at the beginning of this section, we restrict our interest to the connection among patterns, problem areas/families and NFRs. More in detail we are aiming to finding a solution to the following design problem:

Given a software design to model, a set of NFRs and the problem areas the software refers to, which are the components/patterns that best fit them?

The task is non-trivial as: NFRs may be disjoint with each other and cannot be satisfied at the same time; some families may not contain patterns satisfying some of the NFRs. Moreover, the designer may not be aware of all the patterns available given a NFR or given a pattern family.

To the best of our knowledge, the software design theory misses a formal superstructure to integrate and relate the elements of the given sets and implicit or explicit relationships between elements. The approach we propose here, exploits a Fuzzy Description Logic and related reasoning tasks in order both (i) to provide a formal representation of the relations intercurring among design areas, NFRs and design patterns and (ii) to reason with such a representation to help the designer during the selection of the right set of patterns that best match the initial requirements. Full and exaustive background in Description Logics and Fuzzy Description Logic are available in literature ([2] for DLs and  [2224] for fuzzy DLs).

We will illustrate how to encode the information by leveraging on:

  • Fuzzy DL statements to have a high level model of the domain we are dealing with and to represent relations among non-functional properties;

  • Fuzzy DL reasoning to infer new knowledge about NFRs mutual relations and to retrieve sets of patterns satisfying specific requirements;

We next describe the role played by each of the above indicated technologies in the decision process.

Fuzzy DL statements. In order to encode all the information related to NFRs, patterns and corresponding families, we need a formalization of the domain knowledge. The ontology we use to cope with this task can be seen as composed by two main modules: the one describing, at a high level, the connections between patterns and families and between patterns and NFRs; the other one modeling the relations intercurring among NFRs. The formal definition of the ontology is encoded in Fuzzy DL as:

$$\begin{aligned} \begin{array}{l} \exists {\texttt {isInFamily}} \sqsubseteq {\texttt {SoftwareDesignPattern}} \\ \exists {\texttt {nFR}} \sqsubseteq {\texttt {SoftwareDesignPattern}} \\ \top \sqsubseteq \forall {\texttt {isInFamily}}. {\texttt {Families}} \\ \top \sqsubseteq \forall {\texttt {nFR}}. {\texttt {NonFunctionalRequirement}} \end{array} \end{aligned}$$

The first two statements represent domain restrictions while the last two represent range ones. In other words we say that the role \({\texttt {isInFamily}}\) connects instances of the concept \({\texttt {SoftwareDesignPattern}}\) to instances of the concept \({\texttt {Families}}\) while the role \({\texttt {isInFamily}}\) relates instances of \({\texttt {SoftwareDesignPattern}}\) to instances of \({\texttt {NonFunctionalRequirement}}\).

Please note that the structure of the high level ontology we model makes it possible to easily extend it to deal also with other elements, such as Functional Requirements.

Given the ontology, we can state explicit facts about the description of a pattern in terms of pattern family it belongs to and NFRs it guarantees. These statements form the ABox of our knowledge base. Specifically, let us consider the following Fuzzy DL assertions:

$$\begin{aligned} \begin{array}{l} {\small \textsf {proxyPattern}}\text{: }{\small \textsf {SoftwareDesignPattern}} \\ {\small \textsf {resourceManagement}}\text{: }{\small \textsf {Families}} \\ {\small \textsf {reliability}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {loadBalancing}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {reusability}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {(proxyPattern,resourceManagement)}}\text{: }{\small \textsf {isInFamily}}\\ \end{array} \end{aligned}$$

That is, we introduced the pattern \({\texttt {proxyPattern}}\), the family \({\texttt {resourceManagement}}\) and the non-functional requirements \({\texttt {reliability}}\), \({\texttt {loadBalancing}}\), \({\texttt {reusability}}\) as instances/individuals of the classes \({\texttt {SoftwareDesignPattern}}\), \({\texttt {Families}}\) and \({\texttt {NonFunctionalRequirement}}\) respectively.

Based on these individuals and properties we may wish to state that the Proxy Pattern assures a high Load Balancing and a high Reliability. In order to formally represent such constraints we need to introduce new datatype properties, together with the corresponding fuzzy sets, and axioms related to the non functional requirements we just introduced. In the following we will always refer to them for every datatype property and we will use \(\mathbf R\) (for rating) to represent the interval \([{\texttt {very\,\,bad}}, {\texttt {bad}}, {\texttt {medium}},{\texttt {good}},{\texttt {very\,\,good}} ]\). The set of axioms we are going to define are needed in order to exploit the full potential of the fuzzy DL reasoning. It is noteworthy that in a production scenario, they can be automatically added to the knowledge base in a straight way. These are:

$$\begin{aligned} \begin{array}{l} \exists {\texttt {nFR}} \mathbf . \{{\texttt {reliability}} \} \equiv \exists {\texttt {reliabilityRate}} \mathbf . \in _\mathbf{R} \\ \exists {\texttt {nFR}} \mathbf . \{{\texttt {loadBalancing}} \} \equiv \exists {\texttt {loadBalancingRate}} \mathbf . \in _\mathbf{R} \\ \exists {\texttt {nFR}} \mathbf . \{{\texttt {reusability}} \} \equiv \exists {\texttt {reusabilityRate}} \mathbf . \in _\mathbf{R} \end{array} \end{aligned}$$

In the previous statements we say that whenever we have a pattern with an associated non functional requirement we will always have a corresponding degree and vice versa. Based on the datatype properties just introduced we can state, for instance, that

$$\begin{aligned} \begin{array}{l} {\small \textsf {proxyPattern}}\text{: }\exists {\small \textsf {loadBalancingRate}}\mathbf . =_{{\small \textsf {good}}} \\ {\small \textsf {proxyPattern}}\text{: }\exists {\small \textsf {reliabilityRate}}\mathbf . =_{{\small \textsf {good}}} \end{array} \end{aligned}$$

Besides the modeling of the ABox relations, we use Fuzzy DL also to explicitly model relations intercurring between NFRs. Consider the non-functional requirements load balancing, reliability, reusability previously defined as instances (individuals) of the class \({\texttt {NonFunctionalRequirement}}\). An example of mutual relation between NFRs is the one between load balancing and reliability. Indeed, they are directly proportionate, i.e., if the loadBalancing increases (decreases) the same happens for the reliability. With reference to our ontology, such a relation can be written in Fuzzy DL as

$$\begin{aligned} \begin{array}{l} \exists {\texttt {loadBalancingRate}} \mathbf . {\texttt {High}} \sqsubseteq \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {High}} \\ \exists {\texttt {loadBalancingRate}} \mathbf . {\texttt {Fair}} \sqsubseteq \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {Fair}} \\ \exists {\texttt {loadBalancingRate}} \mathbf . {\texttt {Low}} \sqsubseteq \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {Low}} \end{array} \end{aligned}$$

We also know that a system cannot be reliable and reusable at the same time. That is, the two non functional requirements are inversely proportionate. Hence, if a pattern guarantees reliability it cannot guarantees also reusability. We may encode such disjoint relations with the following statement:

$$\begin{aligned} \begin{array}{l} \exists {\texttt {reusabilityRate}} \mathbf . {\texttt {High}} \sqsubseteq \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {Low}} \\ \end{array} \end{aligned}$$

From the two relations explicitly stated before, we may imply that as the Proxy Pattern guarantees a high degree of load balancing, it cannot guarantee a high degree of reusability.

By using automated reasoning over Fuzzy DL knowledge bases we automatically infer all these kind of implicit relations thus providing better results while looking for a design solution. It is noteworthy that the Fuzzy DL we are targeting is allowed to represent also statements like: “a system with a high adaptability has a fair maintainability”. Indeed, as the system adapts its own configuration to context o requirements variations it may not be highly maintainable, i.e.,

$$\begin{aligned} \begin{array}{l} \exists {\texttt {adaptabilityRate}} \mathbf . {\texttt {High}} \sqsubseteq \exists {\texttt {maintainabilityRate}} \mathbf . {\texttt {Fair}} \\ \end{array} \end{aligned}$$

4 Use Case Scenario

We next illustrate how to apply the proposed framework by means of a use case scenario. We model the use case of a Cloud-Social-Adaptable System. In the cloud environment, let us think of an application in social domain in which the various applications (apps) share data distributed over different clusters or data centres.

The system is allowed to dynamically and extensively load external applications depending on variations in the context or depending on changes in the behavior of the user. For example, if the user is travelling for a week-end or on holiday, an app arranges all stored material related to the destination of the trip and creates albums, photo collections with captions, stories etc. Other context-dependent conditions set in the application, enable dynamic loading of different apps. Dynamically loaded applications might compromise properties of the entire system, then it is of crucial importance to provide mechanisms working at run-time and able to check and guarantee the preservation of properties of interest. All nodes in the application are started exploiting the Cloud virtualization, i.e. the physical hardware is shared between all services but the software environment is independent, ensuring low coupling between the virtual nodes. The architecture is flexible since every consumer can access a public service with the available resources, with a saving in terms of costs. Moreover, being the various virtual machines unconnected, the fault of one of them does not compromise all others, thus ensuring a good fault-tolerance in the overall architecture. Virtual machines are made up and launched directly from the middleware just as a consumer requests. The failure of a virtual machine does not affect the others. The availability of content is ensured by a content delivery network. The request for more machines avoids the single point of failure.

The implementation of the scenario previously described requires patterns satisfying characteristics derived both from the running environment and from the main features of the context. We see that such patterns should belong to families that manage Cloud features, but also must solve problems about process communication and middleware. They have to ensure adaptability being the system social-adaptable, hence it would be desirable they belong to the Adaptation and Extension family. Actually, the patterns we are looking for could also be in the Application Control family. Indeed, given the specific environment of the system, it should be necessary to separate the interface from the applications core functionalities. As for the Non Functional Requirements, the architectural model must ensure adaptability, being the system a social adaptable and elasticity since it will work in a cloud environment and will manage a large amount of data. Also fault tolerance is a requirement to be satisfied in order to ensure a dependable system. A low level of coupling is also required being the system implemented in a cloud environment. All these requirements can be summarized as:

  • belonging families: Cloud Patterns, Application Control, Adaptation and Extension, Distribution Infrastructure;

  • non functional requirements: high adaptability, high elasticity, high fault tolerance, low coupling.

Now suppose we have defined in a knowledge base \(\mathcal {K}\) (ABox and TBox) information about a set of patterns, families and NFRs. That is, the ABox contains

\( \begin{array}{@{}l} {\small \textsf {adaptationAndExtension}}\text{: }{\small \textsf {Families}} \ , \ {\small \textsf {cloud}}\text{: }{\small \textsf {Families}} \ , \ {\small \textsf {distributionInfrastructure}}\text{: }{\small \textsf {Families}} \\ {\small \textsf {applicationControl}}\text{: }{\small \textsf {Families}} \end{array} \)

\( \begin{array}{@{}l} {\small \textsf {adaptability}}\text{: }{\small \textsf {NonFunctionalRequirement}} \ , \ {\small \textsf {stability}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {maintainability}}\text{: }{\small \textsf {NonFunctionalRequirement}} \ , \ {\small \textsf {simplicity}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {dependability}}\text{: }{\small \textsf {NonFunctionalRequirement}} \ , \ {\small \textsf {redundancy}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {performance}}\text{: }{\small \textsf {NonFunctionalRequirement}} \ , \ {\small \textsf {reliability}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {elasticity}}\text{: }{\small \textsf {NonFunctionalRequirement}} \ , \ {\small \textsf {faultTolerance}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {loadBalancing}}\text{: }{\small \textsf {NonFunctionalRequirement}} \ , \ {\small \textsf {security}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {flexibility}}\text{: }{\small \textsf {NonFunctionalRequirement}} \ , \ {\small \textsf {scalability}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {coupling}}\text{: }{\small \textsf {NonFunctionalRequirement}} \ , \ {\small \textsf {robustness}}\text{: }{\small \textsf {NonFunctionalRequirement}} \\ {\small \textsf {resilience}}\text{: }{\small \textsf {NonFunctionalRequirement}} \end{array} \)

\( \begin{array}{@{}l} {\small \textsf {reflection}}\text{: }{\small \textsf {SoftwareDesignPattern}} \ , \ {\small \textsf {strictConsistency}}\text{: }{\small \textsf {SoftwareDesignPattern}} \\ {\small \textsf {hypervisor}}\text{: }{\small \textsf {SoftwareDesignPattern}} \ , \ {\small \textsf {observer}}\text{: }{\small \textsf {SoftwareDesignPattern}} \\ {\small \textsf {broker}}\text{: }{\small \textsf {SoftwareDesignPattern}} \end{array} \)

\( \begin{array}{@{}l} {\small \textsf {(reflection,adaptationAndExtension)}}\text{: }{\small \textsf {isInFamily}}\ , \ {\small \textsf {(strictConsistency,cloud)}}\text{: }{\small \textsf {isInFamily}}\\ {\small \textsf {(hypervisor,cloud)}}\text{: }{\small \textsf {isInFamily}}\ , \ {\small \textsf {(observer,applicationControl)}}\text{: }{\small \textsf {isInFamily}} \\ {\small \textsf {(broker,distributionInfrastructure)}}\text{: }{\small \textsf {isInFamily}} \end{array} \)

\( \begin{array}{@{}l} {\small \textsf {reflection}}\text{: }\exists {\small \textsf {adaptabilityRate}}\mathbf . =_{{\small \textsf {very good}}} \ , \ {\small \textsf {reflection}}\text{: }\exists {\small \textsf {stabilityRate}}\mathbf . =_{{\small \textsf {bad}}} \\ {\small \textsf {reflection}}\text{: }\exists {\small \textsf {maintainabilityRate}}\mathbf . =_{{\small \textsf {medium}}} \ , \ {\small \textsf {reflection}}\text{: }\exists {\small \textsf {simplcityRate}}\mathbf . =_{{\small \textsf {bad}}} \end{array} \)

\( \begin{array}{@{}l} {\small \textsf {strictConsistency}}\text{: }\exists {\small \textsf {dependabilityRate}}\mathbf . =_{{\small \textsf {very good}}} \ , \ {\small \textsf {strictConsistency}}\text{: }\exists {\small \textsf {redundancyRate}}\mathbf . =_{{\small \textsf {medium}}} \\ {\small \textsf {strictConsistency}}\text{: }\exists {\small \textsf {performanceRate}}\mathbf . =_{{\small \textsf {medium}}} \ , \ {\small \textsf {strictConsistency}}\text{: }\exists {\small \textsf {reliabilityRate}}\mathbf . =_{{\small \textsf {good}}} \end{array} \)

\( \begin{array}{@{}l} {\small \textsf {hypervisor}}\text{: }\exists {\small \textsf {elasticityRate}}\mathbf . =_{{\small \textsf {very good}}} \ , \ {\small \textsf {hypervisor}}\text{: }\exists {\small \textsf {redundancyRate}}\mathbf . =_{{\small \textsf {medium}}} \\ {\small \textsf {hypervisor}}\text{: }\exists {\small \textsf {faultToleranceRate}}\mathbf . =_{{\small \textsf {good}}} , \ {\small \textsf {hypervisor}}\text{: }\exists {\small \textsf {loadBalancingRate}}\mathbf . =_{{\small \textsf {good}}} \\ {\small \textsf {hypervisor}}\text{: }\exists {\small \textsf {securityRate}}\mathbf . =_{{\small \textsf {good}}} \end{array} \)

\( \begin{array}{@{}l} {\small \textsf {observer}}\text{: }\exists {\small \textsf {flexibilityRate}}\mathbf . =_{{\small \textsf {good}}} \ , \ {\small \textsf {observer}}\text{: }\exists {\small \textsf {scalabilityRate}}\mathbf . =_{{\small \textsf {medium}}} \\ {\small \textsf {observer}}\text{: }\exists {\small \textsf {adaptabilityRate}}\mathbf . =_{{\small \textsf {medium}}} \end{array} \)

\( \begin{array}{@{}l} {\small \textsf {broker}}\text{: }\exists {\small \textsf {loadBalancingRate}}\mathbf . =_{{\small \textsf {very good}}} \ , \ {\small \textsf {broker}}\text{: }\exists {\small \textsf {robustnessRate}}\mathbf . =_{{\small \textsf {medium}}} \\ {\small \textsf {broker}}\text{: }\exists {\small \textsf {faultToleranceRate}}\mathbf . =_{{\small \textsf {bad}}} \ , \ {\small \textsf {broker}}\text{: }\exists {\small \textsf {performanceRate}}\mathbf . =_{{\small \textsf {medium}}} \\ {\small \textsf {broker}}\text{: }\exists {\small \textsf {reliabilityRate}}\mathbf . =_{{\small \textsf {good}}} \ , \ {\small \textsf {broker}}\text{: }\exists {\small \textsf {resilienceRate}}\mathbf . =_{{\small \textsf {good}}} \end{array} \)

Eventually, the TBox contains

\( \begin{array}{@{}l} \exists {\texttt {flexibilityRate}} \mathbf . {\texttt {High}} \sqsubseteq \exists {\texttt {couplingRate}} \mathbf . {\texttt {Low}} \\ \end{array} \)

\( \begin{array}{@{}l} \exists {\texttt {elasticityRate}} \mathbf . {\texttt {High}} \sqsubseteq \exists {\texttt {adaptabilityRate}} \mathbf . {\texttt {High}} \\ \exists {\texttt {elasticityRate}} \mathbf . {\texttt {Fair}} \sqsubseteq \exists {\texttt {adaptabilityRate}} \mathbf . {\texttt {Fair }} \\ \exists {\texttt {elasticityRate}} \mathbf . {\texttt {Low}} \sqsubseteq \exists {\texttt {adaptabilityRate}} \mathbf . {\texttt {Low}} \\ \end{array} \)

\( \begin{array}{@{}l} \exists {\texttt {robustnessRate}} \mathbf . {\texttt {High}} \sqsubseteq \exists {\texttt {faultToleranceRate}} \mathbf . {\texttt {High}} \\ \exists {\texttt {robustnessRate}} \mathbf . {\texttt {Medium}} \sqsubseteq \exists {\texttt {faultToleranceRate}} \mathbf . {\texttt {Medium}} \\ \exists {\texttt {robustnessRate}} \mathbf . {\texttt {Low}} \sqsubseteq \exists {\texttt {faultToleranceRate}} \mathbf . {\texttt {Low}} \\ \end{array} \)

\( \begin{array}{@{}l} \exists {\texttt {faultToleranceRate}} \mathbf . {\texttt {High}} \sqsubseteq \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {High}} \\ \exists {\texttt {faultToleranceRate}} \mathbf . {\texttt {Medium}} \sqsubseteq \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {Medium}} \\ \exists {\texttt {faultToleranceRate}} \mathbf . {\texttt {Low}} \sqsubseteq \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {Low}} \\ \end{array} \)

\( \begin{array}{@{}l} \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {High}} \sqsubseteq \exists {\texttt {dependabilityRate}} \mathbf . {\texttt {High}} \\ \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {Medium}} \sqsubseteq \exists {\texttt {dependabilityRate}} \mathbf . {\texttt {Medium}} \\ \exists {\texttt {reliabilityRate}} \mathbf . {\texttt {Low}} \sqsubseteq \exists {\texttt {dependabilityRate}} \mathbf . {\texttt {Low}} \\ \end{array} \)

\( \begin{array}{@{}l} \exists {\texttt {loadBalancingRate}} \mathbf . {\texttt {High}} \sqsubseteq \exists {\texttt {elasticityRate}} \mathbf . {\texttt {High}} \\ \exists {\texttt {loadBalancingRate}} \mathbf . {\texttt {Medium}} \sqsubseteq \exists {\texttt {elasticityRate}} \mathbf . {\texttt {Medium}} \\ \exists {\texttt {loadBalancingRate}} \mathbf . {\texttt {Low}} \sqsubseteq \exists {\texttt {elasticityRate}} \mathbf . {\texttt {Low}} \\ \end{array} \)

In order to get the best set of patterns satisfying the requirements needed to solve the task, we need a reasoning method for retrieving more suitable patterns according to given requirements.

The set of retrived pattern should be incrementally built considering subsets of the original requirements:

Specifically, let us start with the subset

  • belonging families: Adaptation and Extension;

  • non functional requirements: adaptability.

The formula modeling the previous requirements is thus:

$$\begin{aligned} \begin{array}{l} C' = \exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {adaptationAndExtension}}\} \sqcap \exists {\small \textsf {{\texttt {adaptabilityRate}}}}.{{\texttt {High}}}\mathbf . \end{array} \end{aligned}$$

Therefore, the retrieved ranked list of top-3 patterns satisfying \(C'\) would be: \(\langle {\small \textsf {reflection}},\) \( {\small \textsf {strictConsistency}},\) \( {\small \textsf {hypervisor}}\rangle \) When we defined \(C'\) we assumed the patterns we were looking for belonged only to the Adaptation and Extension family. Actually, we may look also for patterns in other families which satisfy the adaptability NFR. We then extend the previous subset with

  • belonging families: Cloud Patterns, Application Control, Adaptation and Extension, Distribution Infrastructure;

  • non functional requirements: adaptability.

In order to model such a more relaxed requirement we modify \(C'\) in \(C_1\) as

$$\begin{aligned} \begin{array}{lcl} {C_1} &{} = &{} (\exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {adaptationAndExtension}}\}~ \sqcup ~ \exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {cloud}}\}~ \sqcup ~ \\ &{}&{} \exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {applicationControl}}\}~ \sqcup ~\exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {distributionInfrastructure}}\} )~ \sqcap ~ \\ &{}&{} \exists {\small \textsf {{\texttt {adaptabilityRate}}}}.{{\texttt {High}}}\mathbf . \end{array} \end{aligned}$$

With respect to the newly stated requirements, the retrieved ranked list of patterns is: \(\langle {\small \textsf {hypervisor}},\) \( {\small \textsf {reflection}},\) \( {\small \textsf {observer}} \rangle \) with hypervisor and reflection in the same ranking position, and observer that can be equivalently substituted by \({\small \textsf {broker}}\).

We may also define \(C_2\), \(C_3\) and \(C_4\)

$$\begin{aligned} \begin{array}{lcl} {C_2} &{} = &{} (\exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {adaptationAndExtension}}\}~ \sqcup ~ \exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {cloud}}\}~ \sqcup ~ \\ &{}&{} \exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {applicationControl}}\}~ \sqcup ~\exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {distributionInfrastructure}}\} )~ \sqcap ~ \\ &{}&{} \exists {\small \textsf {{\texttt {elasticityRate}}}}.{{\texttt {High}}}\mathbf . \end{array} \end{aligned}$$
$$\begin{aligned} \begin{array}{lcl} {C_3} &{} = &{} (\exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {adaptationAndExtension}}\}~ \sqcup ~ \exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {cloud}}\}~ \sqcup ~ \\ &{}&{} \exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {applicationControl}}\}~ \sqcup ~\exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {distributionInfrastructure}}\} )~ \sqcap ~ \\ &{}&{} \exists {\small \textsf {{\texttt {faultToleranceRate}}}}.{{\texttt {High}}}\mathbf . \end{array} \end{aligned}$$
$$\begin{aligned} \begin{array}{lcl} {C_4} &{} = &{} (\exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {adaptationAndExtension}}\}~ \sqcup ~ \exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {cloud}}\}~ \sqcup ~ \\ &{}&{} \exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {applicationControl}}\}~ \sqcup ~\exists {\small \textsf {isInFamily}}\mathbf . \{{\small \textsf {distributionInfrastructure}}\} )~ \sqcap ~ \\ &{}&{} \exists {\small \textsf {{\texttt {couplingRate}}}}.{{\texttt {Low}}}\mathbf . \end{array} \end{aligned}$$

Hence, the best solution is to adopt both broker and hypervisor, then we have the pair reflection, broker and eventually observer, broker.

5 Related Work

In this section we briefly review the literature on knowledge representation approaches architectural concerns such as nonfunctional requirements, design pattern and service composition.

QoS aspects of Service composition are studied in [7, 18]. While Architectural concerns about services and future Internet applications are considered in [3, 14, 16]. Temporal behavior of design patterns are modeled in [20] using formal methods. A Balanced Pattern Specification Language (BPSL) is modeled in [25] based on a subset of First Order Logic and Temporal Logic of Action to specify both structural and behavioral aspects of patterns [26]. Relationships among design pattern as architectural tactics and architecture are studied in [13]. Pattern languages connect patterns from a variety of different sources into a single pattern network [17]; they are supported by trees or directed graphs and enable typical search algorithms of depth-first or breadth-first. Anyway the modeling of relationships and sequences of patterns and the taxonomy of the several issues concerned with their use needs a more structured approach with respect to data structures such as trees or directed graphs, due to the complex semantics they convey. A state of the art on the treatment of non-functional requirements is in [8]. Definitions of non-functional requirements are surveyed in [10, 12]. In [4] a model of non-functional requirements is given.

Mylopoulos et al. propose two complementary approaches for using non-functional information: process-oriented and product oriented, [21]. State of the art of Model Driven Development approaches with respect to non-functional requirements is in [1], where also a framework for integrating NFRs in the core of Model Driven Development process is given [28].

6 Conclusion and Future Work

In this paper we proposed to use a Fuzzy Description Logic (DL) to model the knowledge related to NFRs, patterns and related families in order to ease and support software components integration and composition in architectural decision making problems.

Although the overall framework has been presented to deal with NFRs, thanks to its declarative nature, it can be easily extended to other characteristics such as Functional Requirements.

We are currently working on how to take into account also information related to temporal interaction among software components thus extending the Fuzzy DL we propose with temporal operators. We are also performing extensive experiments on a structured benchmark to test the framework functionalities and performance on simple and on composable schemes also in more advanced architectural environments.