问:
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?

答:
I would actually... not go for both, but I'll pick yours over your co-worker for your simplified example.

First things first, I tend to favor inlining values instead of doing one-off assignments. This improves code readability for me as I do not have to break my train of thought into multiple assignment statements, then read the line(s) of code where they are used. Therefore, I will prefer your approach over your co-worker, with the slight nitpick that testConstructorWithLeadingAndTrailingWhitespaceInName() can probably be just:

```<code>assertThat(new Foo(" " + VALID_NAME + " ").getName(), is(equalTo(VALID_NAME)));
</code>```

That brings me to the naming. Usually, if your test is asserting an Exception to be thrown, your test name should describe that behavior too for clarity. Using the example above, so what if I have extra whitespaces in the name when I construct my Foo object? And how is that related to throwing an IllegalArgumentException?

Based on the null and "" tests, I am presuming here that the same Exception is thrown this time for calling getName(). If that's indeed the case, maybe setting the test method's name as callingGetNameWithWhitespacePaddingThrows() (IllegalArgumentException - which I think will be part of JUnit's output, hence optional) will be better. If having whitespace padding in the name during instantiation will also throw the same Exception, then I'll skip the assertion entirely too, to make it clear that it's in the constructor's behavior.

However, I think there's a better way of doing things here when you get to more permutations for valid and invalid inputs, namely parameterized testing. What you are testing is exactly that: You are creating a bunch of Foo objects with different constructor arguments, and then asserting it either fails at the instantiation or calling getName(). Therefore, why not let JUnit perform the iteration and scaffolding for you? You can, in layman terms, tell JUnit, "these are the values I want to create a Foo object with", and then have your test method assert for IllegalArgumentException in the right places. Unfortunately, since JUnit's way of parameterized testing doesn't work well with testing for both successful and exceptional cases in the same test (as far as I'm aware of), you'll probably need to jump through a bit of a hoop with the following structure:

```<code>@RunWith(Parameterized.class)
public class FooUnitTests {

    private static final String VALID_NAME = "ABC";

    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
                 { VALID_NAME, false },
                 { "", true },
                 { null, true },
                 { " " + VALID_NAME + " ", true }
           });
    }

    private String input;

    private boolean throwException;

    public FooUnitTests(String input, boolean throwException) {
        this.input = input;
        this.throwException = throwException;
    }

    @Test
    public void test() {
        try {
            Foo test = new Foo(input);
            // TODO any testing required for VALID_NAME?
            if (throwException) {
                assertEquals(VALID_NAME, test.getName());
            }
        } catch (IllegalArgumentException e) {
            if (!throwException) {
                throw new RuntimeException(e);
            }
        }
    }
}
</code>```

Admittedly, this looks clunky for what is an otherwise simple four-value testing, and it isn't helped much by JUnit's somewhat restrictive implementation. In this regard, I find TestNG's @DataProvider approach to be more useful, and it's definitely worth a closer look if you are considering parameterized tests.

Here's how one might be able to use TestNG for your unit tests (using Java 8's Stream to simplify the Iterator construction). Some of the benefits are, but not limited to:

Test parameters become method arguments, not class fields.

You can have multiple @DataProviders providing different kinds of inputs.

It is arguably clearer and easier to add new valid/invalid inputs for testing.

It still looks a bit overblown for your simplified example, but IMHO it's neater than JUnit's approach.

```<code>public class FooUnitTests {

    private static final String VALID_NAME = "ABC";

    @DataProvider(name="successes")
    public static Iterator<Object[]> getSuccessCases() {
        return Stream.of(VALID_NAME).map(v -> new Object[]{ v }).iterator();
    }

    @DataProvider(name="exceptions")
    public static Iterator<Object[]> getExceptionCases() {
        return Stream.of("", null, " " + VALID_NAME + " ")
                    .map(v -> new Object[]{ v }).iterator();
    }

    @Test(dataProvider="successes")
    public void testSuccesses(String input) {
        new Foo(input);
        // TODO any further testing required?
    }

    @Test(dataProvider="exceptions", expectedExceptions=IllegalArgumentException.class)
    public void testExceptions(String input) {
        Foo test = new Foo(input);
        if (input.contains(VALID_NAME)) {
            // TestNG favors assert(actual, expected).
            assertEquals(test.getName(), VALID_NAME);
        }
    }
}
</code>```

Body:
I would actually... not go for both, but I'll pick yours over your co-worker for your simplified example.

First things first, I tend to favor inlining values instead of doing one-off assignments. This improves code readability for me as I do not have to break my train of thought into multiple assignment statements, then read the line(s) of code where they are used. Therefore, I will prefer your approach over your co-worker, with the slight nitpick that testConstructorWithLeadingAndTrailingWhitespaceInName() can probably be just:

assertThat(new Foo(" " + VALID_NAME + " ").getName(), is(equalTo(VALID_NAME)));

That brings me to the naming. Usually, if your test is asserting an Exception to be thrown, your test name should describe that behavior too for clarity. Using the example above, so what if I have extra whitespaces in the name when I construct my Foo object? And how is that related to throwing an IllegalArgumentException?

Based on the null and "" tests, I am presuming here that the same Exception is thrown this time for calling getName(). If that's indeed the case, maybe setting the test method's name as callingGetNameWithWhitespacePaddingThrows() (IllegalArgumentException - which I think will be part of JUnit's output, hence optional) will be better. If having whitespace padding in the name during instantiation will also throw the same Exception, then I'll skip the assertion entirely too, to make it clear that it's in the constructor's behavior.

However, I think there's a better way of doing things here when you get to more permutations for valid and invalid inputs, namely parameterized testing. What you are testing is exactly that: You are creating a bunch of Foo objects with different constructor arguments, and then asserting it either fails at the instantiation or calling getName(). Therefore, why not let JUnit perform the iteration and scaffolding for you? You can, in layman terms, tell JUnit, "these are the values I want to create a Foo object with", and then have your test method assert for IllegalArgumentException in the right places. Unfortunately, since JUnit's way of parameterized testing doesn't work well with testing for both successful and exceptional cases in the same test (as far as I'm aware of), you'll probably need to jump through a bit of a hoop with the following structure:

@RunWith(Parameterized.class)
public class FooUnitTests {

    private static final String VALID_NAME = "ABC";

    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
                 { VALID_NAME, false },
                 { "", true },
                 { null, true },
                 { " " + VALID_NAME + " ", true }
           });
    }

    private String input;

    private boolean throwException;

    public FooUnitTests(String input, boolean throwException) {
        this.input = input;
        this.throwException = throwException;
    }

    @Test
    public void test() {
        try {
            Foo test = new Foo(input);
            // TODO any testing required for VALID_NAME?
            if (throwException) {
                assertEquals(VALID_NAME, test.getName());
            }
        } catch (IllegalArgumentException e) {
            if (!throwException) {
                throw new RuntimeException(e);
            }
        }
    }
}

Admittedly, this looks clunky for what is an otherwise simple four-value testing, and it isn't helped much by JUnit's somewhat restrictive implementation. In this regard, I find TestNG's @DataProvider approach to be more useful, and it's definitely worth a closer look if you are considering parameterized tests.

Here's how one might be able to use TestNG for your unit tests (using Java 8's Stream to simplify the Iterator construction). Some of the benefits are, but not limited to:

Test parameters become method arguments, not class fields.

You can have multiple @DataProviders providing different kinds of inputs.

It is arguably clearer and easier to add new valid/invalid inputs for testing.

It still looks a bit overblown for your simplified example, but IMHO it's neater than JUnit's approach.

public class FooUnitTests {

    private static final String VALID_NAME = "ABC";

    @DataProvider(name="successes")
    public static Iterator<Object[]> getSuccessCases() {
        return Stream.of(VALID_NAME).map(v -> new Object[]{ v }).iterator();
    }

    @DataProvider(name="exceptions")
    public static Iterator<Object[]> getExceptionCases() {
        return Stream.of("", null, " " + VALID_NAME + " ")
                    .map(v -> new Object[]{ v }).iterator();
    }

    @Test(dataProvider="successes")
    public void testSuccesses(String input) {
        new Foo(input);
        // TODO any further testing required?
    }

    @Test(dataProvider="exceptions", expectedExceptions=IllegalArgumentException.class)
    public void testExceptions(String input) {
        Foo test = new Foo(input);
        if (input.contains(VALID_NAME)) {
            // TestNG favors assert(actual, expected).
            assertEquals(test.getName(), VALID_NAME);
        }
    }
}


问:
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

答:
You seem to be asking for two different things here:

changing the values of some fields

  Are you referring to how you need to normalize values' formattings ("yyyy-MM-dd" to "ddMMyy") or possibly even data types here (BigDecimal to int)? If so, I'll suggest creating a conversion class to handles these, so that you can safely eliminate both the conversion and API pollutions within your class.

making changes such that the new file complies to older schema

  Wells, serialization libraries and how they handle schema resolution came to my mind immediately, such as how Apache Avro does it... If you can consider your objects/data files (hmms a bit of a stretch though for the latter) to be handled as a form of serialization, then these libraries are definitely worth a look here, because the problem is most likely solved for you. For the full low-down on schema resolution comparisons, this article is a great, if slightly overwhelming, read too.

