问:
Does SOA service composition actually work in practice?
One of the main SOA service design principles is Service Composability principle
(https://en.wikipedia.org/wiki/Service_composability_principle).

The idea is that by composing new services using existing ones as building blocks, one
can rapidly develop new services. Kind of analogously to how you call exising methods
of objects when you implement new methods. This is where much of productivity boost from SOA is supposed to come from.

Does someone really do this in practice? I have seen this repeated endlessly in written
text, but have not experienced working real world implementations myself. Most of the
text also omits any mention of transaction handling, which seems to me to be the
biggest obstacle in realizing composable services.

First, you really do need to tackle the transactions problem before you can compose any
non-trivial services. Sure, if the example has services "findCurrentTime()" and
"writeLogMessage()" its easy to not worry about transactions, but not when having real
world examples such as "depositMoney()" and "withdrawMoney()".

I know of two options:

Implement real transactions with WS-Atomic Transaction or such

Implement compensation-based solution which compensates call to A with "cancelA()"
or somesuch if call to B fails

Both of these seem very problematic / close to unusable to me:

WS-Atomic Transaction

a lot of complexity, most advice that I found just warns "pain in the ass, dont
do it"

support is limited, for example if you take open source ESBs, main alternatives
ServiceMix, Mule or WSO2 do not support it

compensations

implementing the handling of compensations seems very complex to me. What do we do if service A
succeeds and we never get an answer from service B and do not know if it failed or
succeeded? Handling such logic manually (as implementor of compositing services) makes
me want to slit my wrists - this is the kind of work some tool should do for me!.

I also dont see how you can have compensation methods in non-trivial services. Say
your service A is "depositMoney()" and that succeeds, some other action quickly
transfers the money elsewhere, and then we receive "compensateDepositMoney()", what do
we do now? Seems like a big can of worms.

To me it seems that service composition is such a fundamental SOA principle that you
really do not get the benefits of SOA if you cannot (conveniently) compose services.
What's the reality? 90% of SOA users use "criplled SOA" without real service
componsition? Or most users do in fact use service composition and I am exaggerating
the difficulty of it?

答:
Yes, it can be made to work in practice. However, it may not be the best approach and is perhaps used as the default option more than it should. In my opinion, SOA became popular as a way of integrating legacy systems as organisations evolved their IT to automate ever larger tasks. It can be very messy but possibly worth it if legacy systems can be re-used. If you are lucky enough to be starting a green field project, other approaches should be considered before assuming it is the best way to go.

To answer some of your more specific concerns...

You can use transactions:

WS-TX is a PITA and I would avoid it.

All your services may be running in a single application server, in which case you can span them all with an XA transaction. This is why such things as application servers were invented.

Considering the compensation based approach:

Compensating actions only need to be considered when there has been a failure. Does the service composition tool have a flag it can control that is cleared when running a workflow step the first time, but set on subsequent invocations? Like the possible resend flag in JMS. Then you can use what is called a 1.5 phase commit, which basically means go ahead if the flag is clear, but if the flag is set, first make a call to check if the state is already updated and needs to be made a second time. This still requires manual error handling, and can be complex or even impossible as you point out.

In some situations is doesn't matter:

This is the eventually consistent approach. Suppose one service sends an email. If the service composition fails and is re-started, the email gets sent again. That is slightly annoying for the recipient, but they probably realize its a duplicate and everything can continue without much of a problem.

You could also keep a log of emails sent, and use that to de-dup when the flag is set, and in that way only send the email once.

You can use asynchronous messaging to break transactions up into smaller pieces:

Consider a JMS queue which is transactional. Your service coordinator can update its state and post a message to the queue in a single Tx. Downstream services can take messages off, and update their state in a single Tx. Now you are coordinating services in multiple units of work, but each is atomic. If anything fails and has to be restarted no problem.

This still means that you are doing XA transactions over the database and a JMS queue, but this can still be efficient using the last resource gambit to avoid the full over-head of XA.

Alternatively you can use this pattern but with a 1.5 phase commit to the database and JMS. OR you can run JMS without transactions but make it more reliable by clustering.

Async messaging can also help to decouple systems, as producers and consumers can become more independent of each other, reducing the amount of coupling in the over-all system, and making it more flexible. This kind of decoupling is pretty much essential when it comes to large organisations with lots of diverse services.


问:
How do you handle saving blog tags in MVC?
I'm writing my own blog engine as a learning exercise. The blog is fairly functional right now but I'm trying to add a 'tag' feature to it and I'm confused as to what the best way to handle saving a list of tags back to my controller.

My Question:

Should I be passing my list of comma separated tags back to the controller as a single string and converting it into a IList<Tag> there? Or should I be handling this out in the view and then pass an IList<Tag> to the controller?

A sudo-version of my Post.cs model:

```<code>public class Post : IEntity
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
    public IList<Tag> Tags { get; set; }
}
</code>```

and my Tag.cs model:

```<code>public class Tag : IEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<Post> Posts { get; set; }
}
</code>```

update: Sharing some gist files.

PostController.cs

Create.cshtml

答:
When tags are submitted by the author of a blog, they are under a form of a simple string (with either comma-separated values or, like on Stack Exchange, simple spaces). This is the only moment in the workflow when all tags are appearing as a single string.

The controller then splits those tags and trims them. At this stage, those tags become a Collection<string> (or Collection<Tag> if there is specific data or business logic associated with a tag.) Depending on your specific needs, you may need to use other generic collection classes, such as a HashSet<T> if you need to quickly search through the sequence of tags.

The controller may then persist those tags together with the article, the title, the author info, etc. Depending on the persistence layer (i.e. the type of the database) you use, the tags may take different forms, but usually they will still be considered as some sort of array and stored one by one, not as a single value.

Finally, when it comes to displaying the tags, the controller loads them from the persistence layer (the tags are then appearing in a form of a Collection<string>/Collection<Tag>), and stores the collection (eventually as IEnumerable<string>) in the model, passing the model down to the view.

The view enumerates those tags and displays the corresponding HTML.

Looking at your code, I'm not sure what are you trying to do. I guess that Tags is a sequence in your model, but you're displaying only the first element in your view (line 54 and 55). Why?

This is also why I asked in my comments how are tags displayed in the form. Here's one way to bind an array to a sequence of check boxes; I'm not sure this is what you want or need. Probably what you actually need is something similar to Stack Exchange tagging: a single text field where a user can enter one or more words (or comma-separated values in your case). For instance:

data-center, rack, power-management, wiring

will be entered in a single text box and result in four tags: data-center, rack, power-management and wiring.

This leads to the difference between:

The view which shows a form to an author, letting him modifying the article and its tags, and:

The view which shows the article to the end users.

The first view can deal with all tags represented as a simple string. It already does when it comes to submitting a form: the value of a text box—a simple text, is translated to a string which can then be parsed like you did in your code on line 79 with a Split(). Although disturbing,¹ you can also use a string to populate the form when the author wants to modify an article (this makes it possible to use the same model in both cases.) While the model will contain a string containing comma-separated tags, try to use Collection<Tag> as much as possible within the controller itself. The only locations where you should see a string are the boundaries: when the controller receives the input and when it creates a model.

On the other hand, the view which shows the article—and the tags—to the end user should rely completely on IEnumerable<Tag> representation which should be pushed by the controller through the model down to the view. It's the view which will use the sequence to enumerate through the values with a foreach, generating the corresponding HTML.

A final note: when you'll get your code finished, compiling and working, make sure you post a few parts to CodeReview. There are a lot of things to tell about the code in its current state.

¹ The approach is disturbing because a concatenated string is a wrong data structure for tags. The right one remains a sequence (such as Collection<T>). The problem, in your case, is that you're relying on the same model both for generating the form and getting the submitted values. Since you're forced to use a string in the second case, using a sequence in the first one will require to have two different models, which will make your code more complex than it should be.

ContentLicense: CC BY-SA 3.0


问:
How do I convince my users not to use a sketch UI?
I recently worked on a prototype of a new system using Sketchflow, and now some key stakeholders are pushing for a sketched look & feel in the final product. To make matters worse, the people viewing the prototype were asked to provide feedback on the sketched look & feel by way of a fairly leading survey question, to which 80% of the responses were positive.

It's for an enterprise application that will mostly be for internal clients, but is also intended to be used by some external clients.

The main reasons I have for it thinking it's a bad idea are:

It doesn't look polished or professional

The significant effort involved in skinning an actual application in the sketched style

The sketched style doesn't make efficient use of screen real-estate

I've been trying to figure out what the appeal could possibly be, and the only thing I can come up with is that people are attracted to the simplicity of it -- especially when compared with the existing system(s) it will be replacing.

Can anyone point me in the direction of evidence of why using a sketch look & feel is a bad idea? Ideally something based on UI research. I'm worried that my voice isn't going to be listened to unless I can point to something concrete.

[Edit]

I should probably add that the difficulty of skinning the application is compounded by the fact that it is intended to be delivered as one or more Silverlight webparts in a Sharepoint site. Getting a consistent sketched look & feel across both technologies could be very difficult.

[Edit]

Just in case anyone's not sure about what a Sketchflow prototype looks like (and therefore what the people in question are asking for) they're essentially asking for a production application to have a pencil-sketch wireframe look & feel.

答:
My opinion might be slightly biased in this, but I'd suggest a tool like http://IntuitionHQ.com or something of the like where you could run a very quick, simple usability test on the sketched design vs say a wireframe, or more polished looking design.

It doesn't have to be interactive, but if the numbers come back showing that one design is clearly better and more usable than the other (as per your gut instinct), the stakeholders will find it hard to argue.

We've used this method before, and it's very difficult to argue with the results of these tests. If you are interested you can check out some sample results at video.intuitionhq.com/pub/356/1.

Cheers, and good luck with your designs.

ContentLicense: CC BY-SA 2.5


问:
Advantage/Disadvantage of having all variables declared in a JUnit Test
I've been writing some unit tests for some new code at work, and sent it off for a code review. One of my co-workers made a comment about why I was putting variables that are used in a number of those tests outside of the scope for the test.

The code I posted was essentially

```<code>import org.junit.Test;

public class FooUnitTests {

    @Test
    public void testConstructorWithValidName() {
        new Foo(VALID_NAME);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithNullName() {
        new Foo(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithZeroLengthName() {
        new Foo("");
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithLeadingAndTrailingWhitespaceInName() {
        final String name = " " + VALID_NAME + " ";
        final Foo foo = new Foo(name);

        assertThat(foo.getName(), is(equalTo(VALID_NAME)));
    }

    private static final String VALID_NAME = "name";
}
</code>```

His proposed changes were essentially

```<code>import org.junit.Test;

public class FooUnitTests {

    @Test
    public void testConstructorWithValidName() {
        final String name = "name";
        final Foo foo = new Foo(name);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithNullName() {
        final String name = null;
        final Foo foo = new Foo(name);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithZeroLengthName() {
        final String name = "";
        final Foo foo = new Foo(name);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithLeadingAndTrailingWhitespaceInName() {
        final String name = " name ";
        final Foo foo = new Foo(name);

        final String actual = foo.getName();
        final String expected = "name";

        assertThat(actual, is(equalTo(expected)));
    }
}
</code>```

Where everything that is required within the scope of the test, is defined within the scope of the test.

Some of the advantages he argued were

Each test is self contained.

Each test can be executed in isolation, or in aggregation, with the same result.

Reviewer doesn't have to scroll to wherever these parameters are declared to look up what the value is.

Some of the disadvantages of his method that I argued were

Increases code duplication

Can add noise to the reviewers mind if there are several similar tests with different values defined (ie. test with doFoo(bar) results in one value, while the same call has a different result because bar is defined differently in that method).

Aside from convention, are there any other advantages/disadvantages of using either method over the other?

答:
It depends. In general, having repeating constants declared in only one place is a good thing.

However, in your example, there is no point in defining a member VALID_NAME in the shown way. Assumed in the second variant a maintainer changes the text name in the first test, the second test will most probably be still valid, and vice versa. For example, lets assume you want additionally test upper and lower case letters, but also keep a test case just with lower case letters, with as few test cases as possible. Instead of adding a new test, you could change the first test to

```<code>public void testConstructorWithValidName() {
    final String name = "Name";
    final Foo foo = new Foo(name);
}
</code>```

and still keep the remaining tests.

In fact, having a lot of tests depending on such a variable, and changing the value of VALID_NAME later may unintentionally break some of your tests at a later point in time. And in such a situation, you can indeed improve the self-containment of your tests by not introducing an artificial constant with different tests depending on it.

However, what @KilianFoth wrote about not repeating yourself is correct, too: follow the DRY principle in test code the same way you do it in business code. For example, introduce constants or member variables when it is essential for your test code that their value is the same in every place.

Your example show how tests tend to repeat initialization code, that's a typical place to start with refactoring. So you may consider to refactor the repetition of

```<code>  new Foo(...);
</code>```

into a separate function

```<code> public Foo ConstructFoo(String name)
 {
     return new Foo(name);
 }
</code>```

since it will allow you to change the signature of the Foo constructor at a later point in time more easily (because there are fewer places where new Foo is actually called).

Body:
It depends. In general, having repeating constants declared in only one place is a good thing.

However, in your example, there is no point in defining a member VALID_NAME in the shown way. Assumed in the second variant a maintainer changes the text name in the first test, the second test will most probably be still valid, and vice versa. For example, lets assume you want additionally test upper and lower case letters, but also keep a test case just with lower case letters, with as few test cases as possible. Instead of adding a new test, you could change the first test to

public void testConstructorWithValidName() {
    final String name = "Name";
    final Foo foo = new Foo(name);
}

and still keep the remaining tests.

In fact, having a lot of tests depending on such a variable, and changing the value of VALID_NAME later may unintentionally break some of your tests at a later point in time. And in such a situation, you can indeed improve the self-containment of your tests by not introducing an artificial constant with different tests depending on it.

However, what @KilianFoth wrote about not repeating yourself is correct, too: follow the DRY principle in test code the same way you do it in business code. For example, introduce constants or member variables when it is essential for your test code that their value is the same in every place.

Your example show how tests tend to repeat initialization code, that's a typical place to start with refactoring. So you may consider to refactor the repetition of

  new Foo(...);

into a separate function

 public Foo ConstructFoo(String name)
 {
     return new Foo(name);
 }

since it will allow you to change the signature of the Foo constructor at a later point in time more easily (because there are fewer places where new Foo is actually called).


问:
Understanding the static keyword
I have some experience in developing with Java, Javascript and PHP.

I am reading Microsoft Visual C# 2010 Step by Step which I feel it is a very good book on introducing you to the C# language.

I seem to be having problems in understanding the static keyword. From what I understand this far if a class is declared static all methods and variable have to be static. The main method always is a static method so in the class that the main method exists all variables and methods are declared static if you have to call them in the main method. Also I have noticed that in order to call a static method from another class you do not need to create an object of that you can use the class name.

But what is the actual purpose of the static keyword? When should I declare static variable and methods?

答:
Static members are associated with the Class, not with any instance of that Class.

Since we're talking about .Net, consider the String class, in particular the Split and Join methods.

Split is an instance method.  Create a String variable, give it a value and you can call Split() on that variable/ value and get back an array of "bits" :

```<code>String s1 = "abc,def,ghi" ;
String[] array2 = s1.Split( ',' ) ;
</code>```

So, for instance methods, the value held within the given class instance matters.

Join is a static method.  OK, it yields a String result when given a delimiter and a String array to chew on, so it is "something to do with" the String Class, but it's not associated with any particular value in any String instance (indeed, instance values are not available to static methods).

In other languages, the Join method might have been "stuck onto" the Array Class (or, perhaps better, a StringArray Class) but Our Friends in Redmond decided that it was more "relevant" to the String class, so they put it there.

```<code>String[] array3 = { ... }
s1 = String.Join( array3, "," ) ;
</code>```

Another alternative might have been to have an instance Join method, where the value held within the String [class instance] us used as the joining delimiter, something like:

```<code>// Maybe one day ...
String s4 = "," ;
s1 = s4.Join( array3 ) ;
</code>```

Title: Understanding the static keyword

Body:
Static members are associated with the Class, not with any instance of that Class.

Since we're talking about .Net, consider the String class, in particular the Split and Join methods.

Split is an instance method.  Create a String variable, give it a value and you can call Split() on that variable/ value and get back an array of "bits" :

String s1 = "abc,def,ghi" ;
String[] array2 = s1.Split( ',' ) ;

So, for instance methods, the value held within the given class instance matters.

Join is a static method.  OK, it yields a String result when given a delimiter and a String array to chew on, so it is "something to do with" the String Class, but it's not associated with any particular value in any String instance (indeed, instance values are not available to static methods).

In other languages, the Join method might have been "stuck onto" the Array Class (or, perhaps better, a StringArray Class) but Our Friends in Redmond decided that it was more "relevant" to the String class, so they put it there.

String[] array3 = { ... }
s1 = String.Join( array3, "," ) ;

Another alternative might have been to have an instance Join method, where the value held within the String [class instance] us used as the joining delimiter, something like:

// Maybe one day ...
String s4 = "," ;
s1 = s4.Join( array3 ) ;


问:
Are there flavours of OOP where some or all of the SOLID principles are antithetical to clean code?
I recently had a discussion with a friend of mine about OOP in video game development.

I was explaining the architecture of one of my games which, to my friend's surprise, contained many small classes and several abstraction layers.  I argued that this was the result of me focusing on giving everything a Single Responsibility and also to loosen the coupling between components.

His concern was that the large number of classes would translate to a maintenance nightmare.  My view was that it would have the exact opposite effect.  We proceeded to discuss this for what seemed like centuries, eventually agreeing to disagree, saying that perhaps there were cases where SOLID principles and proper OOP didn't actually mix well.

Even the Wikipedia entry on SOLID principles states that they're guidelines that help to writing maintainable code and that they are part of an overall strategy of agile and adaptive programming.

So, my question is:

Are there cases in OOP where some or all of the SOLID principles do not lend themselves to clean code?

I can imagine right away that the Liskov Substitution Principle could possibly conflict with another flavour of safe inheritance.  That is to say, if someone devised another useful pattern implemented through inheritance, it is quite possible the LSP might be in direct conflict with it.

Are there others?  Perhaps certain types of projects or certain target platforms work better with a less SOLID approach?

Edit:

I'd just like to specify that I'm not asking how to improve my code ;)  The only reason I mentioned a project in this question was to give a little context.  My question is about OOP and design principles in general.

