What is the better way of getting different outputs for two very simmilar related workflows

I have a very concrete scenario but I think it would be quite frequent.

I’m trying to come up with a solution that it’s “better” by better meaning more scalable, reusable and not smelly.

I’m working with very old crufty legacy code and Trying to improve it one thing at a time.
Right now I have a process in which users can “vote” “things”.

The process to determine if a user can vote is a complex logic and it may be subject to change.

Right now I have two functions, one (call it can_vote() ) takes the user and the thing and returns true or false. It’s used to know what to display to the user.

The other one is vote() It takes user and thing and and checks again all the logic that can_vote checks but instead of returning false on error throws an error that gets displayed to the user.

The system tries to never get to a state in which the user would be able to use “vote” if the result would be an exception but it still happens.

I know there may be a thousand flaws to the whole system but right now the only thing I’m trying to do is unite the logic of the two functions in one single place in the better way (as defined above).

Ideally I would like to be able to call can_vote in my controllers just getting a true or false and acting acordingly.
can_vote, being a binary question should return true|false.
I could be able to use the logic inside can_vote in places where I want to display information about “false” responses.

I’ve got multiple ideas about how to solve that but all of them seem… weird:

Possible solutions

a) use can_vote(user,thing,verbose)

verbose beeing true false
if true returns string with the error
if false returns true|false

public can_vote ( user, thing, verbose ) {
    if( user is not logged ) {
        if( verbose ) {
            throw user is not logged
        }
        return false
    }

    //all other checks
    return true
}

cons

  • returns different types depending on parameters
  • you get an if else that you carry arround the function

b) use a private function to determine if can vote. Use two helper functions

that would be something like that:

private can_really_vote ( user, thing ) {
    if( user is not logged ) {
        throw user is not logged
    }

    //all other checks
    return true

}

public can_vote ( user, thing ) {
    try {
        can_vote = this->can_really_vote( user, thing )
    }
    catch {
        //can_really_vote threw an exception
        return false
    }

    return false
}

public vote ( user, thing ) {
    if ( this->can_vote( user, thing ) ) {
        //do the vote thingy
    }
    else {
        // you shouldn't even get here. The user should have gotten an exception from can_really_vote
    }
}

c) what php usually does

That would be something like

public vote () {
    if ( can_vote() ) {
        //carry on with the voting
    }
    else {

        display can_vote_last_error()
    }
}

Things like that are usually seen in database access classes and the like.
Really? Keeping an internal trace of all those silly errors like “you are not logged”, “the contest is over” and all that stuff just to be able to recall them?
It seems quite complicated.

Of course It can be done better, for example with dedicated exceptions… doesn’t seem right dough.

I’m sure I can get more solutions… the problem boils down to wanting to get a true/false result in one case and some text on another for the same logic.

I guess the problem is quite common so there should be some software pattern for this.
Or maybe I’m being unable to abstract from it so I see the obvious elegant solution.

What would you do?

Thanks!

PS I’m almost sure it doesn’t matter but I’m working in vanilla PHP 5.3

I would recommend your solution c), but I would change it a bit: I would not display some error from the can_vote function. The user should know long before that if he can vote or not and why. The vote() function only checks if the user can vote as a safeguard, because as you said yourself there should be NO WAY your program ever calls vote() when the user is not allowed to vote. So just throw an exception or log an error.

A few comments on your other solutions:

I consider a) do be very confusing and very risky, because if you accidentally flip the verbose parameter and check the result for true/false you might think everything went fine even though you got an error message. Try debugging that problem – a nightmare!

Solution b) is just bloating of code, because all you do is wrap one function call in a try/catch and make it another function. Also, imagine a new developer in your project wants to know if a user can vote. He finds the two functions can_vote and can_really_vote – which one is he supposed to call? Needlessly confusing and no advantage whatsoever.

2

I would recommend (d) have your voting function return a result saying whether it was successful or not. Whatever mechanism you use for voting can fail, the user should be informed if that happens.

public bool vote() {
   if (!can_vote()) { return false;}

   // take whatever action you need to, prefer functions that signal failure
   return true;
}

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật