How to improve this code

Source: Internet
Author: User
The following pseudocode shows that AServicedo2 performs operations on P, and then encounters the problem of P operations in PService. If AServicedo2 is called, it is not the latest reference to P, the changes to AServicedo2 will be overwritten during save. Update May 22, 2015 17:24:28... the following pseudo code,
AService do2 operates on P, and then the problem is that P is operated on in PService. If AService do2 is called
Because it is not the latest reference to P, the changes to AService do2 will be overwritten during save.

// Update May 22, 2015 17:24:28
@ Ke_Wu This shouldn't be a logic problem. In fact, as a later caller, I don't have to know the specific implementation in AService: do2, but now I have encountered a problem, that's the design issue.

Class AService {function do2 (pid ){... p = P. getById (pid); p.s = 'zz '; p. save ();...}} class PService {function do1 (pid ){... p = P. getById (pid); p.s = 'yy'; AService. do2 (pid );... p. a = 'a'; p. B = 'B ';... p. save (); // p.s is still yy, and zz is overwritten by yy ...}} class CService {function do4 (cid ){... c = C. getById (cid); pid = c. pid; AService. do2 (pid );...}}

Reply content:

The following pseudo code,
AService do2 operates on P, and then the problem is that P is operated on in PService. If AService do2 is called
Because it is not the latest reference to P, the changes to AService do2 will be overwritten during save.

// Update May 22, 2015 17:24:28
@ Ke_Wu This shouldn't be a logic problem. In fact, as a later caller, I don't have to know the specific implementation in AService: do2, but now I have encountered a problem, that's the design issue.

Class AService {function do2 (pid ){... p = P. getById (pid); p.s = 'zz '; p. save ();...}} class PService {function do1 (pid ){... p = P. getById (pid); p.s = 'yy'; AService. do2 (pid );... p. a = 'a'; p. B = 'B ';... p. save (); // p.s is still yy, and zz is overwritten by yy ...}} class CService {function do4 (cid ){... c = C. getById (cid); pid = c. pid; AService. do2 (pid );...}}

The problem is:

phpp1 = P.getById(pid);p1.s = 'yy';...    p2 = P.getById(pid);    p2.s = 'zz';    p2.save();...p1.save();

The modification of p2 is saved (may be saved to the database), which does not mean that the p1 in the memory is updated, unless you get it again.
The purpose of refactoring is to improve the style and Design of correct working code.
The problem with this code is a logical error. It is too early to rebuild the code.

The essence of your problem is the "Action" of two "subjects" (just services in your case) (do1 and do2) contains an identical "Action Effect" (modify the p.s value ).
Conflicts are not about services, but about redundant action effects.
Think about it. In another case, there is only one subject, and both actions (do1 and do2) belong to it, so the problem is equivalent.
The two actions have overlapping actions, which is too common.
The key lies in how do you define which overlap meets your needs? Which one is wrong or unreasonable?

Here is an example to meet your needs:
Requirement: p is a tips (interface component) with mouse hover ). First, assign the p. top value to a value based on the mouse coordinates. Then, calculate whether the tips exceeds the window edge. If yes, calculate the maximum value of tips top (because the window size may be changed, so you need to calculate), and then assign p. top to the maximum value. P. left is the same.
This is a requirement I met when developing Web Front-end services.

Your solution may solve your specific case, but it may be difficult to solve it in other cases.
In my opinion, the key lies in the effect of a series of actions caused by the source of an action (often an event). avoid overlap unless the requirements overlap.
This "Series" "serial method" should be clearly designed. You have already worked in this direction, but your focus is slightly deviated.
It does not matter whether the object (subject/object) in the process of string is a service or a service.

My solution is as follows. Please advise on any disadvantages:

Service can be divided into two types: 1, Service; 2, behavior Service
For example, UserService and RegisterService

For [term Service], each method in it must return the corresponding object. For example, the upgrade (uid) in UserService must return the updated user object.

For the behavior Service, only one execute (data) is exposed. The excute (data) must return the status of successful behavior and the object to which this behavior is applied, for example, the excute (data) in RegisterService must return whether the registration is successful or not, and the objects affected by the successful registration.

Generally, we agree to call only [behavior Service] externally, and then call multiple [noun Service] and other [behavior Service] in [behavior Service], such as in RegisterService :: execute (data) calls UserService: create (), UserService: markNewbee (uid), SendEmailService: execut (), and so on;
[Behavior Service] cannot be called in [term Service ].

The input parameters of each method of all services can be id or object instance. For example, upgrade () can accept uid or user as input parameters.

Back to my question, you can write it like this.

class AService{    function get(aid_or_object)    {        if (aid_or_object instanceOf A) {            return aid_or_object;        }        return A.getById(aid);    }}class PService{    function get(pid_or_object)    {        if (pid_or_object instanceOf P) {            return pid_or_object;        }        return P.getById(pid);    }}class Do2Service{    function execute(aid_or_object, pid_or_object = null)    {        a = AService.get(aid_or_object);        if (pid_or_object instanceOf P) {            p = pid_or_object        } else {            p = PService.get(a.pid);        }        p.s = 'zz';        p.save();        a.save();        return [:success, a, p];    }}class Do3Service{    function execute(pid_or_object)    {        p = PService.get(pid_or_object);        p.s = 'cc';        p.save();        return [:success, p];    }}class Do1Service{    function execute(pid_or_object)    {        p = PService.get(pid_or_object);        p.s = 'yy' if condition1                result, a, p = Do2Servce.execute(p.aid, p) if condition2        result, p = Do3Servce.execute(p) if condition3        p.a = 'a';        p.b = 'b';        p.save()        return [:success, p, a];    }}

What problems do you want to solve?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.