business-rules https://www.e-learn.cn/tag/business-rules zh-hans Rule development and deployment management with Drools Guvnor https://www.e-learn.cn/topic/4030388 <span>Rule development and deployment management with Drools Guvnor</span> <span><span lang="" about="/user/230" typeof="schema:Person" property="schema:name" datatype="">不问归期</span></span> <span>2021-01-28 20:22:21</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><h2>Introduction</h2> <p>Drools Guvnor has it's own versioning system, that in production use allows the users of an application to modify the rules and decision tables in order to adapt to change in their business. Yet, the same assets continue to live on the development version control system, where new features to the app are developed.</p> <p>This post is for looking insight/ideas/experience on rule development and deployment when working with Drools rules and Guvnor.</p> <p>Below are some key concepts I've been puzzling about.</p> <h2>Deployment to Guvnor</h2> <p>First of all, what is the best way to deploy the drl files and decision tables to production environment? Just simply put them on a zip package and then unzip to Web-Dav folder? What I have navigated around Drools, I haven't found a way to import more than one file at a time. The fact model can be added as a jar archive, though. Guvnor seems to have a REST API of some sort, but using that would require custom deployment scripts.</p> <h2>Change management</h2> <p>Secondly, once the application is in production, the users will likely want to change the values in decision tables in order to set the discount percentages to higher for premium clients etc. This is all fine and dandy, until comes the time to start development of version 2.0 of the app.</p> <p>Now what we have at this point is</p> <ul><li>drl files and decision tables in <strong>version controlling system</strong></li> <li>drl files and decision tables in production environment with user modifications, <strong>versioned by Guvnor</strong></li> </ul><p>Now we are in the point of getting the rules and decision tables back from the Guvnor. And again is the Web-Dav folder the best for this, what other options there are?</p> <p>Merge tools today can even handle Excel file diffs, but sounds like a merge hell to me on a big scale projects.</p> <h2>Keeping the fact model backwards compatible</h2> <p>Yet another topic is fact model integrity. For the assumed version 2.0, developers always want to make refactoring and tear the whole fact model upside down. Still, it must remain backwards compatible with the previous versions as there may be user modified rules that depend on that. Any tips on this? Just keep the fact model simple and clean? Plan ahead / suggest what the users could want to change?</p> <h2>Summary</h2> <p>I'm certain I'm not the first, and surely not the last, to consider options on deployment and change management with Drools and Guvnor. So, what I'd like to hear is comment, discussion, tips etc. on some best (and also the worst in order to avoid them) practices to handle these situations.</p> <p>Thanks.</p> <br /><h3>回答1:</h3><br /><p>The best way to do things depends very much on your specific application and the environment you work in. However the following are pointers from my own experience. Note that I'll add just a few points for now. I'll probably come back to this answer when things come to me.</p> <p><strong>After the initial go-live, keep releases incremental and small</strong></p> <p>For your first release you have the opportunity to try things out. Take advantage of this opportunity, and do as much refactoring as possible, because...</p> <p>Your application has gone live and your business users are maintaining rules in decision tables. You have made great gains in what folks in the industry like to call "business agility". Unfortunately, this tends to be at the expense of application development agility. All of your guided editor rules and decision table rules are tied to your fact model, so any changes existing properties of that fact model will break your decision tables. Unlike in most IDEs these days, you can't just right-click on a fact's getX() method, rename it, and expect all code which relies on that property to be updated.</p> <p>Decision tables and guided rules are hard to refactor. If a fact has been renamed, then in many (all?) versions of Guvnor, that rule/table will no longer open. You need to get at the underlying XML file via WebDav and do some text searching and replacing. That may be very difficult, considering that to do this, you need to download the file from production to a test environment, make changes, test them, deploy them to a test environment. When you're happy with your changes you need to push them back up to the 'production' Guvnor. Unfortunately, while you were doing that, the users have updated a number of decision tables and you need to either start again, or re-apply the past couple of days' changes. In an ideal world, your business users will agree to make no rule changes for a period of time. But the only way to make that feasible is to keep the changes small so that you can make them in a couple of hours or a day depending on how generous they feel.</p> <p>To mitigate this:</p> <ol><li>Keep facts used within Guvnor separate from your application domain classes. Your application developers can then refactor the internal application model to their hearts content, but such changes will not affect the business model. Maintain mappings between the two and ensure there are tests covering those mappings.</li> <li>Avoid changes such as renaming facts or their properties. Make sure that facts you create and their properties have names which suit the domain and agree these with the business. On the other hand, adding a new property is relatively painless. It is well worth prompting the users to give you an eye on their future plans.</li> <li>Keep facts as simple as possible. Don't go more complex than name-value pairs unless you really need to. For one thing, your business users will find it much easier to maintain rules. Your priority with anything managed within Guvnor should always be about making it easy for business users to maintain.</li> <li>Keep external dependencies out of your facts. A developer may think it's a good idea to annotate a fact as a JPA @Entity, for easy persistence. Unfortunately, that adds dependencies which need to be added to Guvnor's classpath, requiring a restart.</li> </ol><p><strong>Tips &amp; tricks</strong></p> <p>My personal technique for making cross-environment changes is to connect Eclipse to two Guvnor WebDav directories, and checkout the rules into local directories, where each local directory maps to an environment. I then use the Eclipse diff tooling.</p> <p>When building a Guvnor-managed knowledge base, I create a separate Maven project containing only the facts, and with no dependencies on anything else. It makes it a lot easier to keep them clean this way. Also, when I really do need to add a dependency (i.e. I use JodaTime where possible), then the build can have a step to generate a shaded JAR containing all the dependencies. That way you only ever deploy one JAR to Guvnor, which is guaranteed to contain the correct versions of your dependencies. </p> <p>I'm sure there will be more that I think of. I'll try to remember to come back to this...</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/19964082/rule-development-and-deployment-management-with-drools-guvnor</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/drools" hreflang="zh-hans">drools</a></div> <div class="field--item"><a href="/tag/rule-engine" hreflang="zh-hans">rule-engine</a></div> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> <div class="field--item"><a href="/tag/drools-guvnor" hreflang="zh-hans">drools-guvnor</a></div> <div class="field--item"><a href="/tag/guvnor" hreflang="zh-hans">guvnor</a></div> </div> </div> Thu, 28 Jan 2021 12:22:21 +0000 不问归期 4030388 at https://www.e-learn.cn How to solve this exercise about Oracle Triggers https://www.e-learn.cn/topic/3952917 <span>How to solve this exercise about Oracle Triggers</span> <span><span lang="" about="/user/240" typeof="schema:Person" property="schema:name" datatype="">北慕城南</span></span> <span>2020-12-06 08:22:08</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I have to solve this exercise about triggers:</p> <blockquote> <p>Consider the following relational database schema used to represent project information:</p> <p>Person (ID, Surname, Name, Nationality)</p> <p>Project (Name, Manager, StartingYear, NumPeopleInvolved, International)</p> <p>Personnel (Project, PersonID)</p> <p>Specify the triggers required in Oracle to maintain the following integrity constraints:</p> <p>a) The number of people involved in a project (attribute NumPeopleInvolved) must be consistent with the number of tuples entered in Personnel for that project</p> <p>b) If the project is international (the International attribute assumes only two values) then the project must involve at least two people of different nationalities</p> </blockquote> <p>I have a problem with the b) part.</p> <p>I don't know how to handle the case in which a given Project has no people involved. If I try to insert the first people, I can not have two people of different nationalities since I have only one people.</p> <p>How should this situation be handled?</p> <p>Should I use a statement level trigger? I have not experience with triggers so I still haven't understood well what I can / I can't do with one kind of trigger.</p> <p>I tried this way but it's clearly not working as it should:</p> <pre><code>CREATE TRIGGER InsertPersonnelInternational AFTER INSERT ON Personnel FOR EACH ROW BEGIN SELECT ProjectName FROM Personnel INNER JOIN Project WHERE PersonID = :new.ID Project = Name SELECT International FROM Personnel INNER JOIN Project ON Project = Name SELECT COUNT(*) AS NumPersonnel FROM Personnel WHERE Project = :new.Project IF NumPersonnel &gt;= 1 THEN BEGIN SELECT COUNT(*) AS NumNationalities FROM Personnel INNER JOIN Person ON Project = ProjectName GROUP BY Nationality IF International THEN IF NumNationalities = 1 Then BEGIN raise_application_error(-1) END ELSE IF NumNationalities &lt;&gt; 1 THEN BEGIN raise_application_error(-1) END END END END </code></pre> <br /><h3>回答1:</h3><br /><p>The best way to do this is with a compound trigger. With a compound trigger we avoid the problem of mutating tables which we would get from a row level trigger on PERSONNEL.</p> <p>We keep track of each project which is referenced by each affected row in a DML statement (insert, update, delete) in an array. At the end of the statement we query those projects to find whether the project is international, and if it is to check the nationalities of its assigned personnel.</p> <p>It might look like this:</p> <pre><code>CREATE OR REPLACE TRIGGER international_project_trg FOR insert or update or delete ON personnel COMPOUND TRIGGER -- Global declaration type project_t is table of number index by personnel.project%type; g_project project_t; BEFORE EACH ROW IS BEGIN CASE -- we don't care about the value here, we just what a set of distinct projects WHEN INSERTING THEN g_project(:new.project) := 1; WHEN UPDATING THEN g_project(:new.project) := 1; WHEN DELETING THEN g_project(:old.project) := 1; END CASE; END BEFORE EACH ROW; AFTER STATEMENT IS l_project personnel.project%type; l_country_cnt pls_integer; l_people_cnt pls_integer; BEGIN l_project := g_project.first(); while l_project is not null loop select count(distinct ppl.nationality) ,count(*) into l_country_cnt ,l_people_cnt from personnel per join project prj on per.project = prj.name join person ppl on per.personid = ppl.id where per.project = l_project and prj.international = 'Y'; if l_people_cnt &lt;= 1 then -- either not international project or only one assigned person -- so we don't care null; elsif l_country_cnt &lt;= 1 then raise_application_error(-20999, l_project ||' must have multi-national team membership'); end if; l_project := g_project.next(l_project); end loop; END AFTER STATEMENT; END international_project_trg; </code></pre> <p>Here is a working demo on db&lt;&gt;fiddle. You can see that although the trigger allows for an international project to have only one assigned person it throws an error when we add a second person of the same nationality. We can solve this by inserting rows in a special order, or better by inserting a set of rows. This is a problem with apply such business rules.</p> <p>You can use the same approach (in the same trigger) to check that whether the number of assigned personnel meets the <code>Project.NumPeopleInvolved</code> rule.</p> <hr /><p>Note: compound triggers arrived in Oracle 11gR1.</p> <br /><br /><br /><h3>回答2:</h3><br /><p>I think the following should work with insertions, deletions and updates on table Personnel. It simply check and update the international consistency for each project whether the table Personnel is altered.</p> <pre><code>CREATE TRIGGER UpdateInternationalProject AFTER INSERT OR UPDATE OR DELETE ON Personnel BEGIN SELECT name, international FROM Project AS ProjectInternational; FOR projectInfo IN ProjectInternational LOOP SELECT COUNT(DISTINCT nationality) AS numNationalities FROM Personnel INNER JOIN Person ON personId = id WHERE project = projectInfo.name; IF numNationalities = 1 THEN IF projectInfo.international THEN UPDATE Project SET international = 0 WHERE name = projectInfo.name; END IF; ELIF numNationalities &gt; 1 THEN IF NOT projectInfo.international THEN UPDATE Project SET international = 1 WHERE name = projectInfo.name; END IF; END IF; END LOOP; END; </code></pre> <br /><br /><br /><h3>回答3:</h3><br /><p>When you have a row-level trigger on table <code>Personnel</code> then you cannot run any SELECT on table <code>Personnel</code> within the trigger - you will get an <code>ORA-04091: table PERSONEL is mutating ...</code> error.</p> <p>I think your teacher is expecting something like this:</p> <pre><code>CREATE TRIGGER ProjectConsistency BEFORE INSERT OR UPDATE ON PROJECT FOR EACH ROW p_count INTEGER; n_count INTEGER; BEGIN SELECT COUNT(*) INTO p_count FROM Personnel WHERE PROJECT = :new.NAME; IF :new.NumPeopleInvolved &lt;&gt; p_count THEN RAISE_APPLICATION_ERROR(-20010, 'The number of people involved in a project must be consistent with the number of tuples entered in Personnel for that project'); END IF; IF :new.International = 'YES' THEN SELECT COUNT(DISTINCT Nationality) INTO n_count FROM Personnel WHERE PROJECT = :new.NAME; IF n_count &lt; 2 THEN RAISE_APPLICATION_ERROR(-20010, 'The project must involve at least two people of different nationalities') END IF; END IF; END; </code></pre> <p>In reality you would not implement such requirement with a trigger, you would use a PL/SQL procedure.</p> <p>Attribute <code>NumPeopleInvolved</code> is useless, i.e. redundant. Typically you would solve it by</p> <pre><code>UPDATE PROJECT proj SET NumPeopleInvolved = (SELECT COUNT(*) FROM Personnel p WHERE PROJECT = :new.NAME) WHERE NAME = :new.NAME; </code></pre> <p>Such an update could be done by a trigger, for example.</p> <p>Actually you would need similar triggers also on table <code>Personnel</code> and <code>Person</code>, because the personel/persons may change and project would become inconsistent. I don't know whether this should be considered by the exercise.</p> <p>Imagine, on person gets released, i.e. deleted from table Person:</p> <ul><li>would the application raise an error - person cannot be released (what happens if the person dies by Corona :-))?</li> <li>would be project be invalid?</li> <li>would be project be automatically updated?</li> </ul><p>Then, you should <strong>never</strong> raise errors like <code>raise_application_error(-1)</code> - always let the user know what went wrong!</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/64461580/how-to-solve-this-exercise-about-oracle-triggers</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/oracle" hreflang="zh-hans">Oracle</a></div> <div class="field--item"><a href="/tag/triggers" hreflang="zh-hans">triggers</a></div> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> </div> </div> Sun, 06 Dec 2020 00:22:08 +0000 北慕城南 3952917 at https://www.e-learn.cn Using the “extends” functionality in drools spreadsheets? https://www.e-learn.cn/topic/3311968 <span>Using the “extends” functionality in drools spreadsheets?</span> <span><span lang="" about="/user/67" typeof="schema:Person" property="schema:name" datatype="">孤人</span></span> <span>2020-01-25 21:09:48</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I have a question about using a certian drools functionality in drools decision spreadsheet, that would help a lot in reducing the files and making them more readable.</p> <p>I can't add more than two links so please downlad this .zip file that includes: Version1.PNG, Version1.drl, Version2.PNG, Version2.drl, Version3desired.drl</p> <p>http://s000.tinyupload.com/?file_id=89653236807266194978</p> <p>So here is the sample rule that we are using right now (something similar)Version1.PNG</p> <p>And this when converted to a drl gives us the following 193 line long drl file. (Version1.drl)</p> <p>It is ok and it works well, but after some research we found out we could use the "extends" functionality in drl.</p> <p>And it works in a drl, what I would like to know is how would I use it in an Excel spreadsheet?</p> <p>I designed the rule in this way: Version2.PNG</p> <p>Clearly this is not how "extends" should be used in Excel, since this returns the following drl (Version2.drl)</p> <p>You can see the extends is inside the "" of the rule name. Makes sense I guess, what I woudl like to know however is, how would I use it correctly? a seperate column? That didn't work, at least not the way I did it. </p> <p>Does anyone know how It should be done? </p> <p>The correct DRL that should be made after the Excel is converted is this: (Version3desired.drl)</p> <p>Thank you for any help :) Cheers!</p> <br /><h3>回答1:</h3><br /><p>There is no gain in using extends with spreadsheets in the way you describe it in your question. </p> <p>I suggest that you stick to the spreadsheet layout shown in <code>Version1.png</code>. If data entry personnel complains about the dull repetition of 1/7/30 in oodles of rows, teach them how to join cells so they need to type each value only once.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/43277402/using-the-extends-functionality-in-drools-spreadsheets</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/excel" hreflang="zh-hans">excel</a></div> <div class="field--item"><a href="/tag/jboss" hreflang="zh-hans">jboss</a></div> <div class="field--item"><a href="/tag/drools" hreflang="zh-hans">drools</a></div> <div class="field--item"><a href="/tag/extends" hreflang="zh-hans">extends</a></div> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> </div> </div> Sat, 25 Jan 2020 13:09:48 +0000 孤人 3311968 at https://www.e-learn.cn Bounded contexts sharing a same aggregate https://www.e-learn.cn/topic/3131210 <span>Bounded contexts sharing a same aggregate</span> <span><span lang="" about="/user/15" typeof="schema:Person" property="schema:name" datatype="">假装没事ソ</span></span> <span>2020-01-06 13:11:03</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>DDD exposes bounded contexts, domain models, aggregates... but I often miss the keypoint of business rules. I would like to know how business rules integrate into this approach. Here is an example :</p> <p>Imagine you have 2 bounded contexts in a credit company. One for debt recovery, the other for early refunds. These contexts embed real business specificities. In a conceptual point of view, I think these bounded contexts should separately embed common model parts, and similar domain model entities (graph of 3 or 4 accountancy entities). Even if their respective models embed a common submodel (we do not plan it can change), business rules that apply to these submodels are different. A DebtRecoveryService ensures rules are correctly applied, and another EarlyFundsService does the same, with specific accountancy rules. </p> <ul><li>Should this submodel be embedded and "served to others" by another dedicated bounded context if different business rules apply to them (in terms of maths and respective behaviours ?).</li> <li>What defines an aggregate, is it only a part of a model ?</li> <li>Do specific business rules define specific aggregates ? </li> </ul><p><em>Do you think an aggregate should be considered only for the entity graph it represents, and be "reused" by other bounded contexts. Is it a good case for CQRS ?</em></p> <p>Thanks,</p> <br /><h3>回答1:</h3><br /><p>It seems pretty clear that according to DDD you <em>should</em> duplicate you models when they are shared by different bounded domains.</p> <p>Also service patterns encourage not using the same object on both sides of the service.</p> <p>However. If you are using POCO style data objects and encapsulating business logic in services rather than the classic OO object graph approach, you are essentialy employing multiple patterns to protect yourself from the same issue. </p> <p>In this case the benefits of code reuse from having a shared common model could out-weigh the potential tech debt should the domain meaning of that model drift apart between bounded contexts over time.</p> <p>Essentialy though this could happen with in a bounded context. I feel your question could boil down to "Have I chosen the correct bounded contexts?" which of course is subjective.</p> <br /><br /><br /><h3>回答2:</h3><br /><p>One basic rule is that Domain Services should only be used <strong>when some domain logic doesn't seem to fit in any Entity</strong>. Domain Services <em>are not meant as Bounded Context-specific "watch dogs"</em> to control changes made to shared dumb data structures. </p> <p>If domain invariants can be contained in an Aggregate, definitely put them there -- it's normal to have two Aggregates with similar data but different rules in two BC's, that's why you have Bounded Contexts in the first place.</p> <p>As a side note, Bounded Context design is not something you should improvise. I strongly recommend reading the tactical <em>and</em> strategic patterns described in the original blue book as well as Vaughn Vernon's red book.</p> <p>Patterns such as Context Mapping or Shared Kernel, to only name a few, are helpful tools to know when designing your Bounded Contexts. BC design doesn't only depend on business concerns but also organizational factors, such as which teams will maintain the contexts, historical factors (legacy context vs greenfield one), etc. </p> <p>You'll learn about all that and a ton of other essential stuff in the books, which will hopefully dissipate the confusion you seem to be in.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/29728001/bounded-contexts-sharing-a-same-aggregate</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c" hreflang="zh-hans">c#</a></div> <div class="field--item"><a href="/tag/domain-driven-design" hreflang="zh-hans">domain-driven-design</a></div> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> </div> </div> Mon, 06 Jan 2020 05:11:03 +0000 假装没事ソ 3131210 at https://www.e-learn.cn Is using Rule Engine to implement chain of rules [complex business logic] overkill? https://www.e-learn.cn/topic/3110483 <span>Is using Rule Engine to implement chain of rules [complex business logic] overkill?</span> <span><span lang="" about="/user/48" typeof="schema:Person" property="schema:name" datatype="">白昼怎懂夜的黑</span></span> <span>2020-01-05 07:45:20</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>Recently, I am reading about the rule engines in JBOSS Drools Manual [ref - 2.2.5. Strong and Loose Coupling]. Below is the excerpt from it 'If your rules are all strongly coupled, the chances are that the rules will have future inflexibility, and more significantly, that perhaps a rule engine is overkill (as the logic is a clear chain of rules - and can be hard coded. [A Decision Tree may be in order]). This is not to say that strong or weak coupling is inherently bad, but it is a point to keep in mind when considering a rule engine and in how you capture the rules. "Loosely" coupled rules should result in a system that allows rules to be changed, removed and added without requiring changes to other rules that are unrelated.'</p> <p>Does that mean, the rule engine is not suitable option to implement complex business logic [tightly coupled rules or chain of rules]. </p> <p>In my current project, we have chain of rules i.e. outcome of 1 rule decides the outcome of another rule and so on. The application has many internal variables to chain the rules. I thought rules engine might help to handle the complexity with the added advantage of declarative rules and dynamic business logic.</p> <p>Discussion in this regard will be helpful ...</p> <br /><h3>回答1:</h3><br /><p>Some logic just isn't all that easy to get right even if you exactly know the order and nature of the tests you need to perform, and the actions that should result. Examples are Corporate Audits, Means testing for Assistance programs, Insurance regulations, etc.</p> <p>Most Rules Engines today are beginning to include a Decision Table feature, which in all reality introduces some "limited strong coupling" (I don't know if that is really a term, but it is how I understand the effect in systems such as ILog, Drools, etc.). This is helpful because some tests are just related to other tests and decision tables are far better for structuring these tests than IF THEN ELSE structures.</p> <p>Corticon (a proprietary Rules Engine) and DTRules (an open source Rules Engine) just toss the whole loosely coupled rules approach, and just build decision tables. The idea is that giving a nice structure for the construction of your decisions (which amount to decision trees underneath everything) is easier for many applications.</p> <br /><br /><br /><h3>回答2:</h3><br /><p>"Avoiding strong coupling" has nothing to do with "avoiding complexity".</p> <p>What the documentation advocates is that you should not call one rule from another, instead, each rule should produce an outcome, and the outcome itself should trigger the next rule in chain. This way rules do not concern with what happens next, and instead they deal with facts (aha!). And if - instead of writing rules for facts - you focus on writing an ordinary flow of procedural logic, you do not really need the added complexity of a rules engine.</p> <p>The difference is subtle, but not more subtle than rules like "don't put your business logic in view" or "don't put your database access code in your business logic". </p> <br /><br /><br /><h3>回答3:</h3><br /><p>In IBM ILOG Jrules there are many ways you can represent your rules. </p> <ol><li>In plain english like language , if else kind of syntax.</li> <li>decision table - for a set of value</li> <li>decision tree - multiple outcomes , branching out.</li> </ol><p>so you can decide on which way you can use the above three ways which fits to crack your complex rules into a more simpler form.</p> <p>you can use rule flow orchestration with conditional flow to tackle " outcome of 1 rule will be the input of another rule " </p> <br /><br /><br /><h3>回答4:</h3><br /><p>I think it all depends on UI, not on actual logic that the rule(s) contain(s). Remember that most of today's engines are decision-table-mentality-based. And all that "Strong and Loose Coupling" is nothing more than buzz words used as an excuse for a bad UI or lack of it. Normal engine can handle execution of a rule of any complexity. Note that this is my personal opinion, lots of folks out there would completely disagree. So, please don't rush to downgrade my answer, I'm just trying to help :)</p> <p>The typical notion is that the rule with complex logic would look really "messed up" or even impossible to implement in a decision table. Normally, guys try to combat that by dividing complex rules into smaller simple rules and stack them up into rule sets based on execution priorities.</p> <p>There are new engines that have decision-table-less UIs by implementing parentheses instead of priorities. Parentheses also help with complexity.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/6541707/is-using-rule-engine-to-implement-chain-of-rules-complex-business-logic-overki</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> </div> </div> Sat, 04 Jan 2020 23:45:20 +0000 白昼怎懂夜的黑 3110483 at https://www.e-learn.cn Validation Rules and Business Rules in MVC https://www.e-learn.cn/topic/3087198 <span>Validation Rules and Business Rules in MVC</span> <span><span lang="" about="/user/175" typeof="schema:Person" property="schema:name" datatype="">一笑奈何</span></span> <span>2020-01-04 01:24:49</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I have a MVC web project. According to best practice, where is the correct place to add my validation rules and business rules?</p> <p><strong>Validation rules</strong> would be the required fields and required formats.</p> <p><strong>Business rules</strong> would be "this email is already taken in the database"</p> <p>Here's how I am currently doing it in my <strong>register model</strong>:</p> <pre><code>public class RegisterModel : IValidatableObject { [Display(Name = "Email address")] [Required(ErrorMessage = "The email address is required")] [EmailAddress(ErrorMessage = "Invalid Email Address")] public string Email { get; set; } public IEnumerable&lt;ValidationResult&gt; Validate(ValidationContext validationContext) { var retVal = new List&lt;ValidationResult&gt;(); using (var entity = new AcademicUniteDatabaseEntities()) { if (entity.UserProfiles.Any(x =&gt; x.UserName == this.Email)) { retVal.Add(new ValidationResult("Email already exist", new List&lt;string&gt; { "Email" })); } } return retVal; } } </code></pre> <p>Here's my <strong>register controller</strong>:</p> <pre><code> public ActionResult Register() { var model = new RegisterModel(); return this.View(model); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Register(RegisterModel model) { if (!this.ModelState.IsValid) { return this.View(model); } model.CreateAccount(); return this.View("WaitConfirmEmail"); } </code></pre> <p><strong>Why I'm doing it this way</strong></p> <ol><li>When I check ModelState.IsValid in the controller, it will have checked the format of the email and if it already exists in the database. I don't make any calls to the database in my controller, only in my model. (is this best practice?)</li> <li>It also binds the "Email already exist" validation result to my Email property so I can display the validation results on my view.</li> </ol><p><strong>Is this best practice?</strong></p> <ol><li>Is this the correct way to add my business rules in MVC? </li> <li>Why or why not?</li> <li>If this is not best practice, can you provide me of an example of how this register model would be best programmed checking business rules (if email already exists)? </li> </ol><br /><h3>回答1:</h3><br /><p>One alternative is to create a custom validator attribute. With your solution, you could end up with very big models. Another alternative is to create static helpers that you can plug in the controller. There is no right answer here, it's just the way you'd like to organize code. My preference is to spread the business logic across custom attributes you can plug and play. This way you can refactor seamlessly.</p> <br /><br /><br /><h3>回答2:</h3><br /><p>Using annotations to validate your models is fine for small applications that require validation, but when your validation rules start to become more and more complicated and your models begin to get more complex then I'd suggest looking at a library like Fluent Validation. </p> <p>The problem with validate your models via attributes is it can be quite messy and you'll begin to suffer from a lot of repetition; where as the benefits you gain from using a library like Fluent Validation are:</p> <ul><li>Allows you to keep you models clean and uncluttered</li> <li>Create far more maintainable and reusable validation rules thanks to DI support.</li> <li>Isn't tied to the UI like ModelState.IsValid is, so can be reused in your business logic layer, etc.</li> </ul><p>An example of a typical Fluent Validation rule:</p> <pre><code>public class CustomerValidator: AbstractValidator&lt;Customer&gt; { public CustomerValidator() { RuleFor(customer =&gt; customer.Surname).NotEmpty(); RuleFor(customer =&gt; customer.Forename).NotEmpty().WithMessage("Please specify a first name"); RuleFor(customer =&gt; customer.Discount).NotEqual(0).When(customer =&gt; customer.HasDiscount); RuleFor(customer =&gt; customer.Address).Length(20, 250); RuleFor(customer =&gt; customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode"); } private bool BeAValidPostcode(string postcode) { // custom postcode validating logic goes here } } Customer customer = new Customer(); CustomerValidator validator = new CustomerValidator(); ValidationResult results = validator.Validate(customer); bool validationSucceeded = results.IsValid; IList&lt;ValidationFailure&gt; failures = results.Errors; </code></pre> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/29866791/validation-rules-and-business-rules-in-mvc</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/c" hreflang="zh-hans">c#</a></div> <div class="field--item"><a href="/tag/aspnet-mvc" hreflang="zh-hans">asp.net-mvc</a></div> <div class="field--item"><a href="/tag/validation" hreflang="zh-hans">validation</a></div> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> </div> </div> Fri, 03 Jan 2020 17:24:49 +0000 一笑奈何 3087198 at https://www.e-learn.cn How do you share configuration information or business rules between languages https://www.e-learn.cn/topic/2977418 <span>How do you share configuration information or business rules between languages</span> <span><span lang="" about="/user/129" typeof="schema:Person" property="schema:name" datatype="">坚强是说给别人听的谎言</span></span> <span>2019-12-28 15:34:29</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I'm looking for best practices for using the same data in different places without repeating yourself - this could include configuration or business rules.</p> <p>Example 1. Data validation rules where you want to validate on the client using javascript, but you want to make sure by validating on the server.</p> <p>Example 2. Database access where your web server and your cronjobs use the same password, username.</p> <p>Ease of processing and a human-readable solution would be a plus. </p> <br /><h3>回答1:</h3><br /><p>Encode your data in JSON. There's a JSON library for pretty much any language you'd care to think of, or if not, it's pretty easy to code one up. If JSON is not enough, perhaps look at YAML.</p> <br /><br /><br /><h3>回答2:</h3><br /><p>XML is pretty globally used. Easy to read, easy to write, and human readable. If you're concerned about the space overhead (which you actually aren't if you want human readable) then just compress it before you send it out, XML compresses quite well.</p> <br /><br /><br /><h3>回答3:</h3><br /><p>See answers to this question. I think they are applicable here, especially the one with a DSL.</p> <br /><br /><br /><h3>回答4:</h3><br /><p>As much hate as they get, for sharing data validation rules, I'm going to have to say Regular Expressions.</p> <p>I know, I know, everyone hates them, but they are (generally) language-agnostic.</p> <br /><br /><br /><h3>回答5:</h3><br /><ol><li><p>Use O/S Environment Variables (envvars) to store application configuration info (such as db passwords)</p></li> <li><p>Validation rules often require logic. You could write your rules in JavaScript, and then run them in the browser, server (using Nashorn), and database (PLV8 with Postgres).</p></li> </ol><br /><br /><p>来源:<code>https://stackoverflow.com/questions/239832/how-do-you-share-configuration-information-or-business-rules-between-languages</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/language-agnostic" hreflang="zh-hans">language-agnostic</a></div> <div class="field--item"><a href="/tag/configuration" hreflang="zh-hans">configuration</a></div> <div class="field--item"><a href="/tag/dry" hreflang="zh-hans">dry</a></div> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> </div> </div> Sat, 28 Dec 2019 07:34:29 +0000 坚强是说给别人听的谎言 2977418 at https://www.e-learn.cn How to pass a collection from a rule to a java method https://www.e-learn.cn/topic/2924944 <span>How to pass a collection from a rule to a java method</span> <span><span lang="" about="/user/137" typeof="schema:Person" property="schema:name" datatype="">独自空忆成欢</span></span> <span>2019-12-25 05:12:29</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I have a collection of Type Cars which I need to pass from the ILOG Jrules to my Java evaluation method. My Java evaluation method can accept an Object, so a collection can be accepted. I need to process the collection of cars in my Java XOM and then return some output to ILOG. But how do I create a collection of cars from my ILOG JRules? And for DVS testing, how do I pass the collection of cars from my DVS Scenario Excel sheet?</p> <br /><h3>回答1:</h3><br /><p>To clarify Tito's comment on the first answer: Well, it depends what you want to do. Without any input, it is hard to tell.</p> <p>Yes, you can send a collection as an InputParameter easily. BUT, if your business users want to author rules against the items of the collection then use [concept.insert(Object) ish to insert all your items in the working memory]. (if you want to write "if the code of the item is.." without having to say: "definitions set item to an item in the items of the shopping cart" first, for instance), and DO NOT use any loop in the rule flow. This is overkilling the perfs.<br /></p> <p>You can send to JRules a complex structured object if you wish. It is then up to you to manage how you will author rules and split the model, if needed, using pointers to objects, like a ruleset parameter being the collection "items" of your main object "shoppingCart" makes sense?</p> <br /><br /><br /><h3>回答2:</h3><br /><p>There are 2 questions there...</p> <p>1/ Why not having a JAVA method typed in your Java? Unless you cannot use Java 5 you should type your collection.</p> <p>You could have a "virtual method" with a Collection as parameter (simply add a method in your BOM, where it makes sense) and in the B2X try to cast from a collection to an Object.</p> <p>JRules is not typed because it uses 1.4, so you may be able to do so... Give it a try.</p> <p>Why would you need to pass in any Collection to your Java? Be careful not to bring back business logic in Java ;-)</p> <p>2/ DVS... how to say that... Especially with Collection as input and or output... This is shite! This is a crappy piece of code which makes the business users feels happy because they will use Excel to create the test scenario but (my friend) if you are really looking for troubles, then go for it.</p> <p>Let me clarify that:</p> <p>Input: you can have complex objects and a collection easily</p> <p>Output: this is a real pain in the back. But you can have a collection and a sorted one as well, as long as you have a Comparator in the BOM. Complex Objects... Feasible, but this requires lots of tweaks, and this is not documented.</p> <p>But you will need to do all that (prepare the Excel file) manually :(<br /> Let me give you the salesmen answer: 7.5 will allow you to do so :) Happy ??</p> <p>Now pragmatically, you can do it but with a lot of "unreadable" code in your stylesheet, meaning that your business users will not be able to use them from scratch. Maybe some of your IT team will not be able to use it. Far too much hassle. And you will have to prevent Business Users from modifying the code of the stylesheet...</p> <p>Due to this hassle, this is absolutely NOT documented, and if you really want to do that, I may have to look at an example I think I have, or you need to have a close contact in the Ilog IT team... Sorry.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/10233177/how-to-pass-a-collection-from-a-rule-to-a-java-method</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> <div class="field--item"><a href="/tag/rule-engine" hreflang="zh-hans">rule-engine</a></div> <div class="field--item"><a href="/tag/ilog" hreflang="zh-hans">ilog</a></div> <div class="field--item"><a href="/tag/jrules" hreflang="zh-hans">jrules</a></div> </div> </div> Tue, 24 Dec 2019 21:12:29 +0000 独自空忆成欢 2924944 at https://www.e-learn.cn Data driven business rules. https://www.e-learn.cn/topic/2810646 <span>Data driven business rules.</span> <span><span lang="" about="/user/214" typeof="schema:Person" property="schema:name" datatype="">半腔热情</span></span> <span>2019-12-23 10:27:10</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I am using SQL SERVER 2005.</p> <p>I have a table </p> <pre><code>table1(ID,col1,col2,col3,col4); </code></pre> <p>Now I have a business logic like:</p> <pre><code>If col1 &gt;= 126 and col2 &gt; 1 then col3 = 0 if col1 &gt;=126 and col2 &lt; 1 then col3 = col1+col4 </code></pre> <p>Now what I am trying to do is store all these rules in database and make it data driven. THe reason for that is to give the end user more flexibility. If tomorrow the business rules changes, end user have the flexibility to change it through the GUI. For eg. if tomorrow the business wants to change the comparision value from 126 to 200 they should be able to change that through the interface. As far as possible I am trying to give flexibility like ability to change columns too like business should able to change the rule so instead of col1 they can change new rules to col2. and if possible they can also have the ability to change the operators too instead of &gt;= they can change it to &lt;=.</p> <p>I want to change it more data driven so when the value is changes in the table we don't need to change the code.</p> <p>Is it possible to do this thing in database? Can someone suggest the data model that supports this business rules to be data driven?</p> <br /><h3>回答1:</h3><br /><p>Do not store code in the database. The database is for data. Code is for code.</p> <p>See the Inner-Platform Effect antipattern.</p> <p><em>Maaaybe</em> you could store values like your 126 and 200 in the database, but I'd put them in a config file. But once the users want so much flexibility that you have to design a data-driven business rules engine for them, you're totally reinventing the wheel.</p> <p>It'll be a nightmare for you in the following ways:</p> <ul><li><strong>Security risks,</strong> because user-specified expressions creates an opening for code injection attacks.</li> <li><strong>Testability,</strong> because you can't predict the ranges of operations if your rules engine includes a constructive grammar. </li> <li><strong>Performance,</strong> because users will add tons of arbitrary expressions and sorting criteria that won't go through performance testing and optimization before running on your server.</li> <li><strong>Maintenance,</strong> because users will become accustomed to the idea that they can do <em>anything</em>, but they can imagine reports far more complex than you can code your business rules to handle.</li> </ul><hr /><p>Update: there are business rules platforms such as Drools, but these should have their own language for executing business rules. SQL is not the best language to do that.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/6879853/data-driven-business-rules</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/sql-server-2005" hreflang="zh-hans">sql-server-2005</a></div> <div class="field--item"><a href="/tag/database-design" hreflang="zh-hans">database-design</a></div> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> </div> </div> Mon, 23 Dec 2019 02:27:10 +0000 半腔热情 2810646 at https://www.e-learn.cn Drools JBOSS rule Nested IF's https://www.e-learn.cn/topic/2738261 <span>Drools JBOSS rule Nested IF&#039;s</span> <span><span lang="" about="/user/98" typeof="schema:Person" property="schema:name" datatype="">六眼飞鱼酱①</span></span> <span>2019-12-22 01:15:49</span> <div class="field field--name-body field--type-text-with-summary field--label-hidden field--item"><h3>问题</h3><br /><p>I am a newbie with Jboss Rule. I have gone through the documentation but I fail to find the approach to begin writing rule for following code sample.</p> <pre><code>For each User code in the list { If User code = ‘11’ { If User code ‘17’ present in the group { Add letter id 1 } Else If User code ‘18’ present in the group { Add letter id 2 } } Else { Add letter id 3 which is the letter need to be sent for code 11 } } </code></pre> <p>I would really appreciate if anyone can give me a hint/idea how to go about it?</p> <p><strong>EDIT:</strong></p> <p>Hi,</p> <p>So far this is what i can develop for the user case discussed above.</p> <ol><li>I am inserting (List of <code>UserDetailVo</code>) to the drools session.</li> <li>Object (<code>UserDetailVo</code>) contains (List of <code>UserInfoVo</code>). Every <code>UserInfoVo</code> contains a code.</li> </ol><p>Now I want to iterate over the (List of <code>UserInfoVo</code>) and update (<code>letterId</code>) to every (<code>UserDetailVo</code>) as i am trying to do below.</p> <p><strong>Case1 : when codeList has 110,121</strong></p> <pre><code>rule "USER LETTER GROUPING 110,121" salience 300 no-loop true when userDetailVo : UserDetailVo () UserInfoVo(code=="110") from userDetailVo.codeList UserInfoVo(code=="121") from userDetailVo.codeList then userDetailVo.addLetterId(1); //modify(trrDetailRequestVo) end </code></pre> <p><strong>Case2 : when codeList has 110,127</strong></p> <pre><code>rule "USER LETTER GROUPING 110,127" salience 300 no-loop true when userDetailVo : UserDetailVo () UserInfoVo(code=="110") from userDetailVo.codeList UserInfoVo(code=="127") from userDetailVo.codeList then userDetailVo.addLetterId(2); //modify(trrDetailRequestVo) end </code></pre> <p><strong>Case3 : when codeList has only 110</strong> </p> <pre><code>rule "USER LETTER GROUPING 110" salience 300 no-loop true when userDetailVo : UserDetailVo (this.letterID.size() == 0) // Checking size of the list UserInfoVo(code=="110") from userDetailVo.codeList then userDetailVo.addLetterId(3); //modify(trrDetailRequestVo) end </code></pre> <p>Issues that I am facing is if I user modify/update at the end of rule. It goes into an infinite loop. If I remove modify/update, in case 3 though list size if greater than 0 still rule is fired.</p> <br /><h3>回答1:</h3><br /><p>The concept of "else" doesn't really translate directly to a declarative language. Instead, you have to explicitly define what "else" truly means in terms of your data and write a rule (or rules) based on that condition. As an example, consider the following conditions:</p> <pre><code>If Order Total &gt;= 1000 Discount = 15% Else If Order Total &gt;= 500 Discount = 10% Else If Order Total &gt;= 250 Discount = 5% Else Discount = 0% </code></pre> <p>The natural first attempt at rules for these conditions might be:</p> <pre><code>rule "15% discount" when $o : Order( total &gt;= 1000 ) then modify($o) { setDiscount(.15); } end rule "10% discount" when $o : Order( total &gt;= 500 ) then modify($o) { setDiscount(.10); } end etc... </code></pre> <p>The problem with this approach is that both the 10% and 15% rules will match for an Order whose total is 1200. This is because the "else" part of "else if" inherently includes the condition that the order total is not greater than 1000. So we write our rules like this instead:</p> <pre><code>rule "15% discount" when $o : Order( total &gt;= 1000, discount == null ) then modify($o) { setDiscount(.15); } end rule "10% discount" when $o : Order( total &gt;= 500, total &lt; 1000, discount == null ) then modify($o) { setDiscount(.10); } end rule "5% discount" when $o : Order( total &gt;= 250, total &lt; 500, discount == null ) then modify($o) { setDiscount(.05); } end rule "no discount" when $o : Order( total &lt; 250, discount == null ) then modify($o) { setDiscount(0); } end </code></pre> <p>(You'll notice I also added a <code>discount == null</code> condition. This is to prevent the rule from reactivating when the Order fact is updated.)</p> <p>I've been focusing on a simple example rather than your specific use case to demonstrate the concept of writing a condition to mimic an "else". I'm still not sure I completely understand your use case, but hopefully I've answered the key conceptual part of your question.</p> <br /><br /><br /><h3>回答2:</h3><br /><p>You can implement nested ifs as below:</p> <pre><code>rule "nested if else" when o: Order(total &gt;= 1000) then o.setDiscount("15%"); if(o.total&gt;=500) o.setDiscount("10%"); else if(o.total&gt;=250) o.setDiscount("5%"); else o.setDiscount("0%"); end </code></pre> <p>You can write any java code under then, example - loops, iterations, declarations etc.</p> <br /><br /><p>来源:<code>https://stackoverflow.com/questions/9771396/drools-jboss-rule-nested-ifs</code></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field--label">标签</div> <div class="field--items"> <div class="field--item"><a href="/tag/drools" hreflang="zh-hans">drools</a></div> <div class="field--item"><a href="/tag/business-rules" hreflang="zh-hans">business-rules</a></div> </div> </div> Sat, 21 Dec 2019 17:15:49 +0000 六眼飞鱼酱① 2738261 at https://www.e-learn.cn