问:
How to encourage client to do some in house QA testing?
Update/Clarification My client understands the need for their in-house testing and he/they always swears they will "do better" (i.e. do something) but it just doesn't happen. They don't have the budget for outside testing. I guess I am asking (vaguely, I acknowledge) about what could instill a "test early, test often, test on target machines' ethos?

Question: how to encourage users to take the time to explicitly test and report issues with new releases, not to "test-as-they-go" in production projects.

Background: I have a small client for whom I have written a suite of multimedia presentation tools. They are a nice client and we have a good relationship. The project is on-going, adding features as we go along.

There are two issues I have:

Feature definition is done on-the-fly, often over the phone, subject to change, revision, reversal. (a bit of like Kennedy's "We will go to the moon and do the other things" – I've always been amused by the "other things" part of that)

Virtually no QA testing is done on their end.

I can deal with #1, more or less. This is not a client who would even read a spec before a meeting, let alone write up one. I'm used to it. It is item #2 which I have the issue with: they don't or won't test new releases. What they do is to use them for production so when bugs come up, they either find a workaround and don't report it, or they are so in a hurry to get on with the project, that bug reports are vague.

We have had many discussions about all this but I have only been able to nudge them a bit (e.g. we use github for issues tracking – though mostly I use it). The root reasons are twofold: they are a small consulting company and don't have (or don't think they have) the resources for testing (nor the budget to outsource it). And cultural: although they think of themselves as "developers" they really are just users of a multimedia software package. (e.g. they have none of the <s>obsessive neurosis</s> attention to detail of "real" developers).

This affects me as you would expect: without feedback I can't tell if a feature is complete (see #1), or if there are other consequences. It also is making me a bit lazy.

答:
they have none of the obsessive neurosis attention to detail of "real" developers

Preface: The kind of language you used here is typically a red flag for me.  When I hear people talk about "real" developers or the (one and only) "right" way of doing things, I start thinking of tunnel visionned cargo-cult developers.

Now, I'm not saying that you're definitely one of these developers (I don't have enough evidence to assert that), but if you are, then you might benefit from this answer.

Answer

It sounds like you and your client are optimizing for different things.
It's an unfortunate fact in software engineering that often the needs of the business and the desires of the developers don't necessarily line up.

Software developers are often passionate people with a focus on improvment.  They like to improve software performance, the development process, business processes, communication methods, etc.  And that's great.  Focusing on these things is what separates the craftsmen and craftswomen from the mindless keypushers.

But, your client isn't a software craftsperson.  Your client is a business with a completely different set of priorities.  And, sometimes, those priorities look ridiculous to we software craftspeople... but that's only because we're optimising for different things.

Business frequently want to optimize for things like early release to market and short term cost savings.  In doing so they may need to sacrifice things like QA, User Experience, long term cost savings, and other things that make developers tick.

Is that a bad thing?  Well, not necessarily.  I can't speak for all businesses, but in my experience my clients do these things in order to increase their own ROI (return on investment).  Doing things like QA, UX refinement, and long term planning offer them lower ROI.  Even worse, many businesses have investment structures that only reward short term wins as opposed to sustainable approaches and long term wins.

So, while you could try to sell the idea of QA to your client you may be wasting your time and straining your relationship with them.  In the best case you'll get someone eager to try out your ideas (unlikely).  In the worst case you'll have to convince the entire company to rework its incentive structures so that long term investments such as QA are rewarded.  In either case, your odds of success are low.


答:
The interesting question is when you get paid, not whether your client does any testing of their own.

if you get paid based on your time, no problem.

if you get paid in advance, no problem.

if you get paid when the client declares the project “done”, big problem.

The problem is how you can know when the client accepts the software and will pay you. This clearly doesn't work when the client continuously amends the project with vaguely defined new requests. If this means that pay day is always deferred – and becomes more unlikely by each request – this becomes untenable for you.

A fixed contract that carefully specifies all features and defines under which conditions the client will accept these features is clearly very uncomfortably strict, but it allows you to plan the project in advance (also the next project). It also guarantees you'll get your money for the software you delivered, if it lives up to the spec. In such a scenario, the only responsibility of a client is during the contract definition phase, and at the end for acceptance testing.

Such acceptance testing done by a client is separate from other forms of testing:

unit tests

system integration tests

usability tests

load tests

pre-release tests

As far as possible, you would anticipate the acceptance tests and perform them yourself before delivering the functionality as to avoid any embarrassments. Aside from acceptance tests (which only measure contract fulfilment, not software quality), all Quality Assurance is your responsibility. In particular, your client does not necessarily have a QA mindset, the necessary technical background, or the contractual obligation to do QA. Also, I find outsourcing bug hunting to the client quite unprofessional.

That is not to say that bugs wouldn't happen. Assuming you have a project-based relationship to your client, you'll want to walk a line between being courteous and rapidly providing fixes, and explaining that they have accepted the current release as sufficient for their needs – large changes require a new contract. If you have an ongoing support contract, you'll of course have to stick to your agreed service level.

In an agile setting, responding to client needs is valued more than sticking to the letter of the contract, but you'll still want to get paid. Therefore, many agile-oriented project methodologies value close client interaction, to the point that the client might become part of the team. You could then always talk to this “product owner” to clarify any necessary points. Since the PO has the authority to grant you the time to work on any feature they find valuable, this can work even when starting with vague client needs. If you do not have such a close communication, you will need to follow a more formal approach.

When you learn of new customer needs, work with the customer to translate them to requirements. This helps the client to get what they actually want.

Requirements are objectively measurable – they are either fulfilled or not. This saves the client from half-solutions that only kind of work.

All client requests must be provided in written form so that you can bill them. This protects them from being billed for stuff you just felt like working on – such as rewriting the entire interface when asking for a button to be aligned differently.

A lot of communication can be done in person or over the phone, but at the end you'll want a piece of paper to document that the client wanted you to work on these requirements. In simple cases, it might be sufficient to recap a phone call and send them an email to verify what they asked you to do.

Bug reports are always difficult. If your clients are devs themselves that should help since they can understand your needs: having clear steps to reproduce. A simple way to get powerful insight is to enable logging in the deployed software. Provided that the data privacy issues can be worked out, requiring every bug report to have the current log attached not only guarantees some written communication, but also tells you what the user actually did (in contrast to what they thought they were trying to do).

ContentLicense: CC BY-SA 3.0

Title: How to encourage client to do some in house QA testing?

Body:
Update/Clarification My client understands the need for their in-house testing and he/they always swears they will "do better" (i.e. do something) but it just doesn't happen. They don't have the budget for outside testing. I guess I am asking (vaguely, I acknowledge) about what could instill a "test early, test often, test on target machines' ethos?

Question: how to encourage users to take the time to explicitly test and report issues with new releases, not to "test-as-they-go" in production projects.

Background: I have a small client for whom I have written a suite of multimedia presentation tools. They are a nice client and we have a good relationship. The project is on-going, adding features as we go along.

There are two issues I have:

Feature definition is done on-the-fly, often over the phone, subject to change, revision, reversal. (a bit of like Kennedy's "We will go to the moon and do the other things" – I've always been amused by the "other things" part of that)

Virtually no QA testing is done on their end.

I can deal with #1, more or less. This is not a client who would even read a spec before a meeting, let alone write up one. I'm used to it. It is item #2 which I have the issue with: they don't or won't test new releases. What they do is to use them for production so when bugs come up, they either find a workaround and don't report it, or they are so in a hurry to get on with the project, that bug reports are vague.

We have had many discussions about all this but I have only been able to nudge them a bit (e.g. we use github for issues tracking – though mostly I use it). The root reasons are twofold: they are a small consulting company and don't have (or don't think they have) the resources for testing (nor the budget to outsource it). And cultural: although they think of themselves as "developers" they really are just users of a multimedia software package. (e.g. they have none of the <s>obsessive neurosis</s> attention to detail of "real" developers).

This affects me as you would expect: without feedback I can't tell if a feature is complete (see #1), or if there are other consequences. It also is making me a bit lazy.


问:
Is 4-5 years the “Midlife Crisis” for a programming career?
I’ve been programming C# professionally for a bit over 4 years now. For the past 4 years I’ve worked for a few small/medium companies ranging from “web/ads agencies”, small industry specific software shops to a small startup. I've been mainly doing "business apps" that involves using high-level programming languages (garbage collected) and my overall experience was that all of the works I’ve done could have been more professional. A lot of the things were done incorrectly (in a rush) mainly due to cost factor that people always wanted something “now” and with the smallest amount of spendable money. I kept on thinking maybe if I could work for a bigger companies or a company that’s better suited for programmers, or somewhere that's got the money and time to really build something longer term and more maintainable I may have enjoyed more in my career. I’ve never had a “mentor” that guided me through my 4 years career. I am pretty much blog / google / self taught programmer other than my bachelor IT degree.

I’ve also observed another issue that most so called “senior” programmer in “my working environment” are really not that senior skill wise. They are “senior” only because they’ve been a long time programmer, but the code they write or the decisions they make are absolutely rubbish! They don't want to learn, they don't want to be better they just want to get paid and do what they've told to do which make sense and most of us are like that. Maybe that’s why they are where they are now. But I don’t want to become like them I want to be better. I’ve run into a mental state that I no longer intend to be a programmer for my future career. I started to think maybe there are better things out there to work on. The more blogs I read, the more “best practices” I’ve tried the more I feel I am drifting away from “my reality”. But I am not a great programmer otherwise I don't think I am where I am now. I think 4-5 years is a stage that can be a step forward career wise or a step out of where you are.