edit Given the risk of link rot, I'll just quote the relevant parts of the article here...

Then you find that people are stuffing all sorts of random fields into their objects, using inconsistent types, and you’d quite like a schema and some documentation... hey, if you had a schema, you could avoid storing objects’ field names, and you could save some more bytes!

Once you get to the fourth stage, your options are typically Thrift, Protocol Buffers or Avro. All three provide efficient, cross-language serialization of data using a schema, and code generation for the Java folks.

In real life, data is always in flux. The moment you think you have finalised a schema, someone will come up with a use case that wasn’t anticipated, and wants to “just quickly add a field”. Fortunately Thrift, Protobuf and Avro all support schema evolution: you can change the schema, you can have producers and consumers with different versions of the schema at the same time, and it all continues to work. That is an extremely valuable feature when you’re dealing with a big production system, because it allows you to update different components of the system independently, at different times, without worrying about compatibility.

ContentLicense: CC BY-SA 3.0


问:
Library OSes vs Unikernels
My understanding of a Hypervisor & Virtual Machines is that the hypervisor is a program (either running on top of a host OS, or running bare metal as the host) that leverages binary-compatible device drivers and a slew of other technologies to provide hardware emulation in the form of isolated "virtual" guest machines, all sharing the host's hardware and peripherals.

My understanding of Linux Containers is that the Linux kernel contains a native hypervisor that allows for this same type of functionality, but for some reason, is much more lightweight than traditional type I/II hypervisors and their VMs. My understanding is that Docker improves upon raw Linux container even more so, though I'm not sure exactly how.

My understanding of Library OSes is that they are bits and pieces of the many Linux libraries and packages out there, effectively allowing you to stitch together your own "Frankenstein" Linux distro from a minimized set of libraries specific to your app.

My understanding of Unikernel is that it is essentially the same thing as a Library OS, but are even (somehow?) more stipped down and minified.

My understanding of an immutable server is that its a server that is configured once at buildtime, and never changes its configuration or internal state after it starts running.

So first, if anything I have asserted so far is incorrect or misled, please begin by correcting me! Assuming I'm more or less on track with these:

What is the exact difference between Library OSes and Unikernels?

For that matter, what's the difference between both of these an "embedded" or "micro" versions of Linux (such as ArchLinux), designed for embedded systems? Aren't they all just "minified Linux"?

Which of these is used to create an immutable server?

答:
The intuition behind unikernels as possible with OpenMirage (a.k.a. MirageOS) is that you code a specialized "kernel" like program (running nearly on the bare metal, but actually) for some hypervisor like Xen which would run several dozens of such unikernels.

Notice that OpenMirage unikernels share very little code (AFAIK, none) with Linux kernel (since they are mostly coded in Ocaml, not in C!); for example their TCP stack is different.

Library OS is nearly a buzzword not meaning much. Read e.g. about the exokernel idea. The OSkit project (dead since 2003, probably) packaged Linux kernel subsystems and drivers to provide people with some libraries to make kernel like software.

Some specialized variants of Linux distributions enable you to use a bare linux kernel with very few specific utilities (but then you are using a common Linux kernel, perhaps with your own init-like program, or just with very few specialized programs started by some usual init or systemd thing). Many embedded Linux (including Android) are used this way, e.g. OpenWRT, but the user-land software is doing ordinary Linux syscalls listed in syscalls(2).

docker is a software container (i.e. some kind of operating system level virtualization or sandbox). See also Chroot, and the chroot(2) & personality(2) & setns(2) syscalls.

Read also about (Linux-specific) credentials(7), capabilities(7), namespaces(7)

Title: Library OSes vs Unikernels


问:
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?

答:
OOP is about encapsulating and hidding behavior inside objects. Objects are black boxes. This is a way to design thing. The asset is in many case one doesn't need to know the internal state of another component and is better to not have to know it. You can enforce that idea with mainly interfaces or inside an object with visibility and taking care only allowed verbs/action are available to caller.

This work well for some kind of problem. For example in user interfaces to modelize individual UI component. When you interract with a text box you are only interrested in setting the text, getting it or listening to text change event. You are typically not interrested as to where the cursor is, the font used to draw the text or how the keyboard is used. Encapsulation provide a lot here.

On the contrary when you call a network service, your provide an explicit input. There usually a grammar (like in JSON or XML) and all the option of calling the service have no reason to be hidden. The idea is that you can call the service the way you want and the data format is public and published.

In this case, or many other (like access to a database) you really work with shared data. As such there no reason to hide it, on the contrary you want to make it available. There can be concern of read/write access or datacheck consistency but at this core, the core concept if this is public.

For such design requirement where you want to avoid encapsulation and make things publics and in the clear, you want to avoid objects. What you really need are tuples, C structs or their equivalent, not objects.

But it also happen in languages like Java, the only things you can modelize is objects or arrays of objects. Objects themselve can hold a few natives types (int, float...) but that's all. But objects can also behave like a simple struct with just public fields and that all.

So if you modelize data you can be done with just public fields inside objects because you don't need more. You don't use encapsulation because you don't need it. This is done this way in many languages. In java, historically, a standard rose where with getter/setter you could at least have read/write control (by not adding setter for example) and that toolings and framework by using instrospection API would look for getter/setter methods and use it to autofill the content or display theses as modifiable fields in auto generated user interface.

There also the argument you could add some logic/checking in the setter method.

In reality there almost no justification for getter/setters as they are most often used to modelize pure data. Frameworks and developpers using your objects do expect the getter/setter do nothing more than setting/getting the fields anyway. You are effectively doing no more with getter/setter than what could be done with public fields.

But that's old habits and olds habits are difficult to remove... You could even be threatened by your collegues or teacher if you don't put getters/setter blindly everywhere if they lack the background to better understand what they are and what they are not.