If you're curious about my project, see this.

Edit 2:

I imagined this question would be answered in one of 3 ways:

Yes, there exist OOP design principles which partially conflict with SOLID

Yes, there exist OOP design principles which completely conflict with SOLID

No, SOLID is the bee's knees and OOP will forever be better with it.  But, as with everything, it's not a panacea.  Drink responsibly.

Options 1 and 2 would have likely generated long and interesting answers.  Option 3, on the other hand, would be a short, uninteresting, but overall reassuring, answer.

We seem to be converging onto option 3.

答:
SOLID principles are good, but KISS and YAGNI takes priority in case of conflicts. The purpose of SOLID is managing complexity, but if applying SOLID itself makes the code more complex it defeats the purpose. To take an example, if you have small program with only few classes, applying DI, interface segregation etc. might very well increase the overall complexity of the program.

The open/closed principle is especially controversial. It basically says you should add features to a class by creating a subclass or a separate implementation of the same interface, but leave the original class untouched. If you are maintaining a library or service used by uncoordinated clients, this makes sense, since you don't want to break behavior which exiting client may rely on. However if you are modifying a class which is only used in your own application, it would often be much simpler and cleaner to simply modify the class.


问:
Should program arguments have mixed interpretations?
I'm developing a command-line tool that has many user options. Some of the options are lists of values. I'd like the program to be able to parse these listed options directly from the command line, and via a file (e.g. --opt=valA,valB and --opt=vals.txt).