I just wanted to hear what other have to say about what I’ve mentioned above and whether you’ve experienced similar situation in your past programming career and how you dealt with it. Thanks.

答:
A lot of people have basically said Learn Something, and I agree with that.  In particular, I suggest finding a domain you have a special interest in and getting good with it.  I know too many web designers who "really wanted to be 3d artists but never figured out how to do it." By far the best way to get hired for interesting projects or technologies is to have experience in other interesting projects or technologies.  An unfulfilling-but-undemanding workplace can be used to your advantage, giving you the mental breathing room to take on new concepts.

In general, the best advice I have heard in these situations is not to think positively but to think constructively.  Where am I in my career? Where do I want to be? What steps do I have to take to get from here to there?

Even taking a hands-on, holistic view of your own company's activities can be refreshing - what realistic alternatives would you implement to the workflow as it stands? are there any small components that can be introduced without too much disruption? Presenting a written proposal of a new model along with working code for a part of it shows vision as well as technical competence.  The difference between a good junior programmer and a good senior programmer is the scope of the solutions they are required to craft.

(Also, 4-and-a-bit years of a 9-5 also represents 10,000 hours put in to a field.  Not particularly relevant, but I thought it was a neat yardstick to know about!)

OwnerDisplayName: Jeff

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: Brandel Zachernuk


问:
Alternatives to Singletons for caching lists of data?
In my project, I have an abstract Cache class that allows me to populate a series of lists that globally persist throughout my application. These cache objects are thread-safe and can be manipulated as necessary, and allow for me to cut-down on the massive overhead of querying external third-party APIs directly. I've seen some serious hate for singletons, so I'm a bit curious what other options I have when this is my current use case.

I've seen dependency injection mentioned quite a bit, but I don't know if it's quite adequate or useful in this scenario.

Here is an example of my Cache abstract class:

```<code>public abstract class Cache<TU, T>
    where TU : Cache<TU, T>, new()
    where T : class
{
    private static readonly TU Instance = new TU();
    private static volatile State _currentState = State.Empty;
    private static volatile object _stateLock = new object();
    private static volatile object _dataLock = new object();
    private static DateTime _refreshedOn = DateTime.MinValue;
    private static T InMemoryData { get; set; }

    public static T Data
    {
        get
        {
            switch (_currentState)
            {
                case State.OnLine:
                    var timeSpentInCache = (DateTime.UtcNow - _refreshedOn);
                    if (timeSpentInCache > Instance.GetLifetime())
                    {
                        lock (_stateLock)
                        {
                            if (_currentState == State.OnLine) _currentState = State.Expired;
                        }
                    }
                    break;

                case State.Empty:
                    lock (_dataLock)
                    {
                        lock (_stateLock)
                        {
                            if (_currentState == State.Empty)
                            {
                                InMemoryData = Instance.GetData();
                                _refreshedOn = DateTime.UtcNow;
                                _currentState = State.OnLine;
                            }
                        }
                    }
                    break;

                case State.Expired:
                    lock (_stateLock)
                    {
                        if (_currentState == State.Expired)
                        {
                            _currentState = State.Refreshing;
                            Task.Factory.StartNew(Refresh);
                        }
                    }
                    break;
            }

            lock (_dataLock)
            {
                if (InMemoryData != null) return InMemoryData;
            }

            return Data;
        }
    }

    public static T PopulateData()
    {
        return Data;
    }

    protected abstract T GetData();

    protected virtual TimeSpan GetLifetime()
    {
        return TimeSpan.FromMinutes(10);
    }

    private static void Refresh()
    {
        if (_currentState != State.Refreshing) return;
        var dt = Instance.GetData();
        lock (_stateLock)
        {
            lock (_dataLock)
            {
                _refreshedOn = DateTime.UtcNow;
                _currentState = State.OnLine;
                InMemoryData = dt;
            }
        }
    }

    public static void Invalidate()
    {
        lock (_stateLock)
        {
            _refreshedOn = DateTime.MinValue;
            _currentState = State.Expired;
        }
    }

    private enum State
    {
        Empty,
        OnLine,
        Expired,
        Refreshing
    }
}
</code>```

And an example of its implementation.

```<code>public class SalesForceCache
{
    public class Users : Cache<Users, List<Contact>>
    {
        protected override List<Contact> GetData()
        {
            var sf = new SalesForce();
            var users = sf.GetAllUsers();

            sf.Dispose();

            return users;
        }

        protected override TimeSpan GetLifetime()
        {
            try
            {
                return TimeSpan.FromDays(1);
            }
            catch (StackOverflowException)
            {
                return TimeSpan.Zero;
            }
        }
    }

    public class Accounts : Cache<Accounts, List<Account>>
    {
        protected override List<Account> GetData()
        {
            var sf = new SalesForce();
            var accounts = sf.GetAllAccounts();

            sf.Dispose();

            return accounts;
        }

        protected override TimeSpan GetLifetime()
        {
            try
            {
                return TimeSpan.FromDays(1);
            }
            catch (StackOverflowException)
            {
                return TimeSpan.Zero;
            }
        }
    }
}
</code>```

答:
You can create one cache instance per third-party API instance.  If your third-party APIs do not come in instances, then encapsulate them into some instantiatable C# wrapper.

You can make your caches members of your one great big root Application object. If you do not have one, come up with one.  This is the only thing which may legitimately be a singleton.  (But even then, it should only be a singleton in the sense that it will be newed once, not in the sense of consisting of static methods.)


答:
The project is the thing. Really. I've run my own small company, and medium and large size teams. The single biggest thing I see is that everyone is motivated when they dig the project. Won't you work cheaper if the project is really cool? Won't you work longer when you're totally into what you're doing and charged to see everyone else feeling the same way?

We do what we value best. So how can you inject value back into your career when you are working for someone who pays your bills? Through innovation. Innovate and share that with others. That's keeps it fresh.

Title: Is 4-5 years the “Midlife Crisis” for a programming career?

Body:
I’ve been programming C# professionally for a bit over 4 years now. For the past 4 years I’ve worked for a few small/medium companies ranging from “web/ads agencies”, small industry specific software shops to a small startup. I've been mainly doing "business apps" that involves using high-level programming languages (garbage collected) and my overall experience was that all of the works I’ve done could have been more professional. A lot of the things were done incorrectly (in a rush) mainly due to cost factor that people always wanted something “now” and with the smallest amount of spendable money. I kept on thinking maybe if I could work for a bigger companies or a company that’s better suited for programmers, or somewhere that's got the money and time to really build something longer term and more maintainable I may have enjoyed more in my career. I’ve never had a “mentor” that guided me through my 4 years career. I am pretty much blog / google / self taught programmer other than my bachelor IT degree.

I’ve also observed another issue that most so called “senior” programmer in “my working environment” are really not that senior skill wise. They are “senior” only because they’ve been a long time programmer, but the code they write or the decisions they make are absolutely rubbish! They don't want to learn, they don't want to be better they just want to get paid and do what they've told to do which make sense and most of us are like that. Maybe that’s why they are where they are now. But I don’t want to become like them I want to be better. I’ve run into a mental state that I no longer intend to be a programmer for my future career. I started to think maybe there are better things out there to work on. The more blogs I read, the more “best practices” I’ve tried the more I feel I am drifting away from “my reality”. But I am not a great programmer otherwise I don't think I am where I am now. I think 4-5 years is a stage that can be a step forward career wise or a step out of where you are.

I just wanted to hear what other have to say about what I’ve mentioned above and whether you’ve experienced similar situation in your past programming career and how you dealt with it. Thanks.

OwnerDisplayName: Spanky


问:
Merits of copy-on-write semantics
I am wondering what possible merits does copy-on-write have? Naturally, I don't expect personal opinions, but real-world practical scenarios where it can be technically and practically beneficial in a tangible way. And by tangible I mean something more than saving you the typing of a & character.

To clarify, this question is in the context of datatypes, where assignment or copy construction creates an implicit shallow copy, but modifications to it creates an implicit deep copy and applies the changes to it instead of the original object.

The reason I am asking is I don't seem to find any merits of having COW as a default implicit behavior. I use Qt, which has COW implemented for a lot of the datatypes, practically all which have some underlying dynamically allocated storage. But how does it really benefit the user?

An example:

```<code>QString s("some text");
QString s1 = s; // now both s and s1 internally use the same resource

qDebug() << s1; // const operation, nothing changes
s1[o] = z; // s1 "detaches" from s, allocates new storage and modifies first character
           // s is still "some text"
</code>```

What do we win by using COW in this example?

If all we intend to do is use const operations, s1 is redundant, might as well use s.

If we intend to change the value, then COW only delays the resource copy until the first non-const operation, at the (albeit minimal) cost of incrementing the ref count for the implicit sharing and detaching from the shared storage. It does look like all the overhead involved in COW is pointless.

It is not much different in the context of parameter passing - if you don't intend to modify the value, pass as const reference, if you do want to modify, you either make an implicit deep copy if you don't want to modify the original object, or pass by reference if you want to modify it. Again COW seems like needless overhead that doesn't achieve anything, and only adds a limitation that you cannot modify the original value even if you want to, as any change will detach from the original object.

So depending on whether you know about COW or are oblivious to it, it may either result in code with obscure intent and needless overhead, or completely confusing behavior which doesn't match the expectations and leaves you scratching your head.

To me it seems that there are more efficient and more readable solutions whether you want to avoid an unnecessary deep copy, or you intend to make one. So where is the practical benefit from COW? I assume there must be some benefit since in it used in such a popular and powerful framework.