You would likely need to change the language to get ride of all theses getters/setters boilerplate code. (Like C# or lisp). To me getters/setter are just another one billion dollar mistake...

Title: How do you avoid getters and setters?


问:
Python: Are all dictionary comprehensions just more expressive and compact for loops?
Recently, to describe dictionary comprehensions in Python, I wrote:

dictionary comprehension is just a more compact & expressive way of
  writing the same logic as for loops (performance may differ).

Is this a correct characterization of Python's dictionary comprehension?

Is it possible to give an objective(-ish) definition of the term expressive used to describe computer code?

Does it make sense to use expressive and compact together to describe code? What are some other examples?

答:
To me, "expressive" means that you can express a large diversity of concepts with it.

In many programming languages, a foreach loop (iterating over a container) is less "expressive" than a for loop. Because you can always trivially rewrite the former in terms of the latter, but not vice versa.

Analogously, I would say that dictionary comprehensions are not more expressive than looping constructs, but less so.


问:
.NET Why should I use DAL over direct database access
Yesterday on one of SO chats I've been told I should never connect to database directly from the application and rather use DAL.

I've been told that:
1. Using something in the middle should improve the performance of app-db communication (which I hardly believe, since there's an overhead coming from additional layer between them)
2. It is more secure (in what terms?)
3. It gives better scalability
4. It allows cross-platform client application (not applicable, since it's written in C# and is only for Windows)

The biggest problem with current application is that 40-50 clients connected to database make it slows down massively.

So, my question is: how DAL can actually improve the performance(my main concern) of my system (in terms of server resource usage and client applications speed)?

答:
Whether you use a DAL or not your application is still going to directly interact with the database.

It is generally just good practice to structure your code in such a way that things like data access is in a centralised "place" in your codebase.

I also generally abstract any data access to a set of methods defined on an interface.

If and when you decide to change your database you don't have to scoure you entire codebase for all the data access code in order to update it all.

Also by using an interface approch to abstract away the DAL code you can more easily write unit tests for the code that consumes the DAL output.

It's just good design to work this way.


答:
You should use a DAL, but not for the reasons stated :)
You performance problem will probably not be fixed by introducing a layer of indirection (even if it might be desirable for other reasons). You should look into what actually causes the performance problem. Some common problems:

The n+1 antipattern which causes far to many database queries. E.g. if you fetch a list of 100 items from the database, this should require one query, but if you by mistake make an individual query for each item, you suddenly get 100+ queries, which will kill database performance. You can detect what queries are actually executes via the database profiler.

Clients hold onto db connections too long, which causes the connection pool to be depleted. Eg. an open SqlConnection is stored in a field rather then closed immediately after use.

The .net framework already include a low-level DAL (classes like System.Data.SqlClient.SqlConnection if you use a SqlServer) which among other things handles connection pooling. This is pretty important for performance, and there is no reason not to use these classes to access the database.

I would guess you already use this layer, and you friend is taking about an additional layer of indirection between the .net data access library and the application logic - perhaps an ORM like the Entity Framework or NHibernate, or a hand rolled equivalent.

This will not help you with performance, security or scalability. It might make the application simpler and more maintainable, but will not solve your immediate problems.

Edit: OK you are talking about a web service layer. And you have desktop app clients connecting to a central database over a local network. So you are talking about turning a two-tier application into a three-tier application. This is not going to help you with performance problems. Rather it will just make it worse due to the overhead of an additional layer. Introducing a middleware layer might have other advantages though. For example you insulate the clients from the database which may improve security. But if you are going in that direction you might consider using a wep application instead, which have the same advantages, and is much easier to deploy and instrument than desktop apps.

Title: .NET Why should I use DAL over direct database access

Body:
Yesterday on one of SO chats I've been told I should never connect to database directly from the application and rather use DAL.

I've been told that:
1. Using something in the middle should improve the performance of app-db communication (which I hardly believe, since there's an overhead coming from additional layer between them)
2. It is more secure (in what terms?)
3. It gives better scalability
4. It allows cross-platform client application (not applicable, since it's written in C# and is only for Windows)

The biggest problem with current application is that 40-50 clients connected to database make it slows down massively.

So, my question is: how DAL can actually improve the performance(my main concern) of my system (in terms of server resource usage and client applications speed)?


问:
Is there a viable alternative to the agile development methodology?
The two predominant software-development methodologies are waterfall and agile.  When discussing these two, there is often much focus on the particular practices that distinguish them (pair programming, TDD, etc. vs. functional spec, big up-front design, etc.)

But the real differences are far deeper, in that these practices come from a philosophy.

Waterfall says:  Change is costly, so it should be minimized.

Agile says:  Change is inevitable, so make change cheap.

My question is, regardless of what you think of TDD or functional specs, is the waterfall development methodology really viable?

Does anyone really think that minimizing change in software is a viable option for those that desire to deliver valuable software?  Or is the question really about what sort of practices work best in our situations to manage the inevitable change?

答:
You begin by saying:

The two predominant
  software-development philosophies are
  waterfall and agile.

This is false. This dichotomy has been constructed by the agile community in order to create an opponent against which to position themselves. Before agile was in vogue, people used to speak about a myriad of different approaches to building software. They still exist today, but somehow they are often lumped together into a big mess called "waterfall" by agile proponents.

I have been using OPEN/Metis and its variants for over 10 years with great success. It is definitely not agile, and definitely not waterfall. Thousands of developers create extremely complex software for aircraft, life critical systems, banking, etc. using non-agile methods every day.

So yes, of course there is a viable alternative to agile.


问:
How do I communicate to a colleague that their code does nothing?
Stay with me here. When I say the code "does nothing", I mean something like the following function:

void factorial(int n)
{
    int result = 1;
    for(int i = 1; i <= n; ++i)
    {
        result *= i;
    }
}
```

Sure, this function creates a local variable and computes a value, but it doesn't do anything to advance the program; there is no way to make use of the result of the computation, and it has no side-effects.

Keep in mind that this is a contrived example for the purposes of the question, but the code I refer to may be more complicated.

When I encounter such code, I often spend some extra time and go through it several times, because I worry that I might be missing something. I could just take the high road, or fix the bug and be done with it, but I worry that this slowdown would reflect badly on me and my performance.

So, should I take the high road, and assume the team understands, or should I communicate that the code doesn't do much? If the latter is the better option, how do I do that without being condescending or disrespectful?

答: If nothing exits or is referenced outside of the scope of the system that the code represents, it has no use. You just have to draw a line around the entire system and challenge the obstinate dev to point out where it's actually crossed.</p>


问:
MVC with Post/Redirect/Get
I have a question in mind for the MVC pattern for a long time now. When using the Post/Redirect/Get principle then it doesn't make sense to use ONE model in the sense of MVC, right? Why should I modify the data in the model if I don't use it anymore? Am I missing something?

So I need one model for the actions in the controller and one with the data for the view?

My current pattern:

controller

-> call and init model used for actions

-> handle actions using the action model, if an action has been executed, use P/R/G to reload

-> call and init model used for the view

-> call view with template and pass view model

The point is, I don't want to load all the data for the view if I possibly don't need it due to the redirect. Or am I just caring about that too much?

答:
In MVC it's very uncommon to have a single model or controller. It is however common to have one or very few view "flavors" which all render templates differently.

Each controller should have a single purpose, whether it's routing, or applying business logic to a model. You should route the request to the appropriate controller for each model, ideally separating POST and GET handling into separate functions. If POST, save and redirect. If GET, display the view.

Model = Structured data. Throws validation exceptions. May contain storage logic.

Controller = Routing and business logic. Works on models directly or through another controller. Assigns presentation data to views, such as models, headers, sub-views, etc. Dies gracefully upon errors.

View = Presentation. Uses whatever it's given in a read-only way. Should produce no errors.

If you're asking whether it's correct to initialize the model for each type of request, the answer is probably yes, unless your POST validation is incredibly simple and is allowed to clobber existing records.

Title: MVC with Post/Redirect/Get


答:
The purpose of all code is ultimately to affect the world outside the program in some way. Nobody cares about the content of memory cells or CPU registers; they only care about the printed page or the information displayed on a screen. If code doesn't input/output anything, and doesnt change the state of the program in any way that could eventually cause any I/O, it is by definition superfluous.

But how to see this? The easiest way is to have unit testing. This code cannot satisfy any test that check for actual factorial values to be computed, since the only value that is computed never makes it outside the function. Simply write up a test case that codifes what the code should be doing, and it becomes trivial to demonstrate that it doesn't. (Admittedly this isn't the primary reason why people usually advocate test-driven development, but it works really well for this purpose, too.)

Title: How do I communicate to a colleague that their code does nothing?

Body:
Stay with me here. When I say the code "does nothing", I mean something like the following function:

void factorial(int n)
{
    int result = 1;
    for(int i = 1; i <= n; ++i)
    {
        result *= i;
    }
}
```

Sure, this function creates a local variable and computes a value, but it doesn't do anything to advance the program; there is no way to make use of the result of the computation, and it has no side-effects.

Keep in mind that this is a contrived example for the purposes of the question, but the code I refer to may be more complicated.

When I encounter such code, I often spend some extra time and go through it several times, because I worry that I might be missing something. I could just take the high road, or fix the bug and be done with it, but I worry that this slowdown would reflect badly on me and my performance.

So, should I take the high road, and assume the team understands, or should I communicate that the code doesn't do much? If the latter is the better option, how do I do that without being condescending or disrespectful?


问:
Does sun.misc.Unsafe give access to the system or just the JVM?
Please note: Although this question involves microcontrollers, it is at its core, a Java question, and so I believe it can be answered by any battle-weary Java guru.

I stumbled accross this blog talking about sun.misc.Unsafe and was trying to understand its full capabilities to see if it was appropriate for a hobby project of mine.

At the 30,000 foot view, I am trying to program an ARM chip (Arduino Due - an ARM SAM3X8E MCU) to drive some IO peripherals (flash some LEDs, drive servos, etc.) on a simple electronics device. For good sport, I would love to do this in pure Java if at all possible. Up until reading that article, I didn't even think this was possible, and figured I'd have to do most if not all the programming in C. Because this flavor of ARM can support Linux, especially a stripped down "unikernel-style" of Linux, I'd like to write my controller program entirely in Java, and deploy it to a location (say /opt/myapp) on a Linux image that I can then flash to the ARM chip. With a little tinkering/hacking, I should be able to get the ARM chip to run the Java app when the device powers up.

My question

To drive my device's IO peripherals, I need to access specific memory addresses that will exist outside the JVM process running my app. Up until now I was under the impression that JVMs "sandbox" their resident apps, disallowing them to access anything in system memory directly. And so my plan was to write a bunch of C code (which actually drives the peripherals, flashes LEDs, etc.) and then have my app invoke that C code through JNI.

But if I'm reading that blog correctly, it seems that sun.misc.Unsafe gives me acess to system memory outside of the JVM. If this is true, then technically I don't need any C code. Of course, I am committing all sorts of security no-no's, making my code non-portable, etc. But that's fine: this is just a hobby project running on a specific platform that I don't intend to change.

So I ask: am I understanding Unsafe correctly, and if so, are there any other caveats/restrictions/limitations I should be considering while using it?

答:
sun.misc.Unsafe isn't part of the Java standard. Thus, your very first task will be determining whether the Java implementation you will be running on the ARM chip supports it.

If the answer to the above is yes, you have to ask yourself whether the I/O addresses you need to access are mapped within the JVM process. Unsafe lets you escape the usual Java memory model, but it doesn't have any facility to escape the JVM process's address space. It would not be unusual for hardware I/O addresses to only be writable from kernel address space, but your platform may be different.

Assuming you have the I/O addresses mapped in the JVM process, then the last hurdle is checking whether all the protocols you plan to use are slow enough or flexible enough with time that you can drive them from a Java process, which may be subject to stop-the-world garbage collection and other factors that make it not-even-remotely-real-time.

If all that checks out, it sounds like an interesting project.

Oh wait, you also have to figure out a way to fit Linux and a JVM in 512KB of flash memory ... and run them in 100KB of RAM. It sounds like you would need to upgrade to a significantly more powerful chip to carry out this concept, probably one with a DRAM controller to be able to attach sensible amounts of RAM.


答:
If you want to program a cheap (32 bits) ARM chip in Java (which is probably not a good idea) and if you accept to code against an old version of the Java programming language, you might consider using gcj, the Java ahead-of-time compiler inside some versions of GCC.

(Beware, Java support in GCC seems phased out in 2015, or at least is becoming less important to the GCC community)

However, you may want to use some other language. If garbage collection is significant to you, you could use D, or Go, or even perhaps use (perhaps by porting it to the bare metal) the Boehm conservative garbage collector in C (or even in C++, see this) - which is used by gcj. You could also consider coding in Ocaml, see MirageOS. And Rust is not garbage collected but might be useful on a small ARM chip.

Read also wikipage on real-time Java

Title: Does sun.misc.Unsafe give access to the system or just the JVM?

Body:
Please note: Although this question involves microcontrollers, it is at its core, a Java question, and so I believe it can be answered by any battle-weary Java guru.

I stumbled accross this blog talking about sun.misc.Unsafe and was trying to understand its full capabilities to see if it was appropriate for a hobby project of mine.

At the 30,000 foot view, I am trying to program an ARM chip (Arduino Due - an ARM SAM3X8E MCU) to drive some IO peripherals (flash some LEDs, drive servos, etc.) on a simple electronics device. For good sport, I would love to do this in pure Java if at all possible. Up until reading that article, I didn't even think this was possible, and figured I'd have to do most if not all the programming in C. Because this flavor of ARM can support Linux, especially a stripped down "unikernel-style" of Linux, I'd like to write my controller program entirely in Java, and deploy it to a location (say /opt/myapp) on a Linux image that I can then flash to the ARM chip. With a little tinkering/hacking, I should be able to get the ARM chip to run the Java app when the device powers up.

My question

To drive my device's IO peripherals, I need to access specific memory addresses that will exist outside the JVM process running my app. Up until now I was under the impression that JVMs "sandbox" their resident apps, disallowing them to access anything in system memory directly. And so my plan was to write a bunch of C code (which actually drives the peripherals, flashes LEDs, etc.) and then have my app invoke that C code through JNI.

But if I'm reading that blog correctly, it seems that sun.misc.Unsafe gives me acess to system memory outside of the JVM. If this is true, then technically I don't need any C code. Of course, I am committing all sorts of security no-no's, making my code non-portable, etc. But that's fine: this is just a hobby project running on a specific platform that I don't intend to change.

So I ask: am I understanding Unsafe correctly, and if so, are there any other caveats/restrictions/limitations I should be considering while using it?


答:
The easiest way is to ask from a point of not understanding and ask their opinion. It's no good to say "your code sucks", it's quite another to say "erm, I saw this and I really can't understand what it's doing, or why it's doing it. What do you think?" or similar - you could say what your concern is and ask them to explain it to you, or ask them just if you are right.

This way, you bring them into being part of the solution and typically will realize the problem and fix it themselves (or you can offer to do it for them).

I'm sure you've written code like that yourself, you just don't see it until someone points it out and you have a d'oh moment. Treat such code not as a huge, glaring error but as just another slight cock up that we all make now and then and you'll be good.


答: Ask the dev to walk you through the code in code-review session, and ask what his thought process was around it. See if he recognises the superfluous behaviour. If he doesn't, ask him specifically about it. Maybe a bit more roundabout, but not as confrontational.</p>


答:
IMO expressiveness is a trait of the language/framework/library as a whole - not of a single feature/function in it. Some operations can be better expressed with for loops, some with dictionary comprehensions - so I wouldn't say that one is more expressive than the other, but that Python as a whole is more expressive for having both.

Compactness is something that can be used to describe a single feature, but I wouldn't say that dictionary comprehensions are always more compact than for loops. For example, I'd argue that

```<code>for i in range(10):
    print(i)
</code>```

is more compact than

```<code>def foo(x):
    print(x)

{i: foo(i) for i in range(10)}
</code>```

Of course, this is a very obvious abuse of dictionary comprehensions, but there can also be less obvious abuses. The point is that list/dictionary comprehensions targets a more specific use cases than for loops, and they can be more compact only in these cases.

If you are looking for the right terminology, I'd say that:

dictionary comprehension is just a more functional way of writing the same logic as for loops (performance may differ).

Title: Python: Are all dictionary comprehensions just more expressive and compact for loops?

Body:
Recently, to describe dictionary comprehensions in Python, I wrote:

dictionary comprehension is just a more compact & expressive way of
  writing the same logic as for loops (performance may differ).

Is this a correct characterization of Python's dictionary comprehension?

Is it possible to give an objective(-ish) definition of the term expressive used to describe computer code?

Does it make sense to use expressive and compact together to describe code? What are some other examples?

Body:
IMO expressiveness is a trait of the language/framework/library as a whole - not of a single feature/function in it. Some operations can be better expressed with for loops, some with dictionary comprehensions - so I wouldn't say that one is more expressive than the other, but that Python as a whole is more expressive for having both.

Compactness is something that can be used to describe a single feature, but I wouldn't say that dictionary comprehensions are always more compact than for loops. For example, I'd argue that

for i in range(10):
    print(i)

is more compact than

def foo(x):
    print(x)

{i: foo(i) for i in range(10)}

Of course, this is a very obvious abuse of dictionary comprehensions, but there can also be less obvious abuses. The point is that list/dictionary comprehensions targets a more specific use cases than for loops, and they can be more compact only in these cases.

If you are looking for the right terminology, I'd say that:

dictionary comprehension is just a more functional way of writing the same logic as for loops (performance may differ).


问:
Access Database Migration: Sharepoint or Custom solution
In order to migrate a local Access database and make it available on-line I'm considering  two solutions:

Migrate the database to SQL and build a custom ASP application in order to add/edit/delete data;

Create a Web Access Database and host it on SharePoint.

Requisites:

Support multiple users at the same time;

Must be available outside the office environment;

Current state of the Access app:

Working with need of custom changes when data needs to be imported from plain files. The data files have changed along the time and the app didn't(CSV files)

Users are familiarized with the current database "interface"

Problems that I anticipate:

After the database is on-line and available, the client needs will change and he will require more functions and features;

Access limitations.

In order to have an app that can be easily modified in the future, what is the best solution?

All thing consider, in terms of costs what option can become cheaper in a long time period of time?

答:
We don't know all of your requirements and resources, so I can't possibly say what is best here. However, there are some things to consider.

Resources

Do you have the knowledge to build this as an Asp application? Does your staff know enough to build and support it?

If you don't have any professional devs on staff to support this, Access may be the way to go.

Do you have access (no pun intended) to the technology you'll need to build and support it. By this I mean a good IDE, the ability to choose the libraries and testing frameworks you want to work with, etc.

We have a rather large Access "database" application where I'm at just because no one was willing to pay for a couple of copies of visual studio. We use a SQL Server as a back end and only use Access as a front end. It works rather well, surprisingly.

Extensibility and Maintainability

There is no VBA for an Access Web Database. You'll be limited to using Macros for everything. This limits what you'll be able to do. Customization will be hampered and limited.

This means you'll also need to translate that ~1300 lines of VBA into macros. This is most likely possible to do, and reasonable for the amount of code you say you have.

It is hard to maintain Access databases built this way. Everything turns into a jumbled mess of queries and macros. Documentation is possible, if you're smart, but certainly not as easy as commenting some code.

Been there, done that. Maintenance will be a nightmare past some critical mass. If you picture this app growing beyond anything trivial, don't build it in Access. It sounds like this application will grow, so if you do go with Access, I'll bet my hat someone ends up porting it later anyway.

You can unit test your ASP project. The same won't be possible for a web database. The ASP way would be much more maintainable and resistant to change and breakage over time.

Performance

Access is slooooowwwwww. Unbearably slow for some things. How critical is performance for your application? If it's expected to be highly responsive and fast, go with ASP.

Even if performance isn't considered to be critical, you need to take it into consideration when calculating your return on investment.

Time and Budget

It's likely that you could port your existing Access app to a Web Database very quickly and with minimal effort. If short on time and cash right now, a web database could be the right option. It will give you the most bang for your buck in the short term.

However, if you have the time and money to start from scratch and build it in ASP, then go ahead and do it. Play the long game and it will save you in the long run. It will take you more up front to get this done, but will pay its dividends down the road as features are added and old functionality changed.


问:
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

答:
It is a variation of Multi-armed bandit problem:

In probability theory, the multi-armed bandit problem (sometimes called the K- or N-armed bandit problem) is a problem in which a gambler at a row of slot machines (sometimes known as "one-armed bandits") has to decide which machines to play, how many times to play each machine and in which order to play them. When played, each machine provides a random reward from a distribution specific to that machine. The objective of the gambler is to maximize the sum of rewards earned through a sequence of lever pulls.

There are multiple ways to solve this problem, here is one:

Each page is given two values:

number of times it was shown, initially 1

number of times it was clicked, initially 1

The fitness of a page is clicked/shown. I use a term from genetic programming here, maybe there is more appropriate term in probability theory.

Fitness proportionate selection is used to choose one page. To choose more than one, you can exclude the previously selected one from a set and repeat selection.

Each time a page is displayed, its' shown value is increased by one. If it was also clicked, than clicked is also increased by one, otherwise it's left unchanged.

Goto 2

However, it is tricky to decide when you should stop the experiment. You might want to look at Google Analytics docs on A/B-testing for details.


问:
Should curly braces appear on their own line?
Should curly braces be on their own line or not? What do you think about it?

```<code>if (you.hasAnswer()) {
    you.postAnswer();
} else {
    you.doSomething();
}
</code>```

or should it be

```<code>if (you.hasAnswer())
{
    you.postAnswer();
}
else
{
    you.doSomething();
}
</code>```

or even

```<code>if (you.hasAnswer())
    you.postAnswer();
else
    you.doSomething();
</code>```

Please be constructive! Explain why, share experiences, back it up with facts and references.

答:
I personally like the second way.

However, the way I'm going to demonstrate is in my opinion best because it results in greatest job security! A fellow student from my university asked me for help with his homework and this is how his code looked like. Whole program looked like one single block. The interesting thing is that 95% of the bugs in the program he made came from mismatched braces. The other 5% were obvious once the braces were matched.

```<code>while(1){
i=0;
printf("Enter coded text:\n");
while((s=getchar())!='\n'){
         if(i%1==0){
            start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!");
exit(1);}
input=start;}
      input[i++]=s;}
start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!!!");
exit(1);}
input=start;
input[i]='\0';
                puts(input);
</code>```

Body:
I personally like the second way.

However, the way I'm going to demonstrate is in my opinion best because it results in greatest job security! A fellow student from my university asked me for help with his homework and this is how his code looked like. Whole program looked like one single block. The interesting thing is that 95% of the bugs in the program he made came from mismatched braces. The other 5% were obvious once the braces were matched.

while(1){
i=0;
printf("Enter coded text:\n");
while((s=getchar())!='\n'){
         if(i%1==0){
            start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!");
exit(1);}
input=start;}
      input[i++]=s;}
start=(char*)realloc(input,(i+1)*sizeof(char));
if(start==NULL){
printf("Memory allocation failed!!!");
exit(1);}
input=start;
input[i]='\0';
                puts(input);

ContentLicense: CC BY-SA 2.5


问:
SPARC and Assembly
I'm currently self teaching myself programming and became familiar with Python, Java and C and I'm confused as to what are the differences between Assembly and SPARC Assembly and whether or not I should learning Assembly first then SPARC.</p>

答:
Assembler languages are processor (or CPU) specific. Each processor has its own assembler language (which maps to a different machine language). So SPARC processors use SPARC assembler, x86-64 processors use x86-64 assembler, etc.

For a few processors, including x86-64 used in most laptops & desktops in 2015, you might have two different syntaxes so two flavors of assembly language (so called Intel vs ATT) which are translated to the same machine code.

(BTW, x86-64 understands both 32 bits ia32 and 64 bits amd64 machine code and assembler, as if the chip had a mixture of two processors; it actually has several modes: the old 16 bit one -from 8086-, the 32 bit one -from i386-, the amd64 one, etc...).

Read wikipage about instruction sets (which is what your processor understands, and what its assembler is emitting in object files with relocation information, e.g. for the linker) Notice that x86 means a family of instruction sets (with a common base), because of extensions like SSE3, AVX, etc.

The SPARC and MIPS instruction sets are probably easier to understand than x86. You might even look into MMIX (an hypothetical instruction set for teaching purposes) or Open RISC V (a free specification instruction set).

It is a bit more complex, since many instructions sets have both 32 bits and 64 bits variants.

Title: SPARC and Assembly


问:
Where should my team start with becoming "modern"?
I'm a relatively new developer, fresh from college. While in college and during subsequent job-seeking, I realized that there were a lot of "modern" software development methodologies that my education was lacking: unit testing, logging, database normalization, agile development (vs. generic agile concepts), coding style guides, refactoring, code reviews,  no standardized documentation methods (or even requirements), etc.

Overall, I didn't see this is a problem. I expected my first job to embrace all of these ideas and to teach them to me on the job. Then I got my first job (full stack web development) at a big corporation and I realized that we do none of these things. In fact I, the least experienced on the team, am the one who is spearheading attempts to bring my team up to speed with "modern" programming techniques - as I worry that not doing so is professional suicide down the road.

First I began with logging software (log4J), but then I quickly moved on to writing my own styleguide, then abandoning it for the Google styleguide - and then I realized that our Java web development used hand-written front controllers, so I pushed for our adoption of Spring - but then I realized we had no unit tests, either, but I was already learning Spring... and as you can see, it becomes overwhelming all too quickly, especially when paired with normal development work. Furthermore, it is difficult for me to become "expert" enough in these methodologies to teach anyone else in them without devoting too much time to a single one of them, let alone them all.

Of all these techniques, which I see as "expected" in today's software development world, how do I integrate them into a team as a new player without overwhelming both myself and the team?

How can I influence my team to become more agile? is related, but I'm not an Agile developer like the asker here, and I'm looking at a much broader set of methodologies than Agile.

答:
It sounds to me like you are putting the cart before the horse.

What is the major problem your team is facing and which technologies would help fix it?

For example, if there are lots of bugs, particularly regression-type bugs, then unit testing may be a starting point. If your team is lacking time, perhaps a framework may help (medium to long term). If people have difficulty reading each others' code, styling may be useful.

Remember that the purpose of the business you work for is to make money, not to make code.


答:
Java?  Modern?!  You've failed at the first hurdle. If you want to be truly modern and avoid "professional suicide" then you must be writing Rust code. Of course, next week, it'll all change and you'll have to learn something even newer to keep up!

Or, you could accept that no amount of buzzword technologies or methodologies or frameworks or any other du jour will change the fact that you want to build quality products that work. It doesn't matter if you don't use agile if you are successfully producing the right output. Of course, if you're not, then you might want to change things but chances are no particular practice will fix the problems.  They will remain human problems that can be fixed in any number of different ways.

As for professional suicide, if you know what you're doing and are flexible then you don't need any of the things you mentioned. People will continue to come up with new ways of doing the old work and you'll always be catching up.  Or you can simply use whatever techniques your current company uses regardless. When you change your company, you simply learn and use the techniques they use.

Too many kids get hung up on all the new tools they could use, forgetting that these tools are worthless in the hands of a novice. Learn the practice first, once you're an experienced developer you can start to "fix" the development practices with "cool new things", but by then you will hopefully have realised that they are not nearly as important as you currently think, and only to be used when they are really needed.

Title: Where should my team start with becoming "modern"?

Body:
I'm a relatively new developer, fresh from college. While in college and during subsequent job-seeking, I realized that there were a lot of "modern" software development methodologies that my education was lacking: unit testing, logging, database normalization, agile development (vs. generic agile concepts), coding style guides, refactoring, code reviews,  no standardized documentation methods (or even requirements), etc.

Overall, I didn't see this is a problem. I expected my first job to embrace all of these ideas and to teach them to me on the job. Then I got my first job (full stack web development) at a big corporation and I realized that we do none of these things. In fact I, the least experienced on the team, am the one who is spearheading attempts to bring my team up to speed with "modern" programming techniques - as I worry that not doing so is professional suicide down the road.

First I began with logging software (log4J), but then I quickly moved on to writing my own styleguide, then abandoning it for the Google styleguide - and then I realized that our Java web development used hand-written front controllers, so I pushed for our adoption of Spring - but then I realized we had no unit tests, either, but I was already learning Spring... and as you can see, it becomes overwhelming all too quickly, especially when paired with normal development work. Furthermore, it is difficult for me to become "expert" enough in these methodologies to teach anyone else in them without devoting too much time to a single one of them, let alone them all.

Of all these techniques, which I see as "expected" in today's software development world, how do I integrate them into a team as a new player without overwhelming both myself and the team?

How can I influence my team to become more agile? is related, but I'm not an Agile developer like the asker here, and I'm looking at a much broader set of methodologies than Agile.


问:
Do Temporary tables have any form of index in SQL?
Consider a simple query like this:

```<code>SELECT * FROM DATA
JOIN
(
SELECT * FROM DATA
)TEMPORARY_DATA
ON TEMPORARY_DATA.DATA_IDN = DATA.DATA_IDN
</code>```

What is the performance of this? Is it O(n2) because TEMPORARY_DATA doesn't have indexes as opposed to normal tables. Normal joins I think happens in O(nlogn) time because it is indexed right?

Does this change if the inner query is slightly complex and so direct? I mean is it possible the optimized it not able to guess that it is not the indexed DATA table!

I am newbie to these things, please let me know if this belongs to some other place on the SO Network.

答:
(The following answer uses SQL Server RDBMS to explain)

First off, there are no temporary tables in your question.  Temporary tables (in SQL Server) are actual tables that live in tempdb, and are defined with one or two pound signs (#) preceding it.  What you have is a simple alias (temporary_data).  Two extremely different things.

That is an extremely long and verbose way of writing a join on a table to itself.  Take this table structure:

```<code>create table dbo.Data
(
    Id int not null
);
go
</code>```

I will insert a few rows:

```<code>insert into dbo.Data
values (1), (2), (3);
go
</code>```

The result set of:

```<code>select *
from dbo.Data
join
(
    select *
    from dbo.Data
) temporary_data
on temporary_data.Id = Data.Id;
</code>```

Is...

```<code>Id  Id
1   1
2   2
3   3
</code>```

Looking at the post execution plan of this operation, SQL Server just does a join on these two tables:

Logically this is the exact same query (results and execution plan) as the following:

```<code>select *
from dbo.Data d1
inner join dbo.Data d2
on d1.Id = d2.Id;
</code>```

It is just an extremely long way to write it.  Nothing is gained by the former, and the only thing lost is readability.

Body:
(The following answer uses SQL Server RDBMS to explain)

First off, there are no temporary tables in your question.  Temporary tables (in SQL Server) are actual tables that live in tempdb, and are defined with one or two pound signs (#) preceding it.  What you have is a simple alias (temporary_data).  Two extremely different things.

That is an extremely long and verbose way of writing a join on a table to itself.  Take this table structure:

create table dbo.Data
(
    Id int not null
);
go

I will insert a few rows:

insert into dbo.Data
values (1), (2), (3);
go

The result set of:

select *
from dbo.Data
join
(
    select *
    from dbo.Data
) temporary_data
on temporary_data.Id = Data.Id;

Is...

Id  Id
1   1
2   2
3   3

Looking at the post execution plan of this operation, SQL Server just does a join on these two tables:

Logically this is the exact same query (results and execution plan) as the following:

select *
from dbo.Data d1
inner join dbo.Data d2
on d1.Id = d2.Id;

It is just an extremely long way to write it.  Nothing is gained by the former, and the only thing lost is readability.


答:
Many companies are stuck like this; you might even be surprised to find that some of your developer colleagues are self-taught and became developers with no formal background whatsoever. These developers are often better at their jobs, since they will be the ones that are driven to learn new skills and succeed instead of simply doing the job. Unfortunately this can also mean that, while they're excellent at programming, they might not be aware of the benefits of these practices. The fact is these are best practices, not common practices. The best use them, but they are not at all requirements to succeed, they are simply tools to help make success easier.

You're absolutely right, it's going to be overwhelming to try to implement everything all at once. You'll likely burn yourself (and maybe your team) out trying to do it, which is going to demotivate future pushes to adopt new methodologies/technologies. The best thing to do in a situation like this is pick one thing (logging is probably a good start, as you've probably got a tough road ahead finding bugs without logging, and there are sure to be bugs) and talk to the team about it. You don't have to singlehandedly implement this; you'll do much better discussing the pros and cons with the team (and your boss, who absolutely MUST be on board with something like this) and coming up with a plan to implement it. It's going to have to be as painless as possible (remember, you're telling people that they now have to write extra code in addition to what they already do).

And let me say again, make sure your boss buys in. This is crucial; you will probably find that the speed of fixes/releases slows down as you implement new things. The point is that you're paying upfront to save down the line; they MUST understand this and be on your side. If you don't get them on board, you're fighting a losing battle at best, and at worst they may consider you as actively sabotaging the team (ask me how I know).

Once you bring these items to the table, discuss them with the team, plan how to implement them, and follow through, the second, third, eighth, etc. will be easier. Not only that, there's a potential for the team and your boss to gain respect for you as your suggestions are implemented and recognized as adding value. Great! Just make sure that you stay flexible: you'r pushing against inertia here, and change isn't easy. be prepared to slowly make small changes, and make sure that you can track progress and value earned. If you implement logging in a new process and it helps you save hours finding a bug in three weeks, make a big deal about it! Make sure everyone knows that the company just saved $XXX by doing the right thing ahead of time. On the other hand, if you get pushback, or have a tight deadline, don't try forcing the issue. Let the new change slide for the moment, and circle back. You won't ever win by trying to force the team to do something they don't want to do, and you can be sure the first thing they'll suggest dropping is the new 'extra' work (like writing logging, or following a styleguide instead of just 'getting it working').


答:
I worry that this slowdown would reflect badly on me and my performance.

If improving the code you find reflects badly on you, then you have a much bigger problem in your team than exactly how you raise the issues you find! OK, if it's not broken you don't have to fix it, but for genuine redundant code it's probably a good idea to simplify by removing it. Time estimates should be based on the practical reality of understanding code as you go and fixing issues you find. If you're in crisis mode and can't do that, then the answer would be "put your head down and hope for the best", but that should be rare.

Redundant code isn't the worst problem you could find, but it indicates an error in the thinking of whoever wrote it (or modified it to become redundant). Therefore it deserves at least as much attention as any other potential refactor you discover in code you visit, and perhaps more.

should I take the high road, and assume the team understands

No. You're part of the team, you don't understand, so not everyone understands. Don't assume there's a higher mystery everyone else is privy to. Much more likely, nobody would want it to be like that it and everyone else either hasn't noticed it or hasn't got around to improving it. Or you're wrong. In the latter case you'll benefit from an explanation of your mistake, in the former case someone else will benefit from dealing with it.

should I communicate that the code doesn't do much?

Depending how your team feels about code "ownership", it might be that the correct thing to do is just to fix it and (if the change doesn't speak for itself) discuss it when your changes are reviewed. Alternatively there might be someone in the team who's the obvious person to talk to about it before going ahead with a change, either the author or someone else with particular responsibility. When you do talk to someone, be it the owner or a code reviewer, all that's left is to decide what to say.

If you're comfortable shooting straight from the hip:

"This code does nothing"

"You forgot to return the result, shall I fix it?"

"This void function has no side-effects, what's it for?"

Naturally this might be considered rude, it really depends on your relationship with the person. So you can be more diplomatic:

"What does this code do?"

"Is the result needed anywhere or can we skip this part?"

"This looks wrong, so I'm not sure I've understood everything"

"I'm terribly sorry to trouble you, but I haven't been able to understand these few lines of code. It seems to me as if this function doesn't do anything, so I was wondering why that is. Quite likely I've misunderstood it, or I suppose it might be there to support some future direction, in which case I was wondering if I could usefully add some comments to explain what".

Naturally, the last example runs a fine line between obsequiously polite and just plain condescending. Some people sound good talking like that, others sound like sarcastic gits.

Personally, I usually go with "Is this supposed to not return anything?". I'm expecting the answer "no". It's intentionally somewhat impolite/joking, because with my current colleagues I can be, but I wouldn't accuse anyone of anything beyond an oversight. And if the answer is "yes" with a reason, then fair enough. Another common option for me is "I think this should return something". Both are things that I'd be happy to have said to me.


问:
Is this breaking SOA?
We're havng a bit of a disagreement in our team, and I would like to hear other people's views. We have a mature solution that uses an Entity Framework model, which is accessed by a repository layer, which is in turn accessed by a business logic layer. The BLL classes implement interfaces, which are also implemented by services in a WCF project. The WCF services are very thin wrappers around the BLL classes, and each service call is basically a one-liner that passes the call through to the BLL. We have a WPF project that uses the WCF services for its data access.

We have recently added an ASP.NET MVC4 project to the solution, to provide web access to some of the features in the WPF project. As the web server is on the same local network as the SQL Server database and the WCF web folder, I added a reference to the BLL project from the MVC project, and did the data access directly between the MVC controllers and the BLL classes.

Our senior technical chap objected to this, and said I was breaking SOA. He wants me to add WCF service references to the MVC project, and access the data via WCF.

My argument against this is that going via WCF does not add anything of benefit to the MVC project, but hurts the performance (I know this for a fact, as I tried it). Given that the WCF services just pass the calls straight throuh to the BLL classes, which implement the same interfaces, I don't see how it is any more SOA to use WCF than to call the BLL methods directly. Furthermore, performance is critical in this MVC project, and I don't want to do anything that will impact the performance unless there is a very good reason to do so. I can't see any good reason here. Even if we optimise the WCF project, it is still always going to be slower than accessing the BLLs directly.

According to the definitions of SOA that I've seen (for example, see the Definitions section in Wikipedia's SOA article http://en.wikipedia.org/wiki/Service-oriented_architecture), our BLLs are definitely within the pattern. I don't see any requirement to use web services to call it SOA. Sure, web services are a form of SOA, but they aren't the only form. As far as I can see, a layered approach, which ours defintely is, is completely compliant with the principle of SOA. Now I realise that I may not have put his argument very strongly, but that's mainly because I can't understand it. I'm hoping that some people who are more knowledgeable than me can come along and offer some comments one way or the other. We have a meeting to discuss this tomorrow, and I;m sure he's going to pressrue me very strongly to use WCF instead of referencing the BLLs directly. If he's right, then fair enough, we'll have to suffer the performance hit. However, if there isn't any benefit to using WCF in this case, then I need to be able to explain why the way I've done it so far is fully SOA.

I would appreciate any comments.

答:
I can sympathise with your view, Ive been in a similar position with too many WCF layers all on the same box, each one passing the same call down the stack.

However! the point of SOA is that you can orchestrate your services. if you skip a layer then you have lost that flexiblity.

eg. I want any calls to logic X also trigger logic Y. I can add the extra call to the service or add extra routing to my orchestration. But if your app calls logic X directly it will skip my logic Y injection.

Just because you dont currently have logic Y dosnt mean the service has no value.

Performance: WCF is not going to be adding a significant amount of time to your web call. If it is something is wrong, and going through the service gives you caching and scaleablity options.

Title: Is this breaking SOA?


答:
Stay with me here. When I say the code "does nothing", I mean something like the following function

The correct term for this type of source code is incomplete. You could say to another programmer "Upon reviewing your source code I found a function that is incomplete. Can you clarify its intent?"

Incomplete work makes it's way into production products all the time. There are many possible reasons for this to happen.

The developer pushed these changes by mistake.

The developer needed to mock functionality until it can be finished later.

The developer was unable to finish the work, but pushed it anyway.

When I encounter such code, I often spend some extra time and go through it several times, because I worry that I might be missing something. I could just take the high road, or fix the bug and be done with it, but I worry that this slowdown would reflect badly on me and my performance.

Your self-confidence and work efficiency has nothing to do with work produced by other people. The processes, source code quality, quality assurance and management style of a business are outside your control (unless it's part of your job to change them). Try to keep those things separate from how you perceive your own performance and value.

So, should I take the high road, and assume the team understands, or should I communicate that the code doesn't do much? If the latter is the better option, how do I do that without being condescending or disrespectful?

What you're asking here has nothing to do with computer programming.

I would ask this on the https://workplace.stackexchange.com/

You will likely get answers on how to work effectively in a team.

Put 100% of your effort into your work. No one can fault you if you've tried your best. Expecting more than what you are able to do is just foolish management. Trying to work quickly just makes you fail faster.

Communicate constructively with your team members. Speak up and express yourself.

Listen to what your team members have to say.

Don't be a lone wolf. Help the team fix problems.

Openly share with your team members. Share your ideas, thoughts and concerns. Don't wait until someone asks. Make an effort to share.

Offer to help. If you find incomplete work. Offer to finish it.

Be more flexible. Rather than complain about problems. Be thoughtful of why those problems exist, and accept them. Most people stressed out on a project do so over things they can't change.

Always be respectful, supportive and honest with fellow team members. You might not get the same in return, but you'll learn the value of those traits.


问:
WPF and data in the cloud
I need to create a WPF app that users will use on one machine and the manager wishes to use at home in the evenings. I have already suggested a web app which they don't want to do so suggested hosting the data in the cloud.

I haven't used this scenario before so I wanted to take the time to see what other people would suggest on here as an alternative to my suggestion which is essentially a connection string to an external sql server source.

They don't want a web app nor do they have a network there (very small place, only 2 computers), however I am concerned about any internet issues that will effectively stop any data transactions and thus the app itself.

I am happy to hear any alternatives to data source, synchronization etc as I'm happy to take the time to learn something different if it makes the end product better.

答: If they are such a small company with only two computers, I would just suggest to start with VPN.  Use a VPN client to connect to the companies network resources then you can access the database remotely.  After the company grows or grows tired of VPN, a more appropriate solution could be designed.</p>

Title: WPF and data in the cloud


问:
Was .NET's IObserver<T> intended for subscribing to multiple IObservables?
There are IObservable and IObserver interfaces in .NET (also here and here).  Interestingly, the concrete implementation of the IObserver does not hold a direct reference to the IObservable.  It doesn't know who it's subscribed to.  It can only invoke the unsubscriber.  "Please pull the pin to unsubscribe."

edit: The unsubscriber implements the IDisposable. I think, this scheme was employed to prevent the lapsed listener problem.

Two things are not entirely clear to me, though.

Does the inner Unsubscriber class provide the subscribe-and-forget behavior?  Who (and when exactly) calls IDisposable.Dispose() on the Unsubscriber?  Garbage collector (GC) is not deterministic.

[Disclaimer:  overall, I've spent more time with C and C++ than with C# .]

What should happen if I want to subscribe an observer K to an observable L1 and the observer is already subscribed to some other observable L2?

```<code>K.Subscribe(L1);
K.Subscribe(L2);
K.Unsubscribe();
L1.PublishObservation(1003);
L2.PublishObservation(1004);
</code>```

When I ran this test code against MSDN's example, the observer remained subscribed to L1.  This would be peculiar in real development.  Potentially, there are 3 avenues to improve this:

If the observer already has an unsubscriber instance (i.e. it’s already subscribed), then it quietly unsubscribes from the original provider before subscribing to a new one.  This approach hides the fact that it’s no longer subscribed to the original provider, which may become a surprise later.

If the observer already has an unsubscriber instance, then is throws an exception.  A well-behaved calling code has to unsubscribe the observer explicitly.

Observer subscribes to multiple providers.  This is the most intriguing option, but can this be implemented with IObservable and IObserver?  Let’s see.  It is possible for the observer to keep a list of unsubscriber objects: one for each source.  Unfortunately, IObserver.OnComplete() does not provide a reference back to the provider who have sent it.  So, the IObserver implementation with multiple providers would not be able to determine which one to unsubscribe from.

Was .NET's IObserver intended for subscribing to multiple IObservables?

Does the textbook definition of the observer pattern require that one observer has to be able to subscribe to multiple providers? Or is it optional and implementation-dependent?

答:
Just to clear up a few things that are well documented in the official Rx Design Guidelines and at length on my web site IntroToRx.com:

You dont rely on the GC to clean up your subscriptions. Covered in detail here

There is no Unsubscribe method. You subscribe to an observable sequence and are given a subscription. You can then dispose of that subscription indicating that you no longer want to have your callbacks invoked.

An observable sequence can not be completed more than once (see section 4 of the Rx Design Guidelines).

There are numerous ways to consume multiple observable sequences. There is also a wealth of information regarding that on Reactivex.io and again at IntroToRx.

To be specific and answer the original question directly, your usage is back to front. You don't push many observable sequences into a single observer. You compose observable sequences into a single observable sequence. You then subscribe to that single sequence.

Instead of

```<code>K.Subscribe(L1);
K.Subscribe(L2);
K.Unsubscribe();
L1.PublishObservation(1003);
L2.PublishObservation(1004);
</code>```

Which is just pseudo code and would not work in .NET implementation of Rx, you should do the following:

```<code>var source1 = new Subject<int>(); //was L1
var source2 = new Subject<int>(); //was L2

var subscription = source1
    .Merge(source2)
    .Subscribe(value=>Console.WriteLine("OnNext({0})", value));

source1.OnNext(1003);
source2.OnNext(1004);

subscription.Dispose();
</code>```

Now this doesn't exactly fit the initial question, but I don't know what K.Unsubscribe() was supposed to do (unsubscribe from all, the last or the first subscription?!)

Body:
Just to clear up a few things that are well documented in the official Rx Design Guidelines and at length on my web site IntroToRx.com:

You dont rely on the GC to clean up your subscriptions. Covered in detail here

There is no Unsubscribe method. You subscribe to an observable sequence and are given a subscription. You can then dispose of that subscription indicating that you no longer want to have your callbacks invoked.

An observable sequence can not be completed more than once (see section 4 of the Rx Design Guidelines).

There are numerous ways to consume multiple observable sequences. There is also a wealth of information regarding that on Reactivex.io and again at IntroToRx.

To be specific and answer the original question directly, your usage is back to front. You don't push many observable sequences into a single observer. You compose observable sequences into a single observable sequence. You then subscribe to that single sequence.

Instead of

K.Subscribe(L1);
K.Subscribe(L2);
K.Unsubscribe();
L1.PublishObservation(1003);
L2.PublishObservation(1004);

Which is just pseudo code and would not work in .NET implementation of Rx, you should do the following:

var source1 = new Subject<int>(); //was L1
var source2 = new Subject<int>(); //was L2

var subscription = source1
    .Merge(source2)
    .Subscribe(value=>Console.WriteLine("OnNext({0})", value));

source1.OnNext(1003);
source2.OnNext(1004);

subscription.Dispose();

Now this doesn't exactly fit the initial question, but I don't know what K.Unsubscribe() was supposed to do (unsubscribe from all, the last or the first subscription?!)


答:
Look around the team that you're a part of. Can you see any evidence that test driven development or database normalization will improve the quality of the software you're writing or make people more productive?

Have you tried speaking to one of the development supervisors about it, or the head of development? A really informal chat would be a good start. What makes you think that the people above you haven't had the same ideas but can't / won't implement them because the business won't allow it?

I find that leading by example is a good way to go. People are a lot less resistant if someone else has already done the work and can show them how to replicate it. Introduce TDD into a project you're working on. Ask to give a presentation to the rest of the team, or even a couple of others and show them what you have done. What @DrewJordan said about getting buy in from the boss is more important than you probably realise.


答:
I would've preferred to post this as a comment alas I'm short on rep.

In my world, if I can't directly trace a piece of a code to a documented requirement or derived requirement then I flag it for a team review which occurs every two weeks or as needed.

```<code>    // REVIEW: 05/19/2015
    // Can't find the need for this code. Perhaps it's been orphaned?
    // Need to identify the requirement associated or remove it.
    public static bool WouldYouLikeToDance(this Person you, Person dancePartner)
    {
        // determine minimum acceptable attractiveness
        int minAcceptable = you.SelfWorthAndRespect - (you.CountDrinksConsumed() * 0.10);

        return (minAcceptable <= dancePartner.Attractiveness);
    }
</code>```

I find it's best not to confront them directly, just anonymously identify concerns and expect they would do the same for you. During the group review, you can weigh in with the team as a control to ensure you're not erroneously identifying something valid. The overall goal is code quality and as a side effect, improving the skill set of each developer and the team as a whole.

Body:
I would've preferred to post this as a comment alas I'm short on rep.

In my world, if I can't directly trace a piece of a code to a documented requirement or derived requirement then I flag it for a team review which occurs every two weeks or as needed.

    // REVIEW: 05/19/2015
    // Can't find the need for this code. Perhaps it's been orphaned?
    // Need to identify the requirement associated or remove it.
    public static bool WouldYouLikeToDance(this Person you, Person dancePartner)
    {
        // determine minimum acceptable attractiveness
        int minAcceptable = you.SelfWorthAndRespect - (you.CountDrinksConsumed() * 0.10);

        return (minAcceptable <= dancePartner.Attractiveness);
    }

I find it's best not to confront them directly, just anonymously identify concerns and expect they would do the same for you. During the group review, you can weigh in with the team as a control to ensure you're not erroneously identifying something valid. The overall goal is code quality and as a side effect, improving the skill set of each developer and the team as a whole.


答:
So for example, given a Customer class that keeps alot if 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?

I think this question is prickly because you are worried about behavior methods for populating data but I don't see any indication of what behavior the Customer class of objects is intended to encapsulate.

Don't confuse Customer as a class of objects with 'Customer' as a user/actor who performs different tasks using your software.

When you say given a Customer class that keeps alot if information about the customer then as far as behavior goes it looks like your Customer class has little distinguishing it from a rock. A Rock can have a color, you could give it a name, you could have a field for storing its current address but we don't expect any sort of intelligent behavior from a rock.

From the linked article about getters/setters being evil:

The OO design process centers on use cases: a user performs standalone
  tasks that have some useful outcome. (Logging on is not a use case
  because it lacks a useful outcome in the problem domain. Drawing a
  paycheck is a use case.) An OO system, then, implements the activities
  needed to play out the various scenarios that comprise a use case.

Without any behavior defined, referring to a rock as a Customer doesn't change the fact that it is just an object with some properties you'd like to track and it doesn't matter what tricks you want to play to get away from getters and setters. A rock doesn't care if it has a valid name and a rock wouldn't be expected to know whether an address is valid or not.

Your order system could associate a Rock with a purchase order and as long as that Rock has an address defined then some part of the system can make sure an item gets delivered to a rock.

In all of these cases the Rock is just a Data Object and will continue to be one until we define specific behaviors with useful outcomes instead of hypotheticals.

Try This:

When you avoid overloading the word 'Customer' with 2 potentially different meanings it should make things easier to conceptualize.

Does a Rock object place an Order or is that something that a human being does by clicking on UI elements to trigger actions in your system?

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?


答:
A dictionary comprehension is expressive in the sense that by using one, you are expressing that your intent is to create a dictionary.  You can always do the same thing in a for loop, but doing so does not express that intent.  It is something the reader has to determine by code inspection.  So consider this:

```<code>cache = {key:lookup(key) for key in keystore}
</code>```

Now compare to a version without a dictionary comprehension:

```<code>cache = {}
for key in keystore:
    cache[key] = lookup(key)
</code>```

The first version is a bit more compact.  But more importantly, it directly expresses that your intent is to create a dictionary.  In the for loop version, you have to read the code and see that this is what the result is.

The other point to consider is that a dictionary comprehension version is inherently simpler than a for loop version.  A dictionary comprehension cannot fail to produce a dictionary.   There are a number of mistakes that you could potentially make in the for loop version that cannot occur in the dictionary comprehension.

Here's an example of how a comprehension might help avoid a defect:

```<code>cache = {}
for key in keystore:
    cache[key] = lookup(key)

cache2 = {}
for key in keystore2:
    cache[key] = lookup(key)  # oops
</code>```

We decided to use a second cache, but when copy-pasting, we introduced a defect.  Now look at the dictionary comprehension version:

```<code>cache = {key:lookup(key) for key in keystore}
cache2 = {key:lookup(key) for key in keystore2}
</code>```

Because cache appears twice in the for loop version, it is possible for those two instances to become misaligned.  That is impossible with the dictionary comprehension because the target dictionary only appears once.

I know this example seems trivial, but in the real world, with more complex code (for instance, if you have an if/else clause) this problem becomes worse.

Body:
A dictionary comprehension is expressive in the sense that by using one, you are expressing that your intent is to create a dictionary.  You can always do the same thing in a for loop, but doing so does not express that intent.  It is something the reader has to determine by code inspection.  So consider this:

cache = {key:lookup(key) for key in keystore}

Now compare to a version without a dictionary comprehension:

cache = {}
for key in keystore:
    cache[key] = lookup(key)

The first version is a bit more compact.  But more importantly, it directly expresses that your intent is to create a dictionary.  In the for loop version, you have to read the code and see that this is what the result is.

The other point to consider is that a dictionary comprehension version is inherently simpler than a for loop version.  A dictionary comprehension cannot fail to produce a dictionary.   There are a number of mistakes that you could potentially make in the for loop version that cannot occur in the dictionary comprehension.

Here's an example of how a comprehension might help avoid a defect:

cache = {}
for key in keystore:
    cache[key] = lookup(key)

cache2 = {}
for key in keystore2:
    cache[key] = lookup(key)  # oops

We decided to use a second cache, but when copy-pasting, we introduced a defect.  Now look at the dictionary comprehension version:

cache = {key:lookup(key) for key in keystore}
cache2 = {key:lookup(key) for key in keystore2}

Because cache appears twice in the for loop version, it is possible for those two instances to become misaligned.  That is impossible with the dictionary comprehension because the target dictionary only appears once.

I know this example seems trivial, but in the real world, with more complex code (for instance, if you have an if/else clause) this problem becomes worse.


问:
When developing an MVC framework, how should I be using Knockout.js?
I'm currently using the Laravel PHP MVC Framework to develop a web application; and it's going along quite nicely. I'm very comfortable with the expectations of the framework and how my application should be structured. This is not a problem.

My problem is with the front end, UI/interaction side. I am using Knockout.js & jQuery to encapsulate a lot of front end UI & data interaction; and I'm not sure I'm using the former correctly.

Knockout.js prides itself on binding elements in the DOM to event handlers and functions in a Javascript "ViewModel" layer, allowing you to send requests away to the server via AJAX to fetch new data, add templates of HTML to your current DOM, and alter what is present on your page. I understand this within a single page context. By that, I mean, if I have a discrete page where I need user & data interaction, I will probably end up creating a SomeSinglePageViewModel.js file to handle this.

What I am not to sure about is how, or even whether, Knockout.js view models should be used across/between pages. Right now, I'm creating a ViewModel for nearly every CRUD operation and page in my application. Is this correct design?

For example, I'll have a CreateUserViewModel.js for my /User/Signup page, and a EditUserViewModel.js for my /User/Edit page; and a `HomePageViewModel.js for the application landing page to control that UI. Is it correct to follow a "one viewmodel per page" philosophy? Or am I doing it wrong? Is it meant to be a "one viewmodel per data model" philosophy?

Where do I draw the line between ViewModels? Do I risk encapsulating too much functionality into one object, or do I risk separating everything out too broadly and creating duplicative files? How have you structured your Knockout.js ViewModels?

答:
As mentioned by Pelican, you are taking the right approach in terms of tailoring your viewmodels to your views. That said, you can still abstract some functionality out for reuse. For example, you might have use for paging lists in multiple views. In that case, create a generic model that can be reused in multiple viewmodels.

If you find you require more completely functionality, like passing state, dealing with complex CRUD operations etc, then Knockout is probably not best for those cases. In that case, BackBone.js (or fuller frameworks like Angular etc) are more suited to that.


答:
You should start with the book Working Effectively with Legacy Code by Michael Feathers. From the book's introduction, "It's about taking a tangled, opaque, convoluted system and slowly, gradually, piece by piece, step by step, turning it into a simple, nicely structured, well-designed system." He mostly starts with automated testing, so that you can refactor safely (you'll know if you break anything), and he includes lots of strategies for bringing difficult code under automated testing. This is useful for every project that's still under development. Once you've got some basic order in place, you can see what other modern technologies your project could really benefit from--but don't assume you need all of them.

If you want to learn a new framework (or something) for professional reasons rather than because your current project actually needs it, then you should use it in some personal project (on your own time).


问:
Non-licensed source code later becomes licensed
Last year, I created a derived work from published source code that was distributed unlicensed on a blog. Recently, I went back to the blog and noticed it was now licensed under CC BY-SA 3.0. Is my derived work also bound by share alike now?

答:
A license doesn't restrict what you are allowed to do, a license gives you permission to do things that you would not be allowed to do without the license.

If that code had no license, then you had no right to use it, and creating a derived work was copyright infringement. You are lucky that it is now licensed.