Is it preferable to have two separate options for each case, or have the program interpret the arguments at runtime? I've seen programs doing it both ways but I can't decide which is the better design (if there is an objective reason).

答: You've seen programs that interpret option arguments both as a filename and as literals? Depending on what, the state of the file system? That's an insidious defect or exploit waiting to happen. Never, never, ever do this.


问:
Ternary operator considered harmful?
For example, would you prefer this one-liner

```<code>int median(int a, int b, int c) {
    return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
</code>```

or an if/else solution involving multiple return statements?

When is ?: appropriate, and when is it not? Should it be taught to or hidden from beginners?

答:
When is  appropriate, and when is it not?

I think that when developing for a homogeneous group of people, there is no problem but when you have to deal with people that handle different levels, this kind of oneliners only introduce a further level of complexyti to the code. So, my policy on the matter is: code clear and dont explain rather than code short and explain 123123 times.

Should it be taught to or hidden from
  beginners?

I should not be taught to beginners, rather prefert them to figure it out when need emerges, so it'll be used only when necesary and not every time you need an if.

Title: Ternary operator considered harmful?


问:
Is code commonly generated from UML?
So when I was at university I was educated on the benefits of UML and its future in code development.

But from my industry experience, I've found that while we do use diagrams—ranging from ER diagrams, class diagrams, state diagrams, to work flow diagrams—all of it is for communication purposes.

That is, I've never generated code automatically from diagrams, and from a communication standpoint, I generally try to keep my diagrams as simple and easy to understand as possible.

But when I look at Visio and Enterprise Architect, it seems they have many different types of graphs, shapes, properties objects, most of which I don't use.

Do people use UML to do more sophisicated things such as code or database generation?

答:
I think we can use UML to generate code. Not business logic, as business logic is not a standard and varies application to application.
Class diagrams along with ER diagrams can be used for generating interfaces, classes, hibernate entities, basic dao methods, etc.
Other boilerplate code like facade implementation, data type converters(e.g entity to transfer objects)can also be generated with help of object digrams.

Also, as mentioned in previous comments, database schema, DDL scripts, etc. can be generated using models.

Using OAW, and modelling tool like Enterprise Architect, we can write stronger code generators, which can even help in generating configuration files, factory code using stereotypes and tagged values.

Title: Is code commonly generated from UML?


问:
Design suggestions for converters in Java
I'm trying a set of converters which will convert an object to some older form. And there are different objects which are converted. By older form I mean changing the values of some fields and in case of file objects making changes such that the new file complies to older schema, etc.

```<code>A convertObjectAToOldFormat(A a);
B convertObjectBToOldFormat(B b);
</code>```

Should I create class for each of this converters? Or Can I put all of them in a single class and expose the interface to clients?
Or is there any design which will handle this better?

Language used is Java

答:
Which class should know how to convert a new A to a legacy A?

Maybe it's the A class itself which has this knowledge. It may know how new and legacy values are mapped, which fields should be added or removed, etc. In this case the following approach seems quite natural:

```<code>A legacyA = a.toLegacy();
</code>```

The benefit of this approach is consistency: it's similar to toString() method which converts, say, an integer or a double to a string. The interesting part here is that while toString of an int creates an instance of a completely different type (string), toLegacy returns an instance of the same type.

The drawback is the violation of SRP principle, as well as the fact that the conversion code (especially to some legacy forms) is polluting the class. If the conversion logic is complex and has few things to do with A itself, it makes sense to move this code to a separate class.

This situation is very similar to factory pattern and abstract factory pattern: when the logic required for creating instances of a class becomes too complex to remain in the class itself (in a form of a static method), then factory pattern is used. If there are many similar entities, an abstract factory pattern starts to be valuable.

In a similar way, you can have your abstract converter class, and the concrete classes which deal with the conversions of different business entities:

```<code>abstract class ConverterToLegacy<T>
{
    public T Convert(T businessEntity);
}

class ConverterToLegacyA implements ConverterToLegacy<A>
{
    public A Convert(A a)
    {
        ...
    }
}

class ConverterToLegacyB implements ConverterToLegacy<B>
{
    public B Convert(B b)
    {
        ...
    }
}
</code>```

Body:
Which class should know how to convert a new A to a legacy A?

Maybe it's the A class itself which has this knowledge. It may know how new and legacy values are mapped, which fields should be added or removed, etc. In this case the following approach seems quite natural:

A legacyA = a.toLegacy();

The benefit of this approach is consistency: it's similar to toString() method which converts, say, an integer or a double to a string. The interesting part here is that while toString of an int creates an instance of a completely different type (string), toLegacy returns an instance of the same type.

The drawback is the violation of SRP principle, as well as the fact that the conversion code (especially to some legacy forms) is polluting the class. If the conversion logic is complex and has few things to do with A itself, it makes sense to move this code to a separate class.

This situation is very similar to factory pattern and abstract factory pattern: when the logic required for creating instances of a class becomes too complex to remain in the class itself (in a form of a static method), then factory pattern is used. If there are many similar entities, an abstract factory pattern starts to be valuable.

In a similar way, you can have your abstract converter class, and the concrete classes which deal with the conversions of different business entities:

abstract class ConverterToLegacy<T>
{
    public T Convert(T businessEntity);
}

class ConverterToLegacyA implements ConverterToLegacy<A>
{
    public A Convert(A a)
    {
        ...
    }
}

class ConverterToLegacyB implements ConverterToLegacy<B>
{
    public B Convert(B b)
    {
        ...
    }
}


答:
The test to apply is whether or not someone can definitively understand the intent of the arguments just by looking at them.

In your example, the interpretation of --opt=foo would vary depending on the program's surroundings.  That could sow confusion or, worse, cause a security problem if there's a file named foo in the current working directory and the intent was foo as a literal.  (This, by the way, is why putting . or other relative directories in the program search path is considered unsafe.)

There are two ways to make the intent clear:

Use different switches (e.g., --opt=foo and --opt-file=bar.txt).

Add a sigil to the beginning of the value to indicate that it's a file and not a literal.  Some programs use @ (e.g., --opt=foo and --opt=@bar.txt).  This comes at the expense of not being able to specify literals starting with that character without escaping it.

Either could easily be added to an argument parsing library or simply dealt with when you have the results.

Title: Should program arguments have mixed interpretations?

Body:
I'm developing a command-line tool that has many user options. Some of the options are lists of values. I'd like the program to be able to parse these listed options directly from the command line, and via a file (e.g. --opt=valA,valB and --opt=vals.txt).

Is it preferable to have two separate options for each case, or have the program interpret the arguments at runtime? I've seen programs doing it both ways but I can't decide which is the better design (if there is an objective reason).


问:
What are the pros and cons of HTML5, native and hybrid mobile app approaches?
I want to develop a mobile application. I recently read an article on Telerik Forum, which compares among three types of mobile application and I don't know which one should I select to begin with. Here is an image describing the pros and cons of different mobile design choices

To decide between these design choices, I would like to better understand the pros and cons of each architecture choice listed in the diagram.  What are the pros and cons of each architecture approach?

答:
Being a mobile developer myself, the worst thing is offline access. You simply force users to be online which should work in a lot of apps, but not in all.

The other great bad aspect is slowness. Time needed to parse remote data can take significant time. Yes, you can pre-fetch data during the load time, but in all other cases you cannot avoid slowness.

I found that such app ended app more expensive than native ones. I no longer recommend them to any client of mine.


答:
You could have a factory which provides the correct adapted object.

Exposing a series of classes or a single class with multiple methods assumes that you have some knowledge before hand of the system. Another (problematic, I think) issue is that by exposing all the adapters you are giving the caller (client) complete control over which adapter gets called.

This, in my opinion, could cause some issues since someone might try and find a way (on purpose of by accident) around some internal mechanisms you might have (validation comes to mind) which could be problematic.

Having 1 endpoint which is exposed to the user and having some logic which does everything which needs doing provides you with more control.

Title: Design suggestions for converters in Java

Body:
I'm trying a set of converters which will convert an object to some older form. And there are different objects which are converted. By older form I mean changing the values of some fields and in case of file objects making changes such that the new file complies to older schema, etc.

```<code>A convertObjectAToOldFormat(A a);
B convertObjectBToOldFormat(B b);
</code>```

Should I create class for each of this converters? Or Can I put all of them in a single class and expose the interface to clients?
Or is there any design which will handle this better?