Furthermore, from what I've read, COW is now explicitly forbidden in the C++ standard library. Don't know whether the con's I see in it have something to do with it, but either way, there must be a reason for this.

答:
For strings and such it seems like it would pessimize more common use cases than not, as the common case for strings is often small strings, and there the overhead of COW would tend to far outweigh the cost of simply copying the small string. A small buffer optimization makes much more sense to me there to avoid the heap allocation in such cases instead of the string copies.

If you have a heftier object, however, like an android, and you wanted to copy it and just replace its cybernetic arm, COW seems quite reasonable as a way to keep a mutable syntax while avoiding the need to deep copy the entire android just to give the copy a unique arm. Making it just immutable as a persistent data structure at that point might be superior, but a "partial COW" applied on individual android parts seems reasonable for these cases.

In such a case the two copies of the android would share/instance the same torso, legs, feet, head, neck, shoulders, pelvis, etc. The only data which would be different between them and not shared is the arm which was made unique for the second android on overwriting its arm.

Title: Merits of copy-on-write semantics


问:
CQRS and validations
I'm starting to introduce myself in CQRS concepts, but I get stucked with the following situation:
Supouse you have an entity that must have an unique name.  In order to verify that, prior to create the entity you must make a query, thus you are verifing against the query subsystem.
But what happens if the syncronization has not been happened between the command system and the query system yet?  Other client just had sent the same name before you.
What happens in that case?</p>

答:
There are two possible remedies here.

