about:navigating_principle_languages
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revisionNext revisionBoth sides next revision | ||
about:navigating_principle_languages [2013-09-05 21:55] – created christian | about:navigating_principle_languages [2013-09-14 18:05] – christian | ||
---|---|---|---|
Line 6: | Line 6: | ||
- | ===== Characterizing Sets ===== | + | ===== How to Navigate |
- | A principle language cannot free the designer from actually taking a decision. There is no algorithm which replaces a sound judgment. Rather principle languages point to the relevant aspects to consider. | + | The following approach |
- | There are two typical | + | - //Starting Principles//: |
+ | - // | ||
+ | - First the characterizing set just consists of the starting principle(s). | ||
+ | - Then the following is repeated for each principle in the characterizing set | ||
+ | - Have a look at the related principles. They may or may not qualify for the characterizing set. | ||
+ | * //Contrary principles// | ||
+ | * // | ||
+ | * // | ||
+ | * // | ||
+ | - Repeat the procedure with the (now altered) characterizing set. | ||
+ | - The procedure stops when there are no further principles which qualify for the given design problem. Alternatively the procedure may be aborted if the designer already feels comfortable with making a decision. | ||
+ | - //Result//: The result is a characterizing set for the given design problem. Sets with around four or five principle are common. Characterizing sets with only one principle are rare. There may also be cases with seven or eight principles but that's also rare. | ||
- | - Given a design problem and a solution, is the solution good? | ||
- | - Given a design problem and several solutions which one is the best, i.e. the appropriate one? | ||
- | In the first case the solution can be rated according | + | Remarks: |
+ | * The procedure is not deterministic. The order in which the principles are considered, may vary. | ||
+ | * Characterizing sets are not unique for several reasons: | ||
+ | * Different starting principles may have been taken. | ||
+ | * For some principles it may be a matter of opinion whether they qualify or not. | ||
+ | * The procedure may be aborted at any time. | ||
+ | * The whole procedure is meant to be light-weight. It's not meant to be documented or otherwise to be followed pedantically. The idea is to have a lightweight approach which is not much more than a way of thinking. While inexperienced designers might want to look every principle up, more advanced ones will only need a short glance at the principle language graph. Experienced designers who do not need this kind of guidance at all can skip all that and just use the principle language as a set of vocabulary for talking about their design. So the principle language helps designers with very different levels of experience. | ||
+ | * The rationale section in the wiki may be used to justify whether a principle qualifies or not. | ||
- | For the second question all the solutions are rated. The solutions which are not pareto-optimal (see [[conflicting principles]]) are clearly bad solutions. The others are all " | ||
- | ===== Weighting Principles | + | ===== Example |
- | Note that it's not the number of principles which is essential. Weighting the principles and taking the decision is still the task of the designer. Sometimes the weights may be derived from the requirements. Where this is not possible the weighting is an expression of the personal style of the designer, the team or the project. | + | ==== Context ==== |
- | The [[principles: | + | The following |
- | Certainly some people will rather favor KISS and others will prefer DRY. Some will say one duplication is tolerable and you should only refactor when there are three similar pieces of code (see [[principles: | + | In CoCoME |
+ | * For the data layer there is a data component, a class '' | ||
+ | <code java> | ||
+ | public class DataImpl implements DataIf | ||
+ | { | ||
+ | public EnterpriseQueryIf getEnterpriseQueryIf() | ||
+ | { | ||
+ | return new EnterpriseQueryImpl(); | ||
+ | } | ||
+ | public PersistenceIf getPersistenceManager() | ||
+ | { | ||
+ | return new PersistenceImpl(); | ||
+ | } | ||
- | ===== How to Navigate ===== | + | public StoreQueryIf getStoreQueryIf() |
+ | { | ||
+ | return new StoreQueryImpl(); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
- | | + | |
- | | + | |
+ | <code java> | ||
+ | public class DataIfFactory | ||
+ | { | ||
+ | private static DataIf dataaccess = null; | ||
- | ===== Example | + | private DataIfFactory() {} |
+ | |||
+ | public static DataIf getInstance() | ||
+ | { | ||
+ | if (dataaccess | ||
+ | { | ||
+ | dataaccess | ||
+ | } | ||
+ | return dataaccess; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Essentially '' | ||
+ | [[factory: | ||
+ | |||
+ | ==== Question | ||
+ | |||
+ | //Is this a good solution?// | ||
+ | |||
+ | ==== Finding a Characterizing Set ==== | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | We will examine this question using the OOD principle language. First we have to find suitable starting principles. This is one of the rather sophisticated cases where finding a starting principle is at least not completely obvious. If we don't have a clue where to start, we'll have a look at the different categories of principles in the language. Essentially the " | ||
+ | |||
+ | Now we'll have a look at the relationships. LC lists [[principles: | ||
+ | |||
+ | * KISS | ||
+ | * The mechanism may be considered simple or complex, so KISS qualifies | ||
+ | * We'll insert it into the characterizing set: {LC, KISS} | ||
+ | * HC | ||
+ | * The mechanism does not have any influence on cohesion; HC does not qualify | ||
+ | * RoE | ||
+ | * The access to the data modules is gained implicitly, so RoE fits | ||
+ | * New characterizing set: {LC, KISS, RoE} | ||
+ | * TdA/IE | ||
+ | * Getting hold of a data module requires chained gets: '' | ||
+ | * Although we first did not think about TdA/IE, it qualifies; We'll add it: {LC, KISS, RoE, TdA/IE} | ||
+ | * MP | ||
+ | * There is no obvious model involved | ||
+ | * IH/E | ||
+ | * Does not quite fit. We might think about the data component (not) hiding some information but we can regard that a bit far-fetched. | ||
+ | * DIP | ||
+ | * Does not qualify let alone replace LC. | ||
+ | |||
+ | |||
+ | So up until now the characterizing set is {LC, KISS, RoE, TdA/IE}. Now let's examine the relationships of the newly added principles. KISS lists [[principles: | ||
+ | |||
+ | * GP | ||
+ | * Does not qualify. | ||
+ | * ML | ||
+ | * Certainly it is relevant to think about what can go wrong, so ML qualifies. | ||
+ | * {LC, KISS, RoE, TdA/IE, ML} | ||
+ | * MP | ||
+ | * Already examined above. | ||
+ | * MIMC | ||
+ | * KISS fits better | ||
+ | |||
+ | Characterizing set up until now: {LC, KISS, RoE, TdA/IE, ML}. ML was newly added. Maybe on this point we might decide to abort the process because we already have a good idea of the aspects. But for the sake of the example, we'll continue with the relationships of ML. The wiki page lists KISS as a contrary principle and [[principles: | ||
+ | |||
+ | * KISS | ||
+ | * Already examined above. | ||
+ | * DRY | ||
+ | * There is no duplication. DRY does not qualify. | ||
+ | * EUHM | ||
+ | * ML fits better. | ||
+ | * UP | ||
+ | * Whether UP qualifies or not, depends on the rest of the system, the team, other projects, etc. For the example, we'll assume that there are no other projects and parts of the system we want to be consistent with. | ||
+ | * IAP | ||
+ | * Does not fit better and adds no valuable aspect. | ||
+ | |||
+ | As a result we get {LC, KISS, RoE, TdA/IE, ML} as the characterizing set. | ||
+ | |||
+ | Note that although in this example the principles are examined in a certain order, the method does not prescribe any. | ||
+ | |||
+ | |||
+ | ==== Using the Characterizing Set ==== | ||
+ | |||
+ | In order to answer the above question, we have to informally rate the solution based on the principles of the characterizing set: | ||
+ | |||
+ | * LC | ||
+ | * The solution creates a relatively strong coupling to the concrete implementations of the components. If a class uses the " | ||
+ | * KISS | ||
+ | * The solution is pretty easy to implement. Furthermore it is easy to get access to an arbitrary component. So according to KISS this is a good solution. | ||
+ | * RoE | ||
+ | * Getting access to a component is implicit. There is no need to explicitly pass a reference around. There is not even the necessity to explicitly define an attribute for the dependent class. RoE tells, that the solution is bad. | ||
+ | * TdA/IE | ||
+ | * Getting access to a the '' | ||
+ | * ML | ||
+ | * There are no particular pitfalls with this solution. So ML has nothing against it. | ||
+ | |||
+ | So LC, RoE and TdA/IE are against the solution, KISS thinks it's good and ML has nothing against it. As it is not the number of principles which is important, the designer still has to make a sound judgment based on these results. What is more important: Coupling, testability, | ||
+ | |||
+ | ==== Deciding between Alternatives ==== | ||
+ | |||
+ | In the next step we would think about better alternatives and might come up with [[patterns: | ||
+ | |||
+ | We already constructed a characterizing set. So the only thing to do is to rate the ideas according to the principles: | ||
+ | |||
+ | The current " | ||
+ | * LC | ||
+ | * DI > SL > F | ||
+ | * Note that in the SL approach there is an additional coupling to the service locator | ||
+ | * KISS | ||
+ | * F > DI = SL | ||
+ | * All three solutions are rather simple but in DI there is complexity for passing around the references and in the SL approach there is complexity in maintaining the registry | ||
+ | * RoE | ||
+ | * The rating of RoE depends on the concrete variant of the pattern. In the DI approach the dependencies are explicitly visible on the interface, which is not the case in the two other approaches. In solution F the dependency is not visible from the interface at all. Same with SL if the service locator is globally accessible. Even if a reference to the service locator is explicitly passed around, it is still not visible which services provided by the locator are used. On the other hand getting a reference is explicit with F and SL. In the DI approach it is only explicit when it is done manually. Typical DI frameworks wire the instances implicitly. | ||
+ | * TdA/IE | ||
+ | * FIXME | ||
+ | * ML |
about/navigating_principle_languages.txt · Last modified: 2013-09-16 17:27 by christian