Language used is Java


问:
Should I include the research time in a agile task?
I was given a project for a logging framework. It has many tasks of course. One of them is "Create a Class that can Log to a nLog Target"(6 hours). However I am not familiar with Nlog. I guess that I need a lot of google research time. I am not sure whether should I include the research time. If so then six hours is obvious not enough. I am confused the task time, is it the pure coding time?

EDIT:

We don't have a research spike in the process but we have two hours for research NLog API.

答:
Ken Rubin answered this at a training workshop for us. His advice was to either use a research spike or to use a story task for the training. In your case, you know what product that you are using, and you just need to account for the learning curve. I would recommend a learning task. I remember during the class someone asked if we could just create a story like "As a software engineer, I want to learn NLog...." This was answered with a firm "No" because the story does not provide business value, but as a team you are free to create the tasks needed to accomplish a story. My team recently needed to learn Elastic Search and we did just this.

Ken Rubin elaborates more in the "PBI Type: Knowledge Acquisition" section here
http://www.innolution.com/blog/demystifying-product-backlog-concepts


问:
Would it look unprofessional to ask users of a mobile app to uninstall app then install it again (clean install)?
One app I am supporting has a very nasty bug in user's private preferences. This bug does not happen now, but is inherited from some previous bad release and now the oldest users have this bug.

I've done zillions of testing how to fix this, but the only real fix it "clean install" of the app (uninstall the current one, lose all preferences and reinstall it again).

This sounds like a horrible idea.

Has anyone seen any app advises users to do the clean install? Is this unprofessional as it look like?

Any other suggestion how to overcome this situation and not lose credibility?

答:
This bug does not happen now, but is inherited from some previous bad release

This may be the key here.

If you ask a complete reinstall every time you release a new version, this looks indeed very unprofessional. It may be OK if the users don't customize your app, so losing previous configuration wouldn't be an issue. If they do and spend at least several minutes doing it, it will quickly become annoying: they will either install a similar app released by your competitor, or stop customizing it.

On the other hand, since there is a before and a now, and upgrading works well unless the user has a previous version, this situation is more common and somehow similar to breaking backwards compatibility. You can do one of the following:

Increment a version number and tell that upgrading from YourApp 3.0 to YourApp 4.0 requires a full uninstall.

If you're, say, at version 3.7.15, and the upgrade works well since 3.4.82, but not for 3.4.81, just document that such upgrade is not supported. If the user attempts to upgrade, the updater should indicate that the option is not supported and will result in the loss of preferences.

Finally, in all cases, backup users' preferences before doing the upgrade. This has two consequences:

If the upgrade fails, the user will be pissed off but will still be able to go back to the previous version without losing anything.

After a fresh install, you can use the backup to get some of the preferences you know to be fail-safe. Losing only a part of the preferences is slightly better than losing everything.


答: Surely a new release of your application should be able to recognise whatever bad information was left over from a previous application and be able to discard it. So yes, asking the user to completely remove a previous install and install from fresh looks very unprofessional to me. </p>

Title: Would it look unprofessional to ask users of a mobile app to uninstall app then install it again (clean install)?

Body:
One app I am supporting has a very nasty bug in user's private preferences. This bug does not happen now, but is inherited from some previous bad release and now the oldest users have this bug.

I've done zillions of testing how to fix this, but the only real fix it "clean install" of the app (uninstall the current one, lose all preferences and reinstall it again).

This sounds like a horrible idea.

Has anyone seen any app advises users to do the clean install? Is this unprofessional as it look like?

Any other suggestion how to overcome this situation and not lose credibility?


答:
The word "research" is indeed being overused in agile. The word can be broken down into:

learning, or reading documentation, or learning-from-trying.

This is just "learning".

This is not meant to belittle the time needed for learning.

It can take a long time, e.g. weeks to months, but the learning process should be considered and included into the time estimate.

It can take a short time - if the team has already used something similar before.

broadly survey from a large number of options, gathering basic information and characteristics (specs, limitations) about each, but avoiding actual coding (i.e. without committing to any).

This was previously called "research" but should have been called "survey".

make a single implementation attempt in order to validate / explore a semi-committed implementation choice.

This is a "spike".

make repeated implementation attempts in order to competitively select one or more implementation choices, but with the understanding that the final implementation will only benefit from one of a few such choices.

This is a true "research".

Coding time spent on inferior choices (which are not known in the beginning but are gradually revealed during the multiple attempts) do not contribute to the business value.

Because of this, it is advised to try "ferret out" and eliminate inferior choices as early as possible.

However, one needs to keep in mind the possibility that an earlier determination of inferiority may change as more information becomes available.

In your situation, it belongs to the first case (learning), therefore:

The 6 hours you mentioned is the planned time for all of the work needed to "create a task that can ..."

Any learning (as explained in the first case) are included in this 6 hours.

It is possible that it will take more than 6 hours. Task estimates are estimates. When estimates are exceeded, the scrummaster will know that in the next day's meeting, and generally the team will be allowed to continue to work on it. Estimates are not deadlines.

The word "time-box" in Scrum also has multiple meanings.

Within a single sprint, it is not a "deadline". When a task took more than the estimates, the team can discuss it, either as a follow-up to the daily stand-up, or perhaps during the sprint retrospective.

The purpose of such discussion is that if a task took much more than the estimate, the team has implicitly discovered or experienced something new - something that will slow down the task, which was not considered when the original estimate was made.

It may be that the task is indeed more difficult than originally planned.

Whatever that is, such new information need to be incorporated into future time estimates.

The dissemination of such experience is the reason for the discussion.

The word "time-box", as used here, is to make sure this discussion happens, that will not go unnoticed.

A "time-box" is a "deadline" only when decided so by the ultimate decision maker, that is, when the stakeholder has the consensus that the feature needs to be dropped because it appears to be unimplementable given the current circumstances and resources.

Disclaimers.

This is my personal opinion.

I don't practice any agile methodology.

My opinion may have many inaccuracies, mistakes and misunderstandings from the point-of-view of the scrum or agile methodology.

I don't have any certificates, trainings, or credentials in relation to anything.

I am personally frustrated by the overuse of the word "research", because in the rare case that a person claiming to do "research" for the case one (learning something), may impede a person actually doing "research" for the case four (actually inventing some new algorithms), by weakening and belittling the claims in the face of project managers or agile practitioners.

Title: Should I include the research time in a agile task?

Body:
I was given a project for a logging framework. It has many tasks of course. One of them is "Create a Class that can Log to a nLog Target"(6 hours). However I am not familiar with Nlog. I guess that I need a lot of google research time. I am not sure whether should I include the research time. If so then six hours is obvious not enough. I am confused the task time, is it the pure coding time?

EDIT:

We don't have a research spike in the process but we have two hours for research NLog API.


问:
Why is it faster to compact a portion of the managed heap than the entire heap?
I was reading this article on MSDN. In the first paragraph under
 the "Generations and Performance" subheading is written:

First, it is faster to compact the memory for a portion of the managed
  heap than for the entire managed heap.

But why ?

答:
The article does not go into any detail to back up that claim, however, there is a simple explanation.

If A is a portion of the heap and B is the entire heap, then clearly compacting A is less work than compacting B because it is smaller. There are fewer chunks of memory to track, fewer memory copies being performed, and fewer pointers to update (the simplified description of references in memory-managed languages are actually double pointers, and they need to be updated during trash compaction).


问:
How do you avoid getters and setters?
I'm having something of a hard time with designing classes in an oo way. I've read that objects expose their behavior, not their data; therefore, rather than using getter/setters to modify data, the methods of a given class should be "verbs" or actions operating on the object. For example, in an 'Account' object, we would have the methods Withdraw() and Deposit() rather than setAmount() etc. See: Why getter and setter methods are evil.

So for example, given a Customer class that keeps alot of information about the customer, e.g. Name, DOB, Tel, Address etc., how would one avoid getter/setters for getting and setting all those attributes? What 'Behavior' type method can one write to populate all that data?

答:
It is perfectly fine to have an object which exposes data rather than behavior. We just call it a "data object". The pattern exists under names like Data Transfer Object or Value Object. If the purpose of the object is to hold data, then getters and setters are valid to access the data.

So why would someone say "getter and setter methods are evil"? You will see this a lot - someone takes a guideline which is perfectly valid in a specific context and then remove the context in order to get a more hard-hitting headline. For example "favor composition over inheritance" is a fine principle, but soon enough someone is going to remove the context and write "Why extends is evil" (hey, same author, what a coincidence!) or "inheritance is evil and must be destroyed".

If you look at the content of the article it actually have some valid points, it just stretches the point to make a click-baity headline. For example, the article states that implementation details should not be exposed. This is the principles of encapsulation and data hiding which are fundamental in OO. However, a getter method does not by definition expose implementation details. In the case of a Customer data object, the properties of Name, Address etc. are not implementation details but rather the whole purpose of the object and should be part of the public interface.

Read the continuation of the article you link to, to see how he suggest actually setting properties like 'name' and 'salary' on a 'Employee'-object without the use of the evil setters. Turns out he uses a pattern with an 'Exporter' which is populated with methods called addName, addSalary which in turn sets fields of the same name... So in the end he ends up using exactly the setter pattern, just with a different naming convention.

This is like thinking you avoid the pitfalls of singletons by renaming them therecanbeonlyonethings while keeping the same implementation.

Title: How do you avoid getters and setters?


答:
The simplest way to avoid setters is to hand the values to the constructor method when you new up the object.  This is also the usual pattern when you want to make an object immutable.  That said, things are not always that clear in the real world.