First is that Race Conditions Don't Exist.  If you are operating at business speeds, where you typically have long running processes, you will typically find that either the races don't really happen (so you shouldn't invest too deeply in trying to handle them) OR that the races are allowed, and there are compensating commands that are used to remedy contingencies.

Second approach: if the unique name constraint really is a business invariant that needs to be maintained, then the entity responsible for the creation needs to ensure the uniqueness of the name -- for instance, by maintaining a list of all names in use.  The client does its best to guard against duplication by checking the read side first to detect if a name is already in use; but in the event of a race by two different clients, one of the commands fails, and the client that loses the race is told of the failure and gets to choose another name.

Title: CQRS and validations


问:
How to respond when you are asked for an estimate?
We, as programmers, are constantly being asked 'How long will it take'?

And you know, the situation is almost always like this:

The requirements are unclear. Nobody has done an in depth analysis of all the implications.

The new feature will probably break some assumptions you made in your code and you start thinking immediately of all the things you might have to refactor.

You have other things to do from past assignments and you will have to come up with an estimate that takes that other work into account.

The 'done' definition is probably unclear: When will it be done? 'Done' as in just finished coding it, or 'done' as in "the users are using it"?

No matter how conscious you are of all these things, sometimes your "programmer's pride" makes you give/accept shorter times than you originally suppose it might take. Specially when you feel the pressure of deadlines and management expectations.

Many of these are organizational or cultural issues that are not simple and easy to solve, but in the end the reality is that you are being asked for an estimate and they expect you to give a reasonable answer. It's part of your job. You cannot simply say: I don't know.

As a result, I always end up giving estimates that I later realize I cannot fulfill. It has happened countless of times, and I always promise it won't happen again. But it does.

What is your personal process for deciding and delivering an estimate? What techniques have you found useful?

答:
Some advice from the dark side from one who learned the hard way.

The requirements are unclear. Nobody has done an in depth analysis of
  all the implications.

Don't do an estimate at this point. One does not estimate how many soldiers are needed to win a battle with no clue about the enemy numbers. The estimate is made after scouting. This is unless you already fought this enemy.

The new feature will probably break some assumptions you made in your
  code and you start thinking immediately of all the things you might
  have to refactor.

This is your responsibility to factor in unless you expect others to have the expertise about this area.

You have other things to do from past assignments and you will have to
  come up with an estimate that takes that other work into account.

Same as above, even for unanticipated work that's created by a slob team mate next to you with a near non-existent test procedure which causes your code to glitch out that you can't perfectly predict in advance. It's a weather forecast.

The 'done' definition is probably unclear: When will it be done?
  'Done' as in just finished coding it, or 'done' as in "the users are
  using it"?

Understand the user-end requirement here, think like a user. Don't do what your peers do if they estimate something to be "done" just because some basic functionality with a barebones workflow that no user can possibly tolerate is what they consider to be "done". Think of it from the user standpoint, because that's all the client you're making the estimate for will typically understand. Estimate towards the complete user-end requirements, not towards the barebone technical requirements. And realize that your clients asking for estimates will be totally inaccurate here about how they word things and understand the technical aspects of what you say.

No matter how conscious you are of all these things, sometimes your
  "programmer's pride" makes you give/accept shorter times than you
  originally suppose it might take. Specially when you feel the pressure
  of deadlines and management expectations.

Don't do this! You sound like a self-motivated hard worker and possibly one who gives in easily to coercion.

The problem here is this: let's say you and Joe made time estimates for the same task (but between two separate employees, unaware of both estimates at one time). You estimate valiantly, "one week". It's okay you think, you'll work over 100+ hours a week, unpaid overtime. Now you're three days late.

Meanwhile, Joe estimates 5 months. You think this is ridiculous, you think you can pull this off in one week. How much does Joe work? 10 hours a week? ... except he finishes on time in exactly 5 months.

Guess who gets perceived as the jackass? That's right, you. Joe seems like a great worker, you seem unreliable now. It doesn't matter so much that you might have achieved an even better result in ~7% of the time that Joe took. What matters is that you were 3 days off from a one week estimate.

Never err on the side of the tighter estimate. Err on the side of the looser estimate. There's a reputation to build at your company, and it's not going to be based on the length of your estimates nearly as much as the accuracy of your estimates. It's easy to be accurate with an estimate that's too long, you just get more time to work on the problem and solve it better. An estimate that's too short leaves no breathing room at all, you either meet it desperately or you're screwed.


答:
Make the testing for your client easy, but make it really hard for your client to use any new features in an untested version in production. This can be accomplished as follows:

Whenever you deliver a new feature, you implement this first in a "beta version", clearly marked with a sign "not for production". You make this beta version available to the client for testing. You also provide the latest "production version" he shall use for real production (without the new features, but with the latest bug fixes), and you refuse to transfer the new beta features into the production version until you got a feedback that someone at the clients side has at least tried it out first.

If the client starts to use the beta version on his real production data though it shows always a big message "Not for production use" whenever he starts the program, then you cannot help him, but at least you made clear that whenever he looses production work because he used the beta for wrong purposes that it is clearly his fault. If the client does not learn from that, you may consider to disable your client's ability to use the "beta" in production by deactivating some crucial functions like saving the results to disk in the "beta", if that's necessary.

Providing a separate "beta" will force you to establish proper version control / configuration management, so you can manage a production branch and a beta testing branch side by side without hassle. But since you are working with Github, I guess you already use something like GIT, which makes this kind of management very simple.


问:
Event Sourcing + Updates to multiple aggregates
I'm trying to learn about event sourcing for potential application to a booking system I am building - I think I understand the core concepts, but I'm having trouble understanding how to handle cases where updates to multiple aggregates / streams are required.

In my case I have modeled two aggregates - Events, which track the number of available seats, and Bookings for one or more seats at a single event which record details about the attendees. Everything I have read indicates that a transaction should update only a single aggregate, however when saving a Booking I need to update both the Event to track the remaining seats at the event, and the Booking to record changes to the attendee details. This creates the potential for inconsistency:

If I update the Booking before the event I need to handle the case where the update to the Event fails because the seats are no longer available (this happens even if I add a "Reserve your seats for the next 10 minutes" step, because at some point I need to update the booking details and confirm the seats).

Conversely if I update the Event first I need to handle cases where someone has managed to concurrently modify the Booking and there is a conflict.

In both cases an unexpected error will leave the Booking and Event inconsistent and I'm unsure how I could handle this.

I've tried looking into how similar problems in other domains are handled (e.g. transferring money between accounts), but I'm not 100% clear as to how those strategies ensure "eventual consistency", and so I'm not really sure how to apply this in my case.

How should updates to multiple linked aggregates be handled?

答:
How should updates to multiple linked aggregates be handled?

Updates to multiple aggregates should each be applied in separate transactions.  If this results in an unacceptable situation for the business, then the conflict should be detected and invoke the remediation policy.

It is often the case that over booking is allowed by the business (in cargo shipping examples, you will often see that there is a deliberate policy in place for booking beyond capacity).

In this case, that would probably mean that you change the bookings in an transactionally consistent way.  The process manager, listing to the booking events, would then command the event to update.  The event aggregate would accept the increased number of reserved seats, and fire two events - one announcing its current count of seats, and another announcing that the capacity of the event had been exceeded.  Another process manager listens for the capacity exceeded event, and starts the mitigation process.

On the other hand, if the business invariant really is an absolute - if the business really can't allow more bookings than there is space at the event - if eventual consistency isn't good enough, then you have to accept the fact that you've got a business invariant that requires data from two different entities, and you need to find a model that incorporates those entities into the same aggregate.


问:
Lookup Tables: Are they a leak in the domain model?
You are building a system that keeps track of Companies. Those companies have Contacts. Those contacts are often specialists that only answer certain types of questions, such as Billing/Payment, Sales, Ordering, and Customer Support.

Using Domain Driven Design and an Onion Architecture, I've modeled this with the
following types:

Company

Has Contacts

Contact

Has Contact Types

ContactType (enum)

CompanyRepository (interface)

EFCompanyRepository (defined in an external assembly, uses EntityFramework, implements CompanyRepository)

Our team has a split opinion on how to model the database for this application.

Side A: The Lean DDDers:

It's the job of the Domain to define which ContactTypes are valid for a Contact. Adding a table to the database to validate that unknown ContactTypes are not saved is a sign of a leaky domain. It spreads logic too far out.

Adding a static table to the database and corresponding code is wasteful. In this application the database solves one problem: persist the thing and give it back to me. Writing an extra table and corresponding CRUD code is wasteful.

Changing the strategy for persistence should be as easy as possible. It is more likely to change that business rules. If I decide that SQL Server costs too much I don't want to have to rebuild all the validation I put in my schema.

Side B: The Traditionalists [that's probably not a fair name. The DBCentrists?]:

It's a bad idea to have data in the database that doesn't make sense without reading code. Reports and other consumers have to repeat the list of values themselves.

It's not that much code to load your db type dictionaries on demand. Don't worry about it.

If the source of this is code and not data I will have to deploy bits instead of a simple SQL script when it changes.

Neither side is right or wrong, but one of them is probably more efficient in the long run, counting development time for initial development, bugs, etc. Which side is it - or is there a better compromise? What do other teams writing this style of code do?

答:
Domain objects stop being domain objects when they cross a process boundary.  Even if the database is just a persistence store, at some point in the future the demands of the business are going to cause a change to the domaim model that is inconsistent with the persisted history, and you are going to need an anti corruption layer anyway....

That said, I think your DBCentrists are missing the boat.  The domain modelers are saying that they need a persistence store.  "Reports and other consumers" need something that they can query -- something with decent indexes, as has been noted in comments.

Who introduced the constraint that all of these different concerns needed to be supported by one database?  What happens if you push back on that.

Search keyword: CQRS.

ContentLicense: CC BY-SA 4.0


答:
Don't let the "serious hate" for singletons trouble you. Anyone who says "always" or "never" is ignorant. Or deranged. Or secretly crying for help.

Conceptually, a cache is a singleton. There's no getting around it. It's sitting in memory somewhere, waiting. Many readers and writers are accessing that one chunk of memory (barring a disk-backed cache). I imagine the dependency injection solutions are talking about injecting an abstraction over the cache. There may be many of them, but if you dig deep enough (not even that deep, really), there should only ever be one cache.

My team's rule of thumb is that singletons may be okay for a single source of truth. That sounds like what you're dealing with.

One observation about your current solution: In my ideal world, as a casual consumer I never want to see the word "Cache" in the code I'm using. If I want a collection of Users, I'd rather say

```<code>var store = new UserStore();
return store.GetUsers()
</code>```

than

```<code>return SalesForceCache.Users.Data;
</code>```

The word "Cache" is mental overhead. When I use it, I'm suddenly thinking about the "how" the data is stored versus "what" I want. Sure, there may be a cache under the hood of my UserStore, but it's hidden from me. And that's a good thing. Some other plumbing should decide if something is cached and for how long.

Also, there are a few possible future frustrations:

The storage mechanism is rigid. You can only ever store a collection. That may not be what I want. For instance, maybe I want to store active Users individually, with a sliding expiration, by email address. (Super useful when you have many users but only a handful of them are online at one time.)

Expirations are absolute. It can be useful to define a sliding expiration. (especially under memory constraint when you only want the most active data in memory)

There are no cache dependencies. Cache dependencies allow you to automatically expire cached data when specific conditions are met.

Take a look at System.Runtime.Caching.MemoryCache for an easy-to-use local memory cache. It's feature rich and uses the idioms common in key/value caches. I absolutely don't want to discourage you from continuing with your approach! Keep at it! The MemoryCache might serve as an interesting reference.

Title: Alternatives to Singletons for caching lists of data?

Body:
In my project, I have an abstract Cache class that allows me to populate a series of lists that globally persist throughout my application. These cache objects are thread-safe and can be manipulated as necessary, and allow for me to cut-down on the massive overhead of querying external third-party APIs directly. I've seen some serious hate for singletons, so I'm a bit curious what other options I have when this is my current use case.

I've seen dependency injection mentioned quite a bit, but I don't know if it's quite adequate or useful in this scenario.

Here is an example of my Cache abstract class:

```<code>public abstract class Cache<TU, T>
    where TU : Cache<TU, T>, new()
    where T : class
{
    private static readonly TU Instance = new TU();
    private static volatile State _currentState = State.Empty;
    private static volatile object _stateLock = new object();
    private static volatile object _dataLock = new object();
    private static DateTime _refreshedOn = DateTime.MinValue;
    private static T InMemoryData { get; set; }

    public static T Data
    {
        get
        {
            switch (_currentState)
            {
                case State.OnLine:
                    var timeSpentInCache = (DateTime.UtcNow - _refreshedOn);
                    if (timeSpentInCache > Instance.GetLifetime())
                    {
                        lock (_stateLock)
                        {
                            if (_currentState == State.OnLine) _currentState = State.Expired;
                        }
                    }
                    break;

                case State.Empty:
                    lock (_dataLock)
                    {
                        lock (_stateLock)
                        {
                            if (_currentState == State.Empty)
                            {
                                InMemoryData = Instance.GetData();
                                _refreshedOn = DateTime.UtcNow;
                                _currentState = State.OnLine;
                            }
                        }
                    }
                    break;

                case State.Expired:
                    lock (_stateLock)
                    {
                        if (_currentState == State.Expired)
                        {
                            _currentState = State.Refreshing;
                            Task.Factory.StartNew(Refresh);
                        }
                    }
                    break;
            }

            lock (_dataLock)
            {
                if (InMemoryData != null) return InMemoryData;
            }

            return Data;
        }
    }

    public static T PopulateData()
    {
        return Data;
    }

    protected abstract T GetData();

    protected virtual TimeSpan GetLifetime()
    {
        return TimeSpan.FromMinutes(10);
    }

    private static void Refresh()
    {
        if (_currentState != State.Refreshing) return;
        var dt = Instance.GetData();
        lock (_stateLock)
        {
            lock (_dataLock)
            {
                _refreshedOn = DateTime.UtcNow;
                _currentState = State.OnLine;
                InMemoryData = dt;
            }
        }
    }

    public static void Invalidate()
    {
        lock (_stateLock)
        {
            _refreshedOn = DateTime.MinValue;
            _currentState = State.Expired;
        }
    }

    private enum State
    {
        Empty,
        OnLine,
        Expired,
        Refreshing
    }
}
</code>```

And an example of its implementation.

```<code>public class SalesForceCache
{
    public class Users : Cache<Users, List<Contact>>
    {
        protected override List<Contact> GetData()
        {
            var sf = new SalesForce();
            var users = sf.GetAllUsers();

            sf.Dispose();

            return users;
        }

        protected override TimeSpan GetLifetime()
        {
            try
            {
                return TimeSpan.FromDays(1);
            }
            catch (StackOverflowException)
            {
                return TimeSpan.Zero;
            }
        }
    }

    public class Accounts : Cache<Accounts, List<Account>>
    {
        protected override List<Account> GetData()
        {
            var sf = new SalesForce();
            var accounts = sf.GetAllAccounts();

            sf.Dispose();

            return accounts;
        }

        protected override TimeSpan GetLifetime()
        {
            try
            {
                return TimeSpan.FromDays(1);
            }
            catch (StackOverflowException)
            {
                return TimeSpan.Zero;
            }
        }
    }
}
</code>```

Body:
Don't let the "serious hate" for singletons trouble you. Anyone who says "always" or "never" is ignorant. Or deranged. Or secretly crying for help.

Conceptually, a cache is a singleton. There's no getting around it. It's sitting in memory somewhere, waiting. Many readers and writers are accessing that one chunk of memory (barring a disk-backed cache). I imagine the dependency injection solutions are talking about injecting an abstraction over the cache. There may be many of them, but if you dig deep enough (not even that deep, really), there should only ever be one cache.

My team's rule of thumb is that singletons may be okay for a single source of truth. That sounds like what you're dealing with.

One observation about your current solution: In my ideal world, as a casual consumer I never want to see the word "Cache" in the code I'm using. If I want a collection of Users, I'd rather say

var store = new UserStore();
return store.GetUsers()

than

return SalesForceCache.Users.Data;

The word "Cache" is mental overhead. When I use it, I'm suddenly thinking about the "how" the data is stored versus "what" I want. Sure, there may be a cache under the hood of my UserStore, but it's hidden from me. And that's a good thing. Some other plumbing should decide if something is cached and for how long.

Also, there are a few possible future frustrations:

The storage mechanism is rigid. You can only ever store a collection. That may not be what I want. For instance, maybe I want to store active Users individually, with a sliding expiration, by email address. (Super useful when you have many users but only a handful of them are online at one time.)

Expirations are absolute. It can be useful to define a sliding expiration. (especially under memory constraint when you only want the most active data in memory)

There are no cache dependencies. Cache dependencies allow you to automatically expire cached data when specific conditions are met.

Take a look at System.Runtime.Caching.MemoryCache for an easy-to-use local memory cache. It's feature rich and uses the idioms common in key/value caches. I absolutely don't want to discourage you from continuing with your approach! Keep at it! The MemoryCache might serve as an interesting reference.


答:
Something I've found many programmers don't understand is that not all decisions are technical.  Sad as it is, doing something "right" is not always an option.  This leads many developers to think their bosses are stupid, or make poor decisions... and yes, often that is indeed the case, but equally as often the fact of the matter is that the company might be out of business, or lose a job entirely if they allowed the programmers to set the schedule and make all the technical decisions.

Sadly, sometimes it's our job to work within the political or financial constraints of the job and do the best we can.

One thing you learn from experience is to be conservative.  The latest techniques may not be proven and you may not have a strong grasp on them even if they are.  Managers don't like spending time on letting you get up to speed on a new technology just because you want to learn something new.

Programmers forget that many companies are not software companies.  They're <insert business industry here> companies that also do software.  Your job as a programmer is to facilitate the mission critifcal processes, not write perfect software.  Sometimes it works out that those are the same thing, but it's actually quite rare.

OwnerDisplayName: Mystere Man


答:
... without it having to be passed either as: a) a parameter or b) globally static.