It is true that methods should be about behavior.  However, some objects, like Customer, exist primarily to hold information.  Those are the kinds of objects that benefit the most from getters and setters; were there no need at all for such methods, we would simply eliminate them altogether.

Further Reading

When are Getters and Setters Justified

Title: How do you avoid getters and setters?

Body:
I'm having something of a hard time with designing classes in an oo way. I've read that objects expose their behavior, not their data; therefore, rather than using getter/setters to modify data, the methods of a given class should be "verbs" or actions operating on the object. For example, in an 'Account' object, we would have the methods Withdraw() and Deposit() rather than setAmount() etc. See: Why getter and setter methods are evil.

So for example, given a Customer class that keeps alot of information about the customer, e.g. Name, DOB, Tel, Address etc., how would one avoid getter/setters for getting and setting all those attributes? What 'Behavior' type method can one write to populate all that data?


答:
Simplest explanation ---
Static => Only one copy will exist per environment.

So within a VM or CLR there will only ever be one copy of a static class, and, any other class referencing it will have to share its methods and data with all the other classes referencing it.

For a static variable, there will only be one instance of this variable in the run time environment no matter how many copies of the owning class are created when they reference a static variable they will all reference the same piece of storage.

Title: Understanding the static keyword

Body:
I have some experience in developing with Java, Javascript and PHP.

I am reading Microsoft Visual C# 2010 Step by Step which I feel it is a very good book on introducing you to the C# language.

I seem to be having problems in understanding the static keyword. From what I understand this far if a class is declared static all methods and variable have to be static. The main method always is a static method so in the class that the main method exists all variables and methods are declared static if you have to call them in the main method. Also I have noticed that in order to call a static method from another class you do not need to create an object of that you can use the class name.

But what is the actual purpose of the static keyword? When should I declare static variable and methods?


问:
How to name variables without plural in a for-each loop?
How do you name loop variables when the list item is named after something without a plural? For instance (in python): [x for x in sheep]. x is not a great name, but sheep have/has no plural that distinguishes it from the singular.

Is there a general best-practice for naming such variables, to emphasise clarity, and avoid confusion?

答: Names should be expressive in direct proportion to their scope. A loop variable should have a really small scope, so it's perfectly alright to just call it s. If this makes the code unreadable, you should refactor the loop code into a method, not find a longer variable name.


问:
Generic PHP web interface for handling concurrent updates optimistically
I'm looking in to writing a new PHP based CMS which handles concurrent edits optimistically like source version control rather than pessimistic locking like Wordpress.  I want to be able to write some general PHP pages to handle any conflict in a user friendly way so that conflict solving is simple, history is kept and reverting is easy.

I want to use a database and need to design it first.  My ideas so far:

Have a history table storing all updates like in Wordpress with a version number.

When a user saves a record, it will check whether there have been other updates since.  This is quite easy to do if you save a checkout version id in the session when the user starts to edit and you can end up with the 3 ids for the saves you want to merge.

How do I display this to the user in a friendly way? I cannot find any information about PHP interfaces for merging things like this.  I know there are whole apps like kmerge doing this for just plain text files and I want to know how to do it at a database record level.

Is my design so far solid? What else do I need?

答:
Have a history table storing all updates like in Wordpress with a
  version number.

Yes, but store not updates, but complete revisions (contents of each edit). If you need to save space, compress it. But don't care too much about the size. Humans are rarely capable of producing large volumes of data by themselves. There are many libraries, that can compute diffs between two versions and you can display them to user in a very friendly way.

When a user saves a record, it will check whether there have been
  other updates since. This is quite easy to do if you save a checkout
  version id in the session when the user starts to edit and you can end
  up with the 3 ids for the saves you want to merge.

You just need to differentiate content revisions and content drafts. When user edits some text, the only thing that gets saved should be a draft of his work. No need to store revisions of drafts. Only when user confirms to propagate his changes as final ones, a revision is created.


答:
To transform the Customer-class from a data object, we can ask ourselves the following questions about the data fields:

How do we want to use {data field}?  Where is {data field} used?  Can and should the use  of {data field} be moved to the class?

E.g.:

What is the purpose of Customer.Name?

Possible answers, display the name in a login web page, use the name in mailings to the customer.

Which leads to methods:

Customer.FillInTemplate(…)

Customer.IsApplicableForMailing(…)

What is the purpose of Customer.DOB?

Validating the customer's age.  Discounts on the customer's birthday.  Mailings.

Customer.IsApplicableForProduct()

Customer.GetPersonalDiscount()

Customer.IsApplicableForMailing()

Given the comments, the example object Customer – both as a data object and as "real" object with its own responsibilities – is too broad; i.e. it has too much properties/responsibilities.  Which leads to either lots of components depending on Customer (by reading its properties) or to Customer depending on lots of components.  Perhaps there exist different views of customer, perhaps each should have its own distinct class1:

The customer in the context of Account and monetary transactions is probably only used to:

help humans identify that their money transfer goes to the correct person; and

group Accounts.

This customer does not need fields like DOB, FavouriteColour, Tel, and perhaps not even Address.

The customer in the context of a user logging in to a banking website.

Relevant fields are:

FavouriteColour, which might come in the form of personalised theming;

LanguagePreferences, and

GreetingName

Instead of properties with getters and setters, these might be captured in a single method:

PersonaliseWebPage(Template page);

The customer in the context of marketing and and personalised mailing.

Here not relying on the properties of a dataobject, but instead starting from the responsibilities of the object; e.g.:

IsCustomerInterestedInAction(); and

GetPersonalDiscounts().

The fact that this customer object has a FavouriteColour property, and/or an Address property becomes irrelevant: perhaps the implementation uses these properties; but it might also use some machine learning techniques and use previous interactions with the customer to discover in which products the customer might be interested.

 1. Of course, the Customer and Account classes were examples, and for a simple example or homework exercise, splitting this customer might be overkill, but with the example of splitting, I hope to demonstrate that the method of turning a data object into an object with responsibilities will work.

Title: How do you avoid getters and setters?

ContentLicense: CC BY-SA 4.0


问:
How do I model partial dates in Python? Like an unknown year, or unknown day of the month?
I want to be able to capture facts like Bob was born in 2000 and Bill's birthday is May 7th.

In both examples we know only part of the person's birth date. In one case we know only the year; in the other case we know the month and day, but not the year.

How do I capture this information?

A few examples of how this might work:

Imagine a library like datetime which allowed None in the fields to represent unknowns. I might have code like the following:

```<code>date_a = date(2000, 5, None)
date_b = date(2000, 6, None)
difference = date_b - date_a
assert difference.min.days == 1
assert difference.max.days == 60  # Or something close to 60.
assert equal(date_a, date_b) == False

date_c = date(2000, 5, None)
assert equal(date_a, date_c) == Maybe
</code>```

This is just an example of how it might behave. I don't necessarily want this precise behavior.

答:
Robert Harvey's second comment contains the right answer, but let me expand on it a bit.

People's year of birth and people's birthdates are completely different entities, so you do not need to (and actually you should not) use the same mechanism for both.

For birthdates, you can devise a BirthDate data type (or possibly a YearlyRecurringDate though I cannot come up with a decent name right now) which would only contain a date with a constant year, like 2000 by convention.  Year 2000 is a good choice because it was leap, so it will not fail people whose birthday is on Feb 28th.

For birth years, you can devise a BirthYear data type (or possibly an ApproximateDate data type) which would contain a date, and an indicator of the precision: Year, Month, Full.

The benefit of these approaches is that at the heart of things you still maintain a date so you can still perform date arithmetic.


答:
First of all, once you start decomposing dates into their constituent components, they are no longer dates.

In the same way that it is not possible to remove functionality via subclasses without breaking OOP, it is not possible to mix dates and date fractions without causing confusion (or worse) making them compatible as in your code example without breaking something else.

If you want to capture a year, what is wrong with an object containing a simple integer? If you want to capture a month and day, why not capture a month enumeration and an integer day? Maybe even store them internally in a date object so you get proper bounds checking (e.g. February 31 makes no sense). Expose a different interface, however.

Why would you want to compare a date to a year to see if they are the same, greater, or lesser? It makes no sense: there is not sufficient information to make that comparison. However, there are other comparisons that might make sense (this is pseudocode):

```<code>Year y = Year(2015)
Date d = Date(2015, 01, 01)
assert y.contains(d) == True
</code>```

Title: How do I model partial dates in Python? Like an unknown year, or unknown day of the month?

Body:
I want to be able to capture facts like Bob was born in 2000 and Bill's birthday is May 7th.

In both examples we know only part of the person's birth date. In one case we know only the year; in the other case we know the month and day, but not the year.

How do I capture this information?

A few examples of how this might work:

Imagine a library like datetime which allowed None in the fields to represent unknowns. I might have code like the following:

```<code>date_a = date(2000, 5, None)
date_b = date(2000, 6, None)
difference = date_b - date_a
assert difference.min.days == 1
assert difference.max.days == 60  # Or something close to 60.
assert equal(date_a, date_b) == False

date_c = date(2000, 5, None)
assert equal(date_a, date_c) == Maybe
</code>```

This is just an example of how it might behave. I don't necessarily want this precise behavior.

Body:
First of all, once you start decomposing dates into their constituent components, they are no longer dates.

In the same way that it is not possible to remove functionality via subclasses without breaking OOP, it is not possible to mix dates and date fractions without causing confusion (or worse) making them compatible as in your code example without breaking something else.

If you want to capture a year, what is wrong with an object containing a simple integer? If you want to capture a month and day, why not capture a month enumeration and an integer day? Maybe even store them internally in a date object so you get proper bounds checking (e.g. February 31 makes no sense). Expose a different interface, however.

Why would you want to compare a date to a year to see if they are the same, greater, or lesser? It makes no sense: there is not sufficient information to make that comparison. However, there are other comparisons that might make sense (this is pseudocode):

Year y = Year(2015)
Date d = Date(2015, 01, 01)
assert y.contains(d) == True


问:
Big O equivalence for LINQ select
I'm trying to determine if there is a change in the Big O equivalence of a nested loop when I use a LINQ select instead.

```<code>public void myFunc(List<Foo> fooList, List<Bar> barList)
{
    foreach(Foo foo in fooList)
    {
        foreach(Bar bar in barList)
        {
            if(foo.PropA == bar.PropA && bar.PropZ.HasValue)
                foo.PropC = foo.PropB * bar.PropZ;
        }
    }
}
</code>```

I believe this nested loop example is O(n^2) for complexity.

I replaced the nested loop with a LINQ select like this:

```<code>public void myFunc(List<Foo> fooList, List<Bar> barList)
{
    foreach(Foo foo in fooList)
    {
        Bar bar = (from b in barList
                    where foo.PropA == b.PropA
                    select b).FirstOrDefault();

        if(bar.PropZ.HasValue)
            foo.PropC = foo.PropB * bar.PropZ;
    }
}
</code>```

If nothing else, the code appears to be a little cleaner to read as it explicitly states "we're looking for this particular Bar to work with."

My question is this: Does using the LINQ select reduce the Big O complexity?

答:
Big O is the same, since both codes will (in the worst case) have to perform a comparison for each combination of items from both lists. For example, if there are no matches between the lists, no optimization in the Linq implementation will avoid having to check all items.

But hey, you don't really want to know about big-O, do you? You want to know if the second one is faster. The answer is yes, the linq-based solution is faster (as long a n is big enough) because it only have to perform the check until the first match in the list is found, while the nested-for solution always have to visit all items. The Where method doesn't scan the whole list immediately but rater creates a lazy iterator. The FirstOrDefault method then executes the iterator until the first match is found, which means that in the common case it doesn't have to traverse the whole list. Of course there is some overhead in the Linq solution, so if n is low enough the nested-for loop will be faster.

You can check out the source yourself:
https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/Enumerable.cs

(But if you added a break in the first sample, the two codes would be semantically equivalent, and the first one would be faster due to less overhead.)

Title: Big O equivalence for LINQ select


问:
What's the idea behind naming classes with "Info" suffix, for example: "SomeClass" and "SomeClassInfo"?
I'm working in a project which deals with physical devices, and I've been confused as how to properly name some classes in this project.

Considering the actual devices (sensors and receivers) are one thing, and their representation in software is another, I am thinking about naming some classes with the "Info" suffix name pattern.

For example, while a Sensor would be a class to represent the actual sensor (when it is actually connected to some working device), SensorInfo would be used to represent only the characteristics of such sensor. For example, upon file save, I would serialize a SensorInfo to the file header, instead of serializing a Sensor, which sort of wouldn't even make sense.

But now I am confused, because there is a middleground on objects' lifecycle where I cannot decide if I should use one or another, or how to get one from another, or even whether both variants should actually be collapsed to only one class.

Also, the all too common example Employee class obviously is just a representation of the real person, but nobody would suggest to name the class EmployeeInfo instead, as far as I know.

The language I am working with is .NET, and this naming pattern seems to be common throughout the framework, for exemple with these classes:

Directory and DirectoryInfo classes;

File and FileInfo classes;

ConnectionInfoclass (with no correspondent Connection class);

DeviceInfo class (with no correspondent Device class);

So my question is: is there a common rationale about using this naming pattern? Are there cases where it makes sense to have pairs of names (Thing and ThingInfo) and other cases where there should only exist the ThingInfo class, or the Thing class, without its counterpart?

答:
So far nobody in this question seems to have picked up on the real reason for this naming convention.

A DirectoryInfo is not the directory. It is a DTO with data about the directory. There can be many such instances describing the same directory. It is not an entity. It is a throw-away value object. A DirectoryInfo does not represent the actual directory. You can also think of it as a handle or controller for a directory.

Contrast that with a class named Employee. This might be an ORM entity object and it is the single object describing that employee. If it was a value-object without identity it should be called EmployeeInfo. An Employee does indeed represent the actual employee. A value-like DTO class called EmployeeInfo would clearly not represent the employee but rather describe it or store data about it.

There's actually an example in the BCL where both classes exist: A ServiceController is a class that describes a Windows Service. There can be any number of such controllers for each service. A ServiceBase (or a derived class) is the actual service and it does not conceptually make sense to have multiple instances of it per distinct service.


问:
Java partial enum backed by the database
I have following problem:

need to use enum in my java code, since I'll have to ask in my business logic things like if(someting == enumname.VALUE_ENUM){... but I don't have all the enum types at the compile time - that is I have them but there is too many enum types that I won't use in my business logic except in cases where I need to loop over all of the enum values for(enumname var : enumname.value()){...

This seems more like the real entity then (since in DB it has an Id and a lot more properties), but it looks ugly to type if(something == object.getByString("VALUE_ENUM"))

Is there some more pedant way of doing it?

答:
found solution here if anybody needs it...

http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically

and this is the one with compile-time solution:

https://bojanv55.wordpress.com/2015/05/25/java-dynamic-enums/


答:
TL;DR

Modeling for behavior is good.

Modeling for good(!) abstractions is better.

Sometimes data objects are required.

Behavior and Abstraction

There are several reasons to avoid getters and setters. One is, as you noted, to avoid modeling data. This is actually the minor reason. The bigger reason is to provide abstraction.

In your example with the bank account that is clear: A setBalance() method would be really bad because setting a balance is not what an account should be used for. The behavior of the account should abstract from its current balance as much as possible. It may take the balance into account when deciding whether to fail a withdrawal, it may give access to the current balance, but modifying interaction with a bank account should not require the user to calculate the new balance. That's what the account should do itself.

Even a pair of deposit() and withdraw() methods is not ideal to model a bank account. A better way would be to provide only one transfer() method that takes another account and an amount as arguments. This would allow the account class to trivially ensure that you don't accidentally create/destroy money in your system, it would provide a very usable abstraction, and it would actually provide users with more insight because it would force the use of special accounts for earned/invested/lost money (see double-accounting). Of course, not every use of an account needs this level of abstraction, but it is definitely worth considering how much abstraction your classes can provide.

Note that providing abstraction and hiding data internals is not always the same thing. Almost any application contains classes that are effectively just data. Tuples, dictionaries, and arrays are frequent examples. You don't want to hide the x-coordinate of a point from the user. There is very little abstraction that you can/should be doing with a point.

The Customer Class

A customer is certainly an entity in your system that should try to provide useful abstractions. For instance, it should likely be associated with a shopping cart, and the combination of the cart and the customer should allow committing a purchase, which might kick off actions like sending him the requested products, charging him money (taking into account his selected payment method), etc.

The catch is, that all the data that you mentioned is not only associated with a customer, all of that data is also mutable. The customer may move. They may change their credit card company. They may change their email-address and phone number. Heck, they may even change their name and/or sex! So, a full featured customer class indeed has to provide full modifying access to all these data items.

Still, the setters can/should provide non-trivial services: They can ensure correct format of email-adresses, verification of postal adresses, etc. Likewise, the "getters" can provide high-level services like providing email-adresses in the Name <user@server.com> format using the name fields and the deposited email address, or provide a correctly formatted postal address, etc. Of course, what of this high level functionality makes sense depends heavily on your use-case. It might be complete overkill, or it might call for another class to do it right. The choice of abstraction level is not an easy one.

Title: How do you avoid getters and setters?


问:
Memcache queries run on a cron job?
I have several queries that leverage storing data in memcached.  Does it makes and is it against best practices to run a cron job to run these queries say every 15 minutes to keep the cache updated?  Currently our cache expires every 30 minutes, and refreshes if someone comes to visit a page that executes the query and stores it in cache. Was wondering what others thought about this approach.</p>

答:
Well, using a timed service to warm a cache is typically what applications do when they need to not be stale beyond N units of time. So this is good.

However I would like to warn you against a strict N minute routine especially if there are some queries that are bound to take longer than N minutes in any scenario. What would happen here is that you would overwhelm the system (cron processes) and the DB with requests when the prior ones haven't returned. I would suggest considering something like N units of time since the last attempt. Of course you will need to see if that fits your requirements but this way you will never have a case where 2 cron jobs or 2 threads trying to run the same query to warm the same cache. And as the system slows down the chances are there will be more processes trying to do the same thing at the same point in wasteful CPU and Memory cycles.

On a less important note I would also suggest you try and integrate the jobs in your application instead of the cron job - but this is a matter of personal taste and if you are confident the cron job deployment in every new environment won't me missed or messed up.

Title: Memcache queries run on a cron job?


答:
Trying to expand on Kasper's answer, it's easiest to rant against and eliminate setters.  In a rather vague, handwaving (and hopefully humorous) argument:

When would Customer.Name ever change?

Seldom.  Maybe they got married.  Or went into witness protection.  But in that case you'd also want to check on and possibly change their residence, next of kin, and other information.

When would DOB ever change?