Pick one. There is no third option.

You either pass the "data querying" abstraction as parameter, with cache serving as a decorator, or you access the cache through globally static property. I would recommend the first, because then it makes the dependency explicit and allows you to transparently separate the caching and data acquisition.

My take why Singletons are bad, is that they break SRP. They have two responsibilities : whatever the singleton is supposed to do and handing it's lifetime. Those two are exclusive and should be separate. Reason why people recommend IoC is to move the lifetime handling outside the singleton and into to IoC container.


问:
Class design dilemma: Encapsulation vs Single Responsibility/Separation of Concerns
I'm working on a class that represents an object with multiple representations - one is an XML type representation used by an automatic ordering system, the other is a POJO-based representation used by a monitoring tool.

The problem I'm running into is that I seem to have to make trade-off between encapsulating the object's internal data and designing my application according to the principle of "separation of concerns" or "single responsibily per class".

Let's look at the class in more detail:

```<code>public class MyObject {
    private Object field1;
    private Object field2;
    private Object field3;
    ...
    private Object field100;
}
</code>```

(Yes it's quite a big ugly monster, something I have no control over).

If I follow the principle of separation of concerns (the way I understand it anyway), I will have to add getters for every field in this class and have a separate XMLBuilder class for the XML representation, and a PojoBuilder for the Monitoring tool representation:

```<code>public class XMLBuilder {

    public XML asXml(MyObject obj) {
        return "<tag1>" + object.getField1() + "</tag1>"
               "<tag2>" + object.getField2() + "</tag2>"
               ...
               ;
        }
}
</code>```

This seems to me to break the principle of encapsulation - I have to expose a lot of the internal data on my class just to provide a representation for it. If I pass my object to other systems, I have no control whether these sub-systems may become dependent on arbitrary fields (i.e. field45), which means that future changes to the structure of this object may become difficult as there are now other possible dependencies on it.

An alternative approach, advocated by Allen Holub (http://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html) for example, is to do the representation inside the class:

```<code>public class MyObject {

    ...

    public XML asXml() {
        return "<tag1>" + field1 + "</tag1>"
               "<tag2>" + field2 + "</tag2>"
               ...
               ;
    }

    public Object asMonitor() {
        ...
    }

 }
</code>```

To me, this solution seems great, as the class never exposes any private fields. The representation generators have access to all the information it needs, and the object itself can be safely passed to other sub-systems without the worry that another module would depend on internals.

Now, when I implement this, my colleagues all raise the issue of "Separation of concerns". The problem, they say, is that the MyObject class now have knowledge of things like XML representations and POJO represantions, which means that if the XML representation changes, you now have to make modifications inside the actual class itself, instead of just updating an "XML ruleset" or some other external configuration.

Holub's solution is to use a Builder pattern:

```<code>public class MyObject {

...

    public void buildContent(MyObjectBuilder builder) {
        builder.setField1(field1);
        builder.setField2(field2);
    }
 }

 public class XMLBuilder implements MyObjectBuilder {

     ...

     public void setField1(Object field1) {
         content += "<tag1>" + field1 + "</tag1>";
     }

     public XML asXML() {
         return content;
     }

     ...
 }
</code>```

but this seems hardly better than the first approach - instead of exposing data as getters, it is now implicitly exposed via a builder. OK, I understand that with the builder I may have additional control over how my object represents itself, but is that iota of control worth the increased complexity in the code base? Changes to the structure of MyObject will still likely result in downstream dependencies requiring updates, so I'm not entirely sure if much have been gained here (except that there are technically no getters).

Is this a case where you simply have to choose your poison? Or is there a magical middle ground that reduces all these issues? What are the common strategies for dealing with this?

答:
Some serialization frameworks implement following approach:

Each model object is required to implement a certain interface

Interface accepts an abstract visitor-like container object

Model object is responsible to populate container object

Container provides trivial operations like storing key-value pairs, sequences, nested objects, may support storage of all primitive types

There are multiple implementations of containers, one for XML, one for POJO, one for JSON etc

This approach reveals structure of model object, but makes it inconvenient to abuse.

See boost::serialization library for reference.

Here is my simplified draft for Java:

public interface Container implements Closable {
  // Repeat for all primitives
  void put(String key, String value);
  Container getChild(String key);
  //TODO: add sequences support
}

public class ConcreteModelObject {
  private final String datum;
  private final String id;
  private final Child child;
  private class Child {
    private final String childId;
    void store(Container container) {
      container.put("id", childId);
    }
  }
  // The only structure exposure point
  public void store(Container container) throws IOException {
    container.put("id", id);
    container.put("datum", datum);
    // Child container should be closed after use, to allow closing of XML tags, for example
    try (Container childContainer: container.getChild("child")) {
      child.store(childContainer);
    }
  }
}
```

This approach lowers coupling between serialization and model object, but does not eliminate it. Similar results can be achieved by choosing a most potent serialization method, implementing that in model, then convert resulting format to others (for example, make model be serializable to XML, provide a way to convert XML to JSON).

Deserialization is more or less symmetric.
Also note, that this approach can be memory consuming if implemented wrong. See boost::serialization for optimized solutions.

Body:
Some serialization frameworks implement following approach:

Each model object is required to implement a certain interface

Interface accepts an abstract visitor-like container object

Model object is responsible to populate container object

Container provides trivial operations like storing key-value pairs, sequences, nested objects, may support storage of all primitive types

There are multiple implementations of containers, one for XML, one for POJO, one for JSON etc

This approach reveals structure of model object, but makes it inconvenient to abuse.

See boost::serialization library for reference.

Here is my simplified draft for Java:

public interface Container implements Closable {
  // Repeat for all primitives
  void put(String key, String value);
  Container getChild(String key);
  //TODO: add sequences support
}

public class ConcreteModelObject {
  private final String datum;
  private final String id;
  private final Child child;
  private class Child {
    private final String childId;
    void store(Container container) {
      container.put("id", childId);
    }
  }
  // The only structure exposure point
  public void store(Container container) throws IOException {
    container.put("id", id);
    container.put("datum", datum);
    // Child container should be closed after use, to allow closing of XML tags, for example
    try (Container childContainer: container.getChild("child")) {
      child.store(childContainer);
    }
  }
}

This approach lowers coupling between serialization and model object, but does not eliminate it. Similar results can be achieved by choosing a most potent serialization method, implementing that in model, then convert resulting format to others (for example, make model be serializable to XML, provide a way to convert XML to JSON).

Deserialization is more or less symmetric.
Also note, that this approach can be memory consuming if implemented wrong. See boost::serialization for optimized solutions.


问:
Should objects with different properties (not behaviour) have different types?
I see a lot of classes that look like:

```<code>class Student extends Model {
    public string major;
    public string minor;
}

class Employee extends Model {
    public string department;
    public string building;
}
</code>```

These kind of classes are mostly used to hold data. My question is, should these aliases for Model class exist just because they have different properties? At most, the differences between them are accessors. Are these kinds of classes good or bad? Why don't I see more of:

```<code>student = Model::fromArray(['major' => 'a', 'minor' => 'i']);
employee = Model::fromArray(['department' => 'd', 'building' => 'b']);
</code>```

This is more about style rather than specific application. I see that when it comes to presentation/view, people don't care much about types, a lot of time data is passed as arrays to template subsystem and don't create Presentation Models.

Data Transfer Objects also don't have behaviours and I get some answer from this article LocalDTO about why DTO shouldn't be used locally (only for type checking?). I'm looking for more general case on when to use (or not) these behaviour less classes.

答:
Yes, they should exist, and they are a good thing.

The value of types is providing information on what values of that type contain and how they can be accessed. If you didn't define classes for Employee and Student, you would not have this information present in the type, and therefore would rely on the programmer to not only keep track of when they are working on an Employee or a Student, but also to keep track of which properties exist and what their types is. The burden of validating correct usage is placed then on the programmer, not on the language and its compiler.

You don't necessarily need this information. After all, the programmer can just try to keep it in their head or look it up somewhere else in the code. Having it just makes it much easier to maintain a codebase, because the additional type information provided to code that works with values of that type assists the programmer to ensure correctness by letting the compiler, interpreter or linter do some of the work.


答:
Let me give a manager's point of view.  The world supply of coding opportunities greatly exceeds the available talent-hours available to address them.  Managers run businesses to make a profit, for which reason they try to apply the available talent-hours to as many coding opportunities as possible, so it is only right and proper that things get done in a rush, and on the cheap, provided the consequences don't affect the bottom line.

In my experience the best work gets done when management isn't looking, either as a skunkworks project at a larger company, or increasingly by voluntary contributors working on open source projects.

My advice is embrace the discipline of cost control, look for skunkworks opportunities, find an open source project to engage your spare time, and get into management, because if you don't someone with less technical competence will get to make decisions instead.

PS. I was a C/C++ developer for 12 years and still code Java as a director.

OwnerDisplayName: Piers C


问:
Has any language ever supported a conditional assignment target?
I've never seen a programming language with conditional assignment targets, eg.:

```<code>// If (x == y), then var1 will be set to 1, else var2 will be set to 1
((x == y) ? var1 : var2) = 1
</code>```

The target of the assignment is determined conditionally at run-time, in this case based on whether x == y.

It seems like it could be a handy syntax.

Anyone know of any programming language which supports this?

Or is there a theoretical reason it can't be done effectively?

答:
This isn't really a theory question, but a practical one.

C++ supports what you're asking about:

[C++14: 5.16/4]: If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category [..]

For example:

#include <iostream>

int x = 3, y = 4;

void foo(const bool b)
{
    (b ? x : y) = 6;
}

int main()
{
    std::cout << x << ' ' << y << '\n';   // 3 4
    foo(true);
    std::cout << x << ' ' << y << '\n';   // 6 4
    foo(false);
    std::cout << x << ' ' << y << '\n';   // 6 6
}
```

<p>(live demo)</p>

<p>(This is basically the same as <code>*ptr = val</code>, since dereferencing produces an lvalue.)</p>

<p>It's worth noting that C <em>doesn't</em> support it:</p>

<pre class="lang-c prettyprint-override"><code>#include <stdio.h>
#include <stdbool.h>

int x = 3, y = 4;

void foo(const bool b)
{
    (b ? x : y) = 6;
}

int main()
{
    printf("%d %d\n", x, y);   // 3 4
    foo(true);
    printf("%d %d\n", x, y);   // 6 4
    foo(false);
    printf("%d %d\n", x, y);   // 6 6
}

// main.c: In function 'foo':
// main.c:8:17: error: lvalue required as left operand of assignment
//      (b ? x : y) = 6;
             ^
</code>```

(live demo)

… though it will allow you to simulate this technique, by applying my early observation regarding pointer dereferences:

```<code>*(b ? &x : &y) = 6;
</code>```

Body:
This isn't really a theory question, but a practical one.

C++ supports what you're asking about:

[C++14: 5.16/4]: If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category [..]

For example:

#include <iostream>

int x = 3, y = 4;

void foo(const bool b)
{
    (b ? x : y) = 6;
}

int main()
{
    std::cout << x << ' ' << y << '\n';   // 3 4
    foo(true);
    std::cout << x << ' ' << y << '\n';   // 6 4
    foo(false);
    std::cout << x << ' ' << y << '\n';   // 6 6
}

(live demo)

(This is basically the same as *ptr = val, since dereferencing produces an lvalue.)

It's worth noting that C doesn't support it:

#include <stdio.h>
#include <stdbool.h>

int x = 3, y = 4;

void foo(const bool b)
{
    (b ? x : y) = 6;
}

int main()
{
    printf("%d %d\n", x, y);   // 3 4
    foo(true);
    printf("%d %d\n", x, y);   // 6 4
    foo(false);
    printf("%d %d\n", x, y);   // 6 6
}

// main.c: In function 'foo':
// main.c:8:17: error: lvalue required as left operand of assignment
//      (b ? x : y) = 6;
             ^

(live demo)

… though it will allow you to simulate this technique, by applying my early observation regarding pointer dereferences:

*(b ? &x : &y) = 6;


答:
You can do this in Perl.  It is the same as in C++.

```<code>my $x = 0;
my $y = 0;

1==1 ? $x: $y = 1;

print "x: $x y: $y\n";

$x = 0;
$y = 0;

1==0 ? $x: $y = 1;

print "x: $x y: $y\n";
</code>```

Note: this construct can often lead to confusion.  For example, consider the following code:

```<code>$condition ? $y = 0 : $x = 1;
</code>```

The person writing this line of code likely thought that $y would get set to 0 if $condition is true, but actually this evaluates to $y = 0 = 1, which gives $y a value of 1.

Title: Has any language ever supported a conditional assignment target?

Body:
I've never seen a programming language with conditional assignment targets, eg.:

```<code>// If (x == y), then var1 will be set to 1, else var2 will be set to 1
((x == y) ? var1 : var2) = 1
</code>```

The target of the assignment is determined conditionally at run-time, in this case based on whether x == y.

It seems like it could be a handy syntax.

Anyone know of any programming language which supports this?

Or is there a theoretical reason it can't be done effectively?

Body:
You can do this in Perl.  It is the same as in C++.

my $x = 0;
my $y = 0;

1==1 ? $x: $y = 1;

print "x: $x y: $y\n";

$x = 0;
$y = 0;

1==0 ? $x: $y = 1;

print "x: $x y: $y\n";

Note: this construct can often lead to confusion.  For example, consider the following code:

$condition ? $y = 0 : $x = 1;

The person writing this line of code likely thought that $y would get set to 0 if $condition is true, but actually this evaluates to $y = 0 = 1, which gives $y a value of 1.


问:
What is meant by reuse of inheritance?

A 2013 study of 93 open source Java programs (of varying size) found
  that

While there is [no] huge opportunity to replace inheritance with composition (...), the opportunity is significant (median of 2% of
  uses [of inheritance] are only internal reuse, and a further 22% are
  only external or internal reuse). Our results suggest there is no need
  for concern regarding abuse of inheritance (at least in open-source
  Java software), but they do highlight the question regarding use of
  composition versus inheritance. If there are significant costs
  associated with using inheritance when composition could be used, then
  our results suggest there is some cause for concern.
      — Tempero et al., "What programmers do with inheritance in Java"[4]

From : https://en.wikipedia.org/wiki/Composition_over_inheritance#Empirical_studies_of_composition_and_inheritance

What is the meaning of reuse of inheritance?

答: My guess is that by "reuse of inheritance" they mean code reuse by means of inheritance, as opposed to code reuse by means of composition. The are reusing code, not reusing inheritance. By internal reuse my guess is that they are talking about extending classes in the same package, whereas external is about extending classes from different packages.

Title: What is meant by reuse of inheritance?


答: There are a lot of programmers, but only a small fraction of them are software engineers of quality. I suppose that's true in any profession.</p>

OwnerDisplayName: Loadmaster


答:
The way to encourage communication of bugs is to encourage frequent, granular communication of features.  If you train a company that they can ask for anything with zero ceremony, they'll use that feature for minor bugs, too.  Give up on changing to your client's workflow unless these changes make their life easier.

Getting your client to do in-house testing is tough, but getting them to actually report bugs is not as difficult as it sounds.  The way to get more feedback is to reduce user friction...even if that means transferring some of that friction to yourself.

Use simpler tools, even if those tools are inadequate and inappropriate.  E.g., BaseCamp is a pretty awful bug tracker (because it's intended for project management), but people are actually willing to use it.

Since the bug trackers we were using did not support image copy-paste, I actually wrote a trivial program which copies the current clipboard image to disk (as a Guid), then copies the Guid to the clipboard.  After minimal training, a user could attach clipboard images to issues by just hitting print screen, clicking a button, and then pasting  into the file chooser dialog of the bug submission tool.

A screenshot (possibly edited in MS Paint with annotations) and 1-2 sentences is enough to pinpoint most features/bugs.

Both of these suggestions are targeting friction points which I experienced, and both of these suggestions increased reporting by a factor of more than 10.  However, you will need to target your own friction points.


答:
As long as you are using a relational database you should keep tables normalized to a reasonable extent. Normalization helps prevent insert and update anomalies.

The one-app<->one-database relationship is no longer common, multiple apps can use multiple databases and a single database can be used by multiple apps, so having the database enforce referential integrity as much as possible is good.

The RDBMS is your friend.

You can go with a key-value storage instead and do everything in code.

Title: Lookup Tables: Are they a leak in the domain model?

Body:
You are building a system that keeps track of Companies. Those companies have Contacts. Those contacts are often specialists that only answer certain types of questions, such as Billing/Payment, Sales, Ordering, and Customer Support.

Using Domain Driven Design and an Onion Architecture, I've modeled this with the
following types:

Company

Has Contacts

Contact

Has Contact Types

ContactType (enum)

CompanyRepository (interface)

EFCompanyRepository (defined in an external assembly, uses EntityFramework, implements CompanyRepository)

Our team has a split opinion on how to model the database for this application.

Side A: The Lean DDDers:

It's the job of the Domain to define which ContactTypes are valid for a Contact. Adding a table to the database to validate that unknown ContactTypes are not saved is a sign of a leaky domain. It spreads logic too far out.

Adding a static table to the database and corresponding code is wasteful. In this application the database solves one problem: persist the thing and give it back to me. Writing an extra table and corresponding CRUD code is wasteful.

Changing the strategy for persistence should be as easy as possible. It is more likely to change that business rules. If I decide that SQL Server costs too much I don't want to have to rebuild all the validation I put in my schema.

Side B: The Traditionalists [that's probably not a fair name. The DBCentrists?]:

It's a bad idea to have data in the database that doesn't make sense without reading code. Reports and other consumers have to repeat the list of values themselves.

It's not that much code to load your db type dictionaries on demand. Don't worry about it.

If the source of this is code and not data I will have to deploy bits instead of a simple SQL script when it changes.

Neither side is right or wrong, but one of them is probably more efficient in the long run, counting development time for initial development, bugs, etc. Which side is it - or is there a better compromise? What do other teams writing this style of code do?


问:
Is there a difference between property and attribute?
These two words are completely synonymous for me, but I wonder if there's actually a useful semantic difference that I can incorporate into coding/naming conventions/process.</p>

答:
Attributes represents the state of the object.

Properties are used synonymously as attributes but its depends on language.
Properties are getters and/or setters which are invoked as we read it or assign it.

With properties , we can add error handling code to prevent the object to be in unsafe state.But we cant do the same with attributes as they are just meant to store some value.

ex:

```<code>her.age = -10;
</code>```

// shes is in unsafe state as age cannot be negative

but if her.age is a property , it may check before assign new age to the attribute i.e. private one.

```<code>if(newAge >= 18)

{ *// then do someThing..* }

else

{
  *// throw some exception*
}
</code>```

// here newAge is arg to property age

Properties just execute some error handling code.

You can add custom code to it too.

Body:
Attributes represents the state of the object.

Properties are used synonymously as attributes but its depends on language.
Properties are getters and/or setters which are invoked as we read it or assign it.

With properties , we can add error handling code to prevent the object to be in unsafe state.But we cant do the same with attributes as they are just meant to store some value.

ex:

her.age = -10;

// shes is in unsafe state as age cannot be negative

but if her.age is a property , it may check before assign new age to the attribute i.e. private one.

if(newAge >= 18)

{ *// then do someThing..* }

else

{
  *// throw some exception*
}

// here newAge is arg to property age

Properties just execute some error handling code.

You can add custom code to it too.


答:
It is a bit unclear, but my educated guess (because no other hypothesis seems to make sense) is that:

By "inheritance for external [code] reuse" they mean cases where a subsystem exposes (makes publicly available) an abstract base class, which is to be extended by other classes either of this subsystem or of other subsystems. So, in essence, code that uses the base class has knowledge of the fact that inheritance is utilized.

Example:

```<code>public abstract class A {};
/* package-private or public */ class B extends A {};
/* package-private or public */ class C extends A {};
</code>```

By "inheritance for internal [code] reuse" they mean cases where a subsystem exposes (makes publicly available) an interface, which is internally implemented by a number of classes that are not publicly exposed, and in order to achieve code reuse the subsystem makes use of an also package-private common base class for all the implementing classes.  But none of these classes are publicly exposed, so code outside of the package has no knowledge of the fact that the implementations of the interface are extending some common base class.

Example:

```<code>public interface I {};
/* package-private */ abstract class A implements I {};
/* package-private */ class B extends A {};
/* package-private */ class C extends A {};
</code>```

Of course, internal reuse is best, because it allows for maximum flexibility: the subsystem is hiding from the outside world the fact that it is internally using inheritance, so the subsystem can later be refactored to use composition instead of inheritance, and the outside world will not take notice.  (Outside code will not even have to be recompiled.)  In essence, when inheritance is employed for internal code reuse, the common base class is nothing but a helper.

Title: What is meant by reuse of inheritance?

Body:
A 2013 study of 93 open source Java programs (of varying size) found
  that

While there is [no] huge opportunity to replace inheritance with composition (...), the opportunity is significant (median of 2% of
  uses [of inheritance] are only internal reuse, and a further 22% are
  only external or internal reuse). Our results suggest there is no need
  for concern regarding abuse of inheritance (at least in open-source
  Java software), but they do highlight the question regarding use of
  composition versus inheritance. If there are significant costs
  associated with using inheritance when composition could be used, then
  our results suggest there is some cause for concern.
      — Tempero et al., "What programmers do with inheritance in Java"[4]

From : https://en.wikipedia.org/wiki/Composition_over_inheritance#Empirical_studies_of_composition_and_inheritance

What is the meaning of reuse of inheritance?

Body:
It is a bit unclear, but my educated guess (because no other hypothesis seems to make sense) is that:

By "inheritance for external [code] reuse" they mean cases where a subsystem exposes (makes publicly available) an abstract base class, which is to be extended by other classes either of this subsystem or of other subsystems. So, in essence, code that uses the base class has knowledge of the fact that inheritance is utilized.

Example:

public abstract class A {};
/* package-private or public */ class B extends A {};
/* package-private or public */ class C extends A {};

By "inheritance for internal [code] reuse" they mean cases where a subsystem exposes (makes publicly available) an interface, which is internally implemented by a number of classes that are not publicly exposed, and in order to achieve code reuse the subsystem makes use of an also package-private common base class for all the implementing classes.  But none of these classes are publicly exposed, so code outside of the package has no knowledge of the fact that the implementations of the interface are extending some common base class.

Example:

public interface I {};
/* package-private */ abstract class A implements I {};
/* package-private */ class B extends A {};
/* package-private */ class C extends A {};

Of course, internal reuse is best, because it allows for maximum flexibility: the subsystem is hiding from the outside world the fact that it is internally using inheritance, so the subsystem can later be refactored to use composition instead of inheritance, and the outside world will not take notice.  (Outside code will not even have to be recompiled.)  In essence, when inheritance is employed for internal code reuse, the common base class is nothing but a helper.


答:
Think of this as a chance to chanllege you beyond yourself.I would suggest you to take initiative to improve your atmosphere. You will learn lot along the way ,no matter you would fail or succee.

It's much easier to complain (I know people don't like this words, me too) than to make positive change.To change you should be able to influence others; you should be able to communicate;you should be able frame common ground; you should be persistent and patient; you should be able to listen and motivate others with you vision. These are the never-out-of-data skill that will benifit your whole life.

OwnerDisplayName: pierr


问:
PHI, NoSQL, and searching
I am working with a system that is using NoSQL (Azure Table Storage) primarily to house its data. Unfortunately, the work also involves billing and medical records - meaning the data itself will need to be protected. That's fine, we can provide user access to the system, and encrypt that data over the wire and at rest in the NoSQL.

The problem comes because we want that data to also be searchable. Unecrypted, that's not a problem so much - we make the searchable fields row keys and can do range queries. Encrypted, that won't work. Worse it seems as though any sort of trie or similar structure would need to be stored unencrypted, defeating the purpose. Storing partial strings encrypted would make it easy to break the encryption since we would be leaking information about the cleartext.

So far, the only semi-viable solutions I've run across are 1) stop using NoSQL or 2) read the entire set into memory and do the search there.

Neither are particularly thrilling. Is there any other good approach for this confluence of requirements?

答:
You could maintain a separate (or as a part of the NoSQL record) store of hashes of the searchable data. The nature of a hash being non-reversible makes it leak far less information than encrypted strings when you have various amounts of the strings available. Then as queries come in, you just hash the query request information and match on hashes. This makes the data less compromisable than the encryption itself, while maintaining the performance of not having to unencrypt all the data.

For further security, if there's any discriminator (like owning organization) you can use for the people executing the query that scopes to the records they're querying on - you could use that as a salt. This would only work if there's a complete match on scoping though: A set of records is only viewable by group A, and group A can only view that set of records; then you can salt the hashes for that group separate from the salt used for group B etc.

Also, if you have a discriminator as above, you can decrypt into memory or do other things that may be costly - on only that particular groups data. Reducing the data scope on each operation like that can allow you to do far more costly things to get your query matches.

Title: PHI, NoSQL, and searching


答:
By adopting DDD and onion architecture, you have decided that database is second to your domain model. That means, there won't be anyone else doing operations on the database other than the model. If traditionalists don't like that, they should have objected to use of DDD in the first place.

First thing is clear : you need the "lookup table" in the model. Your model needs to differentiate between different types of contacts. That means, it keeps strongly-typed list of all types. There also needs to be mapping from those strong types to values that are serialized to database. This mapping can be inside the database module. But the list of all possible types will still be in the model. And if the model is to be single source of truth, then it cannot be inside the database. Or at least, when the list changes in the model, it needs to change in the database. And no buts!


问:
How to scramble a word, keeping first and last characters the same?
I have a task, which is to scramble a single word, whose size is greater than 3 letters.

The scrambled word must not be equal to the original, and the first and last letters of the word must remain the same.

For example, the word stack, could give the one of the following results:

satck

scatk

stcak

sactk

etc

While words like is or hey for example, would remain unchanged for being too small.

My attempt to do this can be seen below. I have a JavaScript function that received a word to scramble, and then I choose random indexes within a certain limit to create a new scrambled word and return it. If the index I have chosen was already picked, then I try again hoping for a new result.

```<code>/**
 * Returns a scrambled word with the first and last letters unchanged
 * that is NOT EQUAL to the given parameter 'word', provided it has
 * more than three characters.
 */
function scrambleWord(word){

  if(word.length <= 3)
    return word;

  var selectedIndexes, randomCharIndex, scrambledWord = word;

  while(word === scrambledWord){
    selectedIndexes = [], randomCharIndex, scrambledWord = '';
    scrambledWord += word[0];
    for(var j = 0; j < word.length-2; j++){

      //select random char index making sure it is not repeated
      randomCharIndex = getRandomInt(1, word.length-2);
      while(selectedIndexes.indexOf(randomCharIndex) > -1 && selectedIndexes.length != word.length-2){
        randomCharIndex = getRandomInt(1, word.length-2);
      }

      scrambledWord += word[randomCharIndex];
      selectedIndexes.push(randomCharIndex);
    }
    scrambledWord += word[word.length-1];
  }
  return scrambledWord;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive)
 * Using Math.round() will give you a non-uniform distribution!
 * See: http://stackoverflow.com/a/1527820/1337392
 */
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
</code>```

The problem with this approach, is that it is too slow. I fail the tests because I exceed the time limit of 6 seconds, so I definitely need to improve this solution, but I can't see where I can do it.

From an algorithm perspective, what is the most efficient way that uses the least amount of worst case operations that I can approach this problem?

答:
Something along the following lines; treating the string as a character array:

Handle strings that are 3 or fewer characters, or all the middle characters are the same

Create a sublist of the letters excluding the first and last

Fisher-Yates shuffle the middle letters until they don't match the original (this can be done in O(n) time)

Reattach the first and last letter

A faster shuffle can be used, if it is allowed to be less random (e.g. ln(n) random swaps).  In the extreme case this can be reduced to Mike Nakis' answer


答:
Let n be word.length - 3. (Yes, '3'.)

Issue a random index i in the range 0...n.

Swap the letters at word[1 + n] and word[1 + n + 1].

you are done.

If there is a possibility that the word may contain two identical letters, then whoever gave you this assignment must first answer what happens with words like "moot".  Assuming that they will say "moot" stays same, but "schmoot" must become something other than "schmoot", then:

1.b Check if all letters except first and last are same.  If they are, you are done.

2.b Keep repeating step 2 until the letters at word[1 + n] and word[1 + n + 1] are different.

Title: How to scramble a word, keeping first and last characters the same?

Body:
I have a task, which is to scramble a single word, whose size is greater than 3 letters.

The scrambled word must not be equal to the original, and the first and last letters of the word must remain the same.

For example, the word stack, could give the one of the following results:

satck

scatk

stcak

sactk

etc

While words like is or hey for example, would remain unchanged for being too small.

My attempt to do this can be seen below. I have a JavaScript function that received a word to scramble, and then I choose random indexes within a certain limit to create a new scrambled word and return it. If the index I have chosen was already picked, then I try again hoping for a new result.

```<code>/**
 * Returns a scrambled word with the first and last letters unchanged
 * that is NOT EQUAL to the given parameter 'word', provided it has
 * more than three characters.
 */
function scrambleWord(word){

  if(word.length <= 3)
    return word;

  var selectedIndexes, randomCharIndex, scrambledWord = word;

  while(word === scrambledWord){
    selectedIndexes = [], randomCharIndex, scrambledWord = '';
    scrambledWord += word[0];
    for(var j = 0; j < word.length-2; j++){

      //select random char index making sure it is not repeated
      randomCharIndex = getRandomInt(1, word.length-2);
      while(selectedIndexes.indexOf(randomCharIndex) > -1 && selectedIndexes.length != word.length-2){
        randomCharIndex = getRandomInt(1, word.length-2);
      }

      scrambledWord += word[randomCharIndex];
      selectedIndexes.push(randomCharIndex);
    }
    scrambledWord += word[word.length-1];
  }
  return scrambledWord;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive)
 * Using Math.round() will give you a non-uniform distribution!
 * See: http://stackoverflow.com/a/1527820/1337392
 */
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
</code>```

The problem with this approach, is that it is too slow. I fail the tests because I exceed the time limit of 6 seconds, so I definitely need to improve this solution, but I can't see where I can do it.

From an algorithm perspective, what is the most efficient way that uses the least amount of worst case operations that I can approach this problem?


问:
In C#, what is the benefit of assigning a class variable to an interface variable before calling any methods?
Where I work we develop in C# .NET and I was looking a code that they have made (my job is to optimize it) but I saw something in particular:

Assuming that InterfaceDHO is an interface and ClassDHO is a class that implements InterfaceDHO.

Code:

```<code>InterfaceDHO in1;
ClassDHO cl1 = new ClassDHO();

in1 = cl1;

in1.METHODHERE(ARG HERE, ARG2 HERE);
</code>```

Why are they doing this? Why assign the ClassDHO instance to an interface?

答:
It is possible that ClassDHO doesn't actually implement InterfaceDHO, and the code is doing an implicit conversion (though I don't think that extra step is necessary even then).

It is possible that there used to be different implementations of the interface in that code, so it made sense to split up the variables, but when the others were removed this code wasn't cleaned up.

More likely though, the code was simply written by someone who was bad at programming.


答: Imagine  if your experience was less than 4 years, be a woman, be pretty, be complete in-love of your work as developer and no one take you seriously. Although if you have squashed one and another time in knowledge the men that's surround you but you must pretend all time that you are a silly girl. Yes sometimes it's really frustrating, but I think that everything in live is how much you love what you do, and certainly the only way to really learn is by our own effort.</p>


答:
You are assigning the interface not instantiating

There is nothing to optimize

You just have some line(s) of code that are dealing with the interface.

It is clear that section of code only cares about methods and properties of the interface.

You could have something like this (assuming ClassDHO2 implements InterfaceDHO)

```<code>InterfaceDHO in1;
if(x > y)
{
   ClassDHO  = new ClassDHO();
   in1 = cl1;
}
else
{
   ClassDHO2 cl2 = new ClassDHO2();
   in1 = cl2;
}

in1.METHODHERE(ARG HERE, ARG2 HERE);
</code>```

Consider a method call.

You could pass it the a class that implements InterfaceDHO (cl1) or your variable in1.

```<code>public void(InterfaceDHO interfaceDHO)
{
}
</code>```

Title: In C#, what is the benefit of assigning a class variable to an interface variable before calling any methods?

Body:
Where I work we develop in C# .NET and I was looking a code that they have made (my job is to optimize it) but I saw something in particular:

Assuming that InterfaceDHO is an interface and ClassDHO is a class that implements InterfaceDHO.

Code:

```<code>InterfaceDHO in1;
ClassDHO cl1 = new ClassDHO();

in1 = cl1;

in1.METHODHERE(ARG HERE, ARG2 HERE);
</code>```

Why are they doing this? Why assign the ClassDHO instance to an interface?

Body:
You are assigning the interface not instantiating

There is nothing to optimize

You just have some line(s) of code that are dealing with the interface.

It is clear that section of code only cares about methods and properties of the interface.

You could have something like this (assuming ClassDHO2 implements InterfaceDHO)

InterfaceDHO in1;
if(x > y)
{
   ClassDHO  = new ClassDHO();
   in1 = cl1;
}
else
{
   ClassDHO2 cl2 = new ClassDHO2();
   in1 = cl2;
}

in1.METHODHERE(ARG HERE, ARG2 HERE);

Consider a method call.

You could pass it the a class that implements InterfaceDHO (cl1) or your variable in1.

public void(InterfaceDHO interfaceDHO)
{
}


答:
There is no such thing as an instantiation of an interface.  Interfaces are implemented by classes.  Classes are instantiated.  References are held, either to classes, or to interfaces.

What you are witnessing is (probably) a programmer trying to adhere to the (very good) principle called Program To The Interface, Not To An Implementation.  See:

http://www.fatagnus.com/program-to-an-interface-not-an-implementation/

https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface

So, if the lines that you have shown are the actual code, then this programmer may be a bit confused.  But if the lines that you are showing us have been picked up from different places in the code, (as the blank lines seem to suggest discontinuities in the code listing,) then what is happening is that the code that makes the method call does not want to know anything about the implementation (ClassDHO), it only wants to work with the interface (InterfaceDHO).


答:
If ClassDHO implements InterfaceDHO as follows:

```<code>class ClassDHO : InterfaceDHO
{
    void InterfaceDHO.METHODHERE(arg1, arg2) ...
}
</code>```

then METHODHERE is what's termed an explicit interface implementation, and it can only be accessed via a variable of type InterfaceDHO. The code you show is a little long-winded, but handles that situation. It could be simplied to the following though:

```<code>InterfaceDHO in1 = new ClassDHO();

in1.METHODHERE(ARG HERE, ARG2 HERE);
</code>```

However, if this is not the case, then the following code will, at least for the small snippet you provide, have the same affect:

```<code>var in1 = new ClassDHO();  // in1 will be of type ClassDHO

in1.METHODHERE(ARG HERE, ARG2 HERE);
</code>```

In other words, the interface variable isn't required.

You provide very little code though and in1 may be used in other ways later in the code (or you may have missed bits out), so it's not possible to say for sure.

Body:
If ClassDHO implements InterfaceDHO as follows:

class ClassDHO : InterfaceDHO
{
    void InterfaceDHO.METHODHERE(arg1, arg2) ...
}

then METHODHERE is what's termed an explicit interface implementation, and it can only be accessed via a variable of type InterfaceDHO. The code you show is a little long-winded, but handles that situation. It could be simplied to the following though:

InterfaceDHO in1 = new ClassDHO();

in1.METHODHERE(ARG HERE, ARG2 HERE);

However, if this is not the case, then the following code will, at least for the small snippet you provide, have the same affect:

var in1 = new ClassDHO();  // in1 will be of type ClassDHO

in1.METHODHERE(ARG HERE, ARG2 HERE);

In other words, the interface variable isn't required.

You provide very little code though and in1 may be used in other ways later in the code (or you may have missed bits out), so it's not possible to say for sure.


问:
Multiple controllers for same resource based on user's Role
I'm having trouble designing this role (or permission) based application, when it comes to figuring out how to handle actions that differ per use role.

For instance, our controller is App\ResourceController, and we will be editing the resource. There are 2 roles: admin and user. The admin is allowed to edit every field of the resource, while the user is restricted to some of them.

I'm struggling figuring out the best approach between implementing a single controller that will handle both cases, or routing the request to a different controller for the same resource (like App\Admin\ResourceController, App\User\ResourceController).

The issue with the single controller approach, is that it isn't just showing a different form (with restricted fields) based on role, but also validating different fields and more. The controller's body would pretty much look like a big if-else statement.

Is multiple controller the correct approach, or is there a different one using permissions instead of roles?

答:
In general your choice should be for maintainability and simplicity. In the case you describe it seems that the added complexity from trying to combine the controllers will not be worth the added complexity in the long run.

That being said, making the practical choice between the approaches described depends on the number of elements that differ for user and admin. If that number is small, then the added complexity may be worthwhile.

If you are using an object-oriented environment a third option might be to have the App\Admin\ResourceController inherit from App\User\ResourceController.