Only on initial creation, or on a data entry screwup.  Or if they are a Domincan baseball player.  :-)

These fields should not be accessible with routine, normal setters.  Maybe you have a Customer.initialEntry() method, or a Customer.screwedUpHaveToChange() method that requires special permissions.  But don't have a public Customer.setDOB() method.

Usually a Customer is read from a database, a REST API, some XML, whatever.  Have a method Customer.readFromDB(), or, if you are stricter about SRP / separation of concerns, you'd have a separate builder, e.g. a CustomerPersister object with a read() method.  Internally, they somehow set the fields (I prefer using package access or an inner class, YMMV).  But again, avoid public setters.

(Addendum as Question has changed somewhat...)

Let's say that your application makes heavy use of relational databases.  It would be foolish to have Customer.saveToMYSQL() or Customer.readFromMYSQL() methods.  That creates undesireable coupling to a concrete, non-standard, and likely to change entity.  For example, when you change the schema, or change to Postgress or Oracle.

However, IMO, it's perfectly acceptable to couple Customer to an abstract standard, ResultSet.  A separate helper object (I'll call it CustomerDBHelper, which is probably a subclass of AbstractMySQLHelper) knows about all the complex connections to your DB, knows the tricky optimization details, knows the tables, query, joins, etc...  (or uses a ORM like Hibernate) to generate the ResultSet.  Your object talks to the ResultSet, which is an abstract standard, unlikely to change.  When you change the underlying database, or change the schema, Customer doesn't change, but the CustomerDBHelper does.  If you are lucky, it's only AbstractMySQLHelper that changeswhich automatically makes the changes for Customer, Merchant, Shipping etc...

This way you can (perhaps) avoid or lessen the need for getters and setters.

And, the main point of the Holub article, compare and contrast the above to how it would be if you used getters and setters for everything and changed the database.

Similarly, let's say you use a lot of XML.  IMO, it's fine to couple your Customer to an abstract standard, such as a Python xml.etree.ElementTree or a Java org.w3c.dom.Element.  Customer gets and sets itself from that.  Again, you can (perhaps) lessen the need for getters and setters.

Title: How do you avoid getters and setters?


问:
Does syntax really matter in a programming language?
One of my professors says "the syntax is the UI of a programming language", languages like Ruby have great readability and it's growing, but we see a lot of programmers productive with C\C++, so as programmers does it really matter that the syntax should be acceptable?

I would love to know your opinion on that.

Disclaimer: I'm not trying to start an argument. I thought this is a good topic of discussion.

Update: This turns out to be a good topic. I'm glad you are all participating in it.

答:
Here is a program that computes the faculty of 6:

```<code>S(K(S(S(SI(KK))(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)
(S(KS)(S(K(SI))K))))(KK)KK))))))(S(K(S(S(K(SI))(SII)(S(K(SI))(SII))
(S(K(S(S(KS)(S(KK)(S(SI(KK))(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)KK)))))))
(S(K(S(S(KS)(S(K(SI(KK)))(SI(K(KI)))))))(S(K(S(K(S(S(K(SI))(SII)(S(K(SI))
(SII))(S(K(S(S(KS)(SI(KK)))))(S(S(KS)(S(K(S(KS)))(S(K(S(KK)))(S(S(KS)K)
(K(SI(K(KI))))))))(K(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)))))))))))
(S(S(KS)K)(K(SI(K(KI)))))))))))(S(S(KS)K)(K(SI(K(KI))))))(S(S(KS)(S(KK)(S(KS)
(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)
(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)
(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)
(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)KK)))))))
</code>```

The syntax is minimal:

```<code>expression: expression term | term
term: ‘(‘ expression ‘)‘ | combinator
combinator: 'S' | 'K' | 'I'
</code>```

There seems to be a common belief that syntax is what makes a language difficult. As so often with commonly held believes, exactly the opposite is true.

Note that LISP syntax is only readable (if at all) because it has a lot more syntax than the above. So, if LISP fans tells you that "syntax doesn't matter", ask them to be consequent and try SKI calculus. They will have to admit that a bit syntax is not so bad after all.

Body:
Here is a program that computes the faculty of 6:

S(K(S(S(SI(KK))(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)
(S(KS)(S(K(SI))K))))(KK)KK))))))(S(K(S(S(K(SI))(SII)(S(K(SI))(SII))
(S(K(S(S(KS)(S(KK)(S(SI(KK))(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)KK)))))))
(S(K(S(S(KS)(S(K(SI(KK)))(SI(K(KI)))))))(S(K(S(K(S(S(K(SI))(SII)(S(K(SI))
(SII))(S(K(S(S(KS)(SI(KK)))))(S(S(KS)(S(K(S(KS)))(S(K(S(KK)))(S(S(KS)K)
(K(SI(K(KI))))))))(K(K(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)))))))))))
(S(S(KS)K)(K(SI(K(KI)))))))))))(S(S(KS)K)(K(SI(K(KI))))))(S(S(KS)(S(KK)(S(KS)
(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)
(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)
(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)(KI)
(S(S(KS)(S(KK)(S(KS)(S(K(SI))K))))(KK)KK)))))))

The syntax is minimal:

expression: expression term | term
term: ‘(‘ expression ‘)‘ | combinator
combinator: 'S' | 'K' | 'I'

There seems to be a common belief that syntax is what makes a language difficult. As so often with commonly held believes, exactly the opposite is true.

Note that LISP syntax is only readable (if at all) because it has a lot more syntax than the above. So, if LISP fans tells you that "syntax doesn't matter", ask them to be consequent and try SKI calculus. They will have to admit that a bit syntax is not so bad after all.


问:
Can you learn functional programming in C?
As a result of the comment discussion here, I wonder whether you can learn Functional Programming in C? </p>

答:
TL;DR

Functional programming is about closures and their applications. Unless someone is able to show you a descent closure library for C, forget about using C to learn functional programming.

What is functional programming?

The cardinal concept of functional programming is the notion of closures which roughly speaking, captures a function together with variables bindings.  Besides
the pervasive use of closures, there a few other distinctive traits in functional programming, like the use of recursive functions and immutable values (both play well together).  These traits are more a cultural issue than anything else, and there is no technical obstruction to use them in virtually any language, this is why I focus on closures in my answer: not every language allow to easily create closures.

Three illustrations of closures usefulness

A typical use of closures is the implementation of privacy mechanisms. For instance the Javascript code – in the examples I picked Javascript because it is a functional language with a so-called “C-like syntax” and your question suggests that you are familiar with C:

```<code>create_counter = function()
{
  var x = 0;
  var counter = function()
  {
    ++x;
    return x;
  };
  return counter;
}
</code>```

Then with

```<code>a = create_counter();
b = create_counter();
</code>```

we have two functions a and b counting disjoint collections.  The point of the example is that the variables x is captured by the closure defining the counter closure and each time a new counter closureis instantiated by the function, it gets its fresh own idea of whatx` is.

Another typical use of closures is the definition of partial applications of functions.  Assume that that we have a reporting facility similar to syslog implementing a function

```<code>var log = function(priority, message) {
…
};
</code>```

where the arguments priority and message are expected to be strings, the first one being one of "debug", "info", and so on.  We can define a log factory like this:

```<code>var logWithPriority = function(priority) {
  return function(message) {
    log(priority, message);
  };
};
</code>```

and use it to define specialised versions of our log facility:

```<code>var debug = logWithPriority("debug");
var info = logWithPriority("info");
…
</code>```

This is very useful, because instead of writing error-prone for-loops like this

```<code>for(i = 0; i < journal.length; ++i) {
   log("info", journal[i]);
}
</code>```

we can write the cleaner, shorter and much simpler (there is no i, that's much better):

```<code>journal.forEach(logWithPriority("info"));
</code>```

A third important application field of closures is the implementation of lazy evaluation – note that special language support can provide for a better implementation.

A lazy function, instead of performing a straight computation, returns a closure which can be called (or “forced” in the jargon of laziness) to perform the question. The motivation for doing this is that it separates preparing a computation and performing a computation.  A practical example of this is regular expression compilation: if a program compiles a lot of regular expressions at startup-time, it will need a lot of time to start. If instead we lazily compile the regular expressions and force them as we need them, then our program can quickly start.  Of course, regular-expressions can be substituted here with any structure requiring considerable initialisation time.

Here is how to implement lazy evaluation with closures.  Consider the classical implementation of the arrayMax function returning the max in an array:

```<code>function arrayMax(array) {
  return array.reduce(function(a, b) {
    return Math.min(a, b);
  };
}
</code>```

The lazy variant would be:

```<code>function arrayMax(array) {
  var memo = null;
  function actuallyCompute() {
    if(memo === null) {
      memo = array.reduce(function(a, b) {
        return Math.min(a, b);
      });
    }
    return memo;
  }
  return actuallyCompute;
}
</code>```

The returned value is a closure which can be used to compute the value or retrieve it another time if it has been already computed.

With these three examples, we should be confident that closures and their applications are the core of functional programming.

Conclusion

Learning functional programming means learning how to program with closures. As a consequence, languages allowing the easy manipulation of closures, and especially the partial application of functions, should be regarded when looking for a language to study functional programming.  Conversely, languages where closures cannot be easily manipulated would be poor choices.

Body:
TL;DR

Functional programming is about closures and their applications. Unless someone is able to show you a descent closure library for C, forget about using C to learn functional programming.

What is functional programming?

The cardinal concept of functional programming is the notion of closures which roughly speaking, captures a function together with variables bindings.  Besides
the pervasive use of closures, there a few other distinctive traits in functional programming, like the use of recursive functions and immutable values (both play well together).  These traits are more a cultural issue than anything else, and there is no technical obstruction to use them in virtually any language, this is why I focus on closures in my answer: not every language allow to easily create closures.

Three illustrations of closures usefulness

A typical use of closures is the implementation of privacy mechanisms. For instance the Javascript code – in the examples I picked Javascript because it is a functional language with a so-called “C-like syntax” and your question suggests that you are familiar with C:

create_counter = function()
{
  var x = 0;
  var counter = function()
  {
    ++x;
    return x;
  };
  return counter;
}

Then with

a = create_counter();
b = create_counter();

we have two functions a and b counting disjoint collections.  The point of the example is that the variables x is captured by the closure defining the counter closure and each time a new counter closureis instantiated by the function, it gets its fresh own idea of whatx` is.

Another typical use of closures is the definition of partial applications of functions.  Assume that that we have a reporting facility similar to syslog implementing a function

var log = function(priority, message) {
…
};

where the arguments priority and message are expected to be strings, the first one being one of "debug", "info", and so on.  We can define a log factory like this:

var logWithPriority = function(priority) {
  return function(message) {
    log(priority, message);
  };
};

and use it to define specialised versions of our log facility:

var debug = logWithPriority("debug");
var info = logWithPriority("info");
…

This is very useful, because instead of writing error-prone for-loops like this

for(i = 0; i < journal.length; ++i) {
   log("info", journal[i]);
}

we can write the cleaner, shorter and much simpler (there is no i, that's much better):

journal.forEach(logWithPriority("info"));

A third important application field of closures is the implementation of lazy evaluation – note that special language support can provide for a better implementation.

A lazy function, instead of performing a straight computation, returns a closure which can be called (or “forced” in the jargon of laziness) to perform the question. The motivation for doing this is that it separates preparing a computation and performing a computation.  A practical example of this is regular expression compilation: if a program compiles a lot of regular expressions at startup-time, it will need a lot of time to start. If instead we lazily compile the regular expressions and force them as we need them, then our program can quickly start.  Of course, regular-expressions can be substituted here with any structure requiring considerable initialisation time.

Here is how to implement lazy evaluation with closures.  Consider the classical implementation of the arrayMax function returning the max in an array:

function arrayMax(array) {
  return array.reduce(function(a, b) {
    return Math.min(a, b);
  };
}

The lazy variant would be:

function arrayMax(array) {
  var memo = null;
  function actuallyCompute() {
    if(memo === null) {
      memo = array.reduce(function(a, b) {
        return Math.min(a, b);
      });
    }
    return memo;
  }
  return actuallyCompute;
}

The returned value is a closure which can be used to compute the value or retrieve it another time if it has been already computed.

With these three examples, we should be confident that closures and their applications are the core of functional programming.

Conclusion

Learning functional programming means learning how to program with closures. As a consequence, languages allowing the easy manipulation of closures, and especially the partial application of functions, should be regarded when looking for a language to study functional programming.  Conversely, languages where closures cannot be easily manipulated would be poor choices.


问:
Looking for the name of an algorithm (or technique)
I am searching for an article on the net which I can't find anymore. It was describing an algorithm to rank web pages. I am trying to remember the name of this algorithm or technique.

The principle was the following:

Each page is given a credit of 10 at the beginning.

Each page is assigned a weight/probability by dividing its credit by the sum of
all credits assigned to all pages.

A subset of pages is selected randomly using to their weight/probability.

This subset is displayed to users.

Each time a user clicks on a page, its
credit is increased by one. So preferred pages get more credit.

Operation 2. was repeated to update weights/probabilities.

Thanks

答:
I guess this is what you are looking for because the article says

PageRank is a link analysis algorithm and it assigns a numerical weighting to each element of a hyperlinked set of documents, such as the World Wide Web, with the purpose of "measuring" its relative importance within the set. The algorithm may be applied to any collection of entities with reciprocal quotations and references. The numerical weight that it assigns to any given element E is referred to as the PageRank of E and denoted by PR(E). Other factors like Author Rank can contribute to the importance of an entity.


问:
REST API Structure to request multiple items
I have a REST API that looks something like the below where a person can belong to an organisation (but doesn't have to) and a person has many items. The items may also belong to the organisation instead of the person.

```<code>/people/:personId
/people/:personId/items
/organisations/:orgId/items
/organisations/:orgId/people/:personId/items
</code>```

There is a scenario where we want to query the items for multiple people within an organisation, what's the correct URL structure to use?

Option 1

```<code>/organisations/:orgId/people/items?personId=1&personId=2
</code>```

Option 2

```<code>/organisations/:orgId/items?personId=1&personId=2
</code>```

Option 3

```<code>/items?personId=1&personId=2
</code>```

答:
I would possibly do something similar to how Microsoft deals with choosing pages to print. An example of this is:

To show user 3

```<code>...?show=3
</code>```

To show all users from 10-50

```<code>...?show=10-50
</code>```

To show user 1 to 3 and 5 and 10 to 20

```<code>...?show=1-3,5,10-20
</code>```

It gives complete freedom and can be developed quite easily.

For completeness, I've deviced a simple example in Javascript:

```<code>var input = "3,4,5,10-20,55".split(',');
var complete = [];

for (var x = 0; x < items.length; x++) {
  var item = input[x];
  if (item.contains("-")) {
    var range = item.split("-");
    for (var i = range[0]; i <= range[1]; i++) {
      complete.push(i);
    }
  } else {
    complete.push(item);
  }
}

console.log(complete); //["3", "4", "5", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "55"]
</code>```

Body:
I would possibly do something similar to how Microsoft deals with choosing pages to print. An example of this is:

To show user 3

...?show=3

To show all users from 10-50

...?show=10-50

To show user 1 to 3 and 5 and 10 to 20

...?show=1-3,5,10-20

It gives complete freedom and can be developed quite easily.

For completeness, I've deviced a simple example in Javascript:

var input = "3,4,5,10-20,55".split(',');
var complete = [];

for (var x = 0; x < items.length; x++) {
  var item = input[x];
  if (item.contains("-")) {
    var range = item.split("-");
    for (var i = range[0]; i <= range[1]; i++) {
      complete.push(i);
    }
  } else {
    complete.push(item);
  }
}

console.log(complete); //["3", "4", "5", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "55"]


问:
PHP MVC how to access current user?
What is the best way to tell if a user is already logged in when accessing the page? I have seen many people talk about a Recognition service that will validate a user trying to login, but what about checking if they're already logged in? Assuming I'm storing the user's state in the session, how do I check for this? My application also requires a whitelist. On top of that, I need to redirect the user to a 403 page if they aren't in the whitelist, as opposed to the login page, or whatever page they requested if they are logged in.

My main roadblocks are:

Where to implement whitelist logic? Router, domain object?

Check if user is logged in? Controller?

How to get current user's role if they are logged in for my ACL? Do I call the Recognition service in my index.php and have my Recognition service return the user or their role and pass that along to the acl for the controller to use?

Note: I'm not really fond of the Controller Decorator because if the user can't access the method in the controller, how and where is that handled?

答:
Using PHP you would access the current user SessionToken cookie stored when you authenticated the user to check if:

There is one present

It has not passed its expiry

It is the current token for that user stored in a session database

I would implement this by writing the code in a separate file/module and include it into each page of your project or main controller. Run the appropriate logic on checking these details.

All users need to be stored somewhere, the ideal location is on a database of some kind which will store if they can be logged in (whitelisted/blacklisted), their details and their sessionID.

Title: PHP MVC how to access current user?


问:
Handling my antiquated coworker
I'm a fairly young programmer, and I work at a medium sized company's IT department. I have a coworker, and he is a really good Visual Basic 6 programmer. And I mean really good. Honestly. He can deliver working applications, containing very few bugs, in the time I need to get my first cup of coffee, and boot my machine. He is just that good.

Thing is, we are working with a team, and his working style is completely antiquated. He doesn't believe in versioning software (if you just make sure your code is correct, you don't need all that nonsense). Doesn't believe in deployment (I can deliver a working executable. How that is deployed is for the sysadmins to figure out). Doesn't believe in abstraction. ('if you want to create a subroutine, go ahead, but don't call any subroutines from that subroutine. It gets messy that way, and the code is hard to follow. This way every one can follow every step on the way.' or 'yeah, sure you can use that library to do that for you, but that way you don't really understand what's going on') and certainly doesn't believe in OOP. (we work in VB.net)

He is so good in what he does, he can deliver applications way faster than I can. But it just doesn't work in a team. Our other team member is quiet, and doesn't like to speak out, though he tends to agree. Our manager thinks I make valid points, but is not a programmer.

I have a really hard time maintaining programs he has written, and it doesn't make for a good team atmosphere. What do you think is the best thing for me to do?

答:
I've seen this before,

And I'm almost willing to bet: This type of guy only appears "fast" because he has a set of tried and tested "patterns" in his head. 99% of Line of Business apps is CRUD, basic stuff.

He probably uses a ton of Copy & Paste from his own existing code (nothing wrong with that).

But..

The moment he encounters anything remotely complex, it falls down, why? because it no longer fits any of the basic "patterns".

A little challenge...

I'd create a project on the side, a complex one that really benefits from OOP and code re-use.

Then show him that project and ask him to implement it feature for feature.

I'd then wager that his code will almost certainly be 10x times larger & 10x uglier if he had implemented it his way.

Title: Handling my antiquated coworker