问:
Is there really anything to gain with complex design?
I've been working for a consulting firm for some time, with clients of various sizes, and I've seen web applications ranging in complexity from really simple:

MVC

Service Layer

EF

DB

To really complex:

MVC

UoW

DI / IoC

Repository

Service

UI Tests

Unit Tests

Integration Tests

But on both ends of the spectrum, the quality requirements are about the same.  In simple projects, new devs / consultants can hop on, make changes, and contribute immediately, without having to wade through 6 layers of abstraction to understand what's going on, or risking misunderstanding some complex abstraction and costing down the line.

In all cases, there was never a need to actually make code swappable or reusable - and the tests were never actually maintained past the first iteration because requirements changed, it was too time-consuming, deadlines, business pressure, etc etc.

So if - in the end -

testing and interfaces aren't used

rapid development (read: cost-savings) is a priority

the project's requirements will be changing a lot while in development

...would it be wrong to recommend a super-simple architecture, even to solve a complex problem, for an enterprise client?  Is it complexity that defines enterprise solutions, or is it the reliability, # concurrent users, ease-of-maintenance, or all of the above?

I know this is a very vague question, and any answer wouldn't apply to all cases, but I'm interested in hearing from devs / consultants that have been in the business for a while and that have worked with these varying degrees of complexity, to hear if the cool-but-expensive abstractions are worth the overall cost, at least while the project is in development.

答:
Addressing your questions...

...would it be wrong to recommend a super-simple architecture, even to solve a complex problem, for an enterprise client?

Absolutely not.

From the Client Perspective

As stated above, it largely depends on the client. It also depends on your ability to accurately gauge which solutions are right for your client. While there is always going to be a perceived cost to desired value, as a consultant it is your job to set the appropriate expectations of the client. In some cases, you'll have to meet that perception. In others, it will be in your best interest to correct them. After all, you should be the expert for your client. And if you aren't, you should have the knowledge to be able to become that expert. That's what they pay you for.

From the Developer Perspective

The hardest part about choosing which architecture to use is, often, correctly estimating the amount of work required to utilize the technology to meet the specific needs. This can very quickly lead to projects that fail client expectations. Understand that some projects are actually made faster using these "complex" pieces of code that you mention. It is also understood that some are not. You have to provide that measurement, based on what you or your team knows.

Is it complexity that defines enterprise solutions, or is it the reliability, # concurrent users, ease-of-maintenance, or all of the above?

While specifics may vary, in general, an enterprise solution is a software solution that applies to a wide co-mingled audience. The number of concurrent users may or may not be a factor, though often is. The total number of users, frequently in a variety of business roles, is one of the largest determining factors as to whether the solution is "enterprise".

Many enterprise solutions are highly complex, but some are quite simple. While enterprise gives an air of reliability (and should certainly be held to a certain standard), different solutions have different levels of reliability.

Ease of Maintenance is something that I think every developer (independent or team member) strives for, it is not necessarily as easily achieved. What is important is that there is a maintenance procedure that has firm guidelines, rather than it be "easy". Remember, different code-bases will have substantially differing levels of ease depending upon the philosophies, methodologies, (business) environment activity, and complexity of the code.

Reacting to your other statements...

In all cases, there was never a need to actually make code swappable or reusable

There is often never a specific need to do so. This should be your goal, at all times, however. Consider this... You might have a client that requires the ability to access or display their calender from the web page. If you make your own code reusable, then when another client asks for the same thing, you already have some of the work done. If you don't, then you have to do it all over again. Every client problem is often one that another client in the future may need. In other words, every client you work with should have the potential to reduce the cost of work for your future clients (not necessarily the cost of the product).

and the tests were never actually maintained past the first iteration because requirements changed, it was too time-consuming,

I would argue here that the testing methodology was not abstracted enough. I recently used a piece of code that did its own unit tests directly within itself. A custom assert and expect function were made that accommodated the needs of the project. Anytime a unit test was needed, it could be applied without even adjusting the code. In fact, the code is actively distributed with the asserts and expects still in there. It made those checks as part of the working code.

... deadlines, business pressure, etc etc....

I have often found that extra business pressure and deadlines impeding the coding process have been the fault of the developer, not of the client. While this isn't always the case, many times business pressure is caused by a perception of failure to meet client expectations. When deadlines impede code, it is often because the developer failed to accurately gauge the amount of work required for usable functional code. In other words, schedule them (clients expect it), measure them (future clients expect it), perform them (users require it), and get paid for them (your contract should demand it).


问:
How to estimate cost with very little information?
I have a client who wants a web app that will let him do the following (as he told me word for word):

User registration

Recurring payments for users

Online conference room reservation

I am supposed to give him a cost estimate very fast and I don't have any time to do any deeper requirements analysis! How would you deal with that kind of situation? Should I just give a very broad estimate and work out the exact requirements once he has accepted the estimate? At which point do you usually gather requirements, after or before getting a contract?

答:
Get up on Google, find a similar application (I've no idea about web development, so can't give you any more practical advice than this), a company or a private developer which makes those, and ask them for a quotation. Preferably, ask two.

Based on your experience, see how it fits into your plan of development, and think whether you can do it for less (usually lone developers (assuming) have less costs in some areas than companies devoted to those kind of development.)

Give him an approximation, strongly emphasizing that the exact price will depend on his requirements (of the client, that is).

ContentLicense: CC BY-SA 2.5


问:
Problem regarding DRY principle and Polymorphism
I have a class that is 99% identical to its counter part. Sample code goes below:

```<code>public abstract class BaseClass
{
    void Method1() { }
    void Method2() { }
    void Method3() { }
    public void MainMethod(List<Object1> listObject)
    {
        Method1();
        Method2();
        Method3();
        Method4();
    }

    abstract internal void Method4();

}

public sealed class DerivedClass : BaseClass
{
    internal override void Method4()
    {
        throw new NotImplementedException();
    }
}

public class BaseClass2
{
    void Method1() { }
    void Method2() { }
    void Method3() { }
    public void MainMethod2(List<Object2> listObject)
    {
        Method1();
        Method2();
        Method3();
    }

}
</code>```

As You can see that BaseClass and BaseClass2 are almost identical with Method1 ... Method3.
Is there a better alternative that can be used to minimize duplication of code.

I initially started this polymorphism as an encouraging stuff, I have over 11 derived classes on BaseClass, and because of the second implementation of MainMethod2, I am stuck with duplication of code.

I just cannot think of any clever way to get out of it.

Update:
So this question is potentially containing two parts:

1. How to avoid duplication of code?
I solved this by using Composition successfully as suggested by wonderful answers below.

2. How to avoid leaky abstractions?
With this I am still struggling...

答:
Simplest thing is to get rid of BaseClass2.  It's subclasses should just extend BaseClass and override Method4 with a method that does nothing.

Failing that, have BaseClass2 override BaseClass.  All it would need is MainMethod2.

You could go one step further and get rid of MainMethod2 and replace it with an override for MainMethod that only calls Methods 1, 2 & 3.

ContentLicense: CC BY-SA 3.0


问:
Patterns for maintenance login
Are there any reliable strategies to implement a login mechanism that will allow access to an application for maintenance purposes? Kind of like how some routers have a list of default logins that technicians can use. But the way routers do it is insecure, and I was wondering if there are better ways to implement this sort of access control.

EDIT: Here's a possible solution I came up with. Generate a list of passwords for a given time window, say a month, with a different password for every day. This list would exist in the software in encrypted form. Maintenance technicians would have access to this list, and its use would be logged so we know when to block access should unauthorized personnel gets a copy of the list and use it to log in. Periodic updates would renew the application's password table.

答:
Providing an electronic backdoor is a ... terrible idea.  Don't do it.  It doesn't take much searching to find a number of cases where this "feature" blows up and gets the offending company slathered with horrific mentions in the news.

Your best option would be to provide a reset switch within the device itself.  And please note that's within the system, not on the outside of the system. That forces an attacker to have physical access to the system before they can reset passwords.  Obviously, you should provide a lock to secure the physical system in order to discourage unauthorized access.

You should also assume that any time that reset switch is thrown that the system has been compromised.  So you need to provide a means to audit / validate the settings of the system.  And you need to provide some indicator on the system itself to show that it's in an untrusted state.  Ideally, you'll lock it out from being able to process transactions or do anything else until the audit check is cleared.

You'll also need to identify a way to protect any data that may have been stored on that system.  Assume that "reset password" means "someone attacking the device" and then look for ways to harden that data from any access until the system is validated and determined to be trustworthy again.

If you're thinking "wow, that's an incredible pain in the rear" then you'd be right.  But that's the point.  A rogue point of sale system represents a significant liability for the owning company.  You want these types of resets to be difficult to achieve, and you want to make sure any attack against the system is obvious to everyone else.

In your comment, you mention this is for point of sale systems.  MichaelT's comment with a link to some PCI security documents would be a good place to continue your research.

Title: Patterns for maintenance login


问:
How to implement loose coupling?
I want to implement loose coupling in a project.

I know two examples of successful loose coupling designs:

On a Unix workstation, shell scripts realise a loose coupling between basic utilities. The loose coupling relies on the shell's ability to blindly redirect data flows between utilities, without having any knowledge on the structure.  Utilities agree on a common form to cooperate like a pipe-separated format for sort, cut, paste, awk, etc., a svn dump or a trivial dump of a normalised SGML document (with onsglmls).

On a Mac OS X system, Applescripts can be regarded as a loose coupling.

In these two examples, I see that cooperating components agree on a common protocol to serialise and deserialise data that needs to be exchanged. Thus components depend on the serialisation protocol rather than on internal representation of data.

Is the implementation of a stable communication protocol between application components a winning strategy to implement loose coupling (and good encapsulation)?

To solve ties, I also ask what would be a nice name for the protocol artefacts: “data” is a bit vague and there is a lot of them at various places in a software!

答:
By parameterizing.

For example, here f is hard-linked to lots of other modules:

```<code>def f():
    return module1.g(module2.x, module3.y)
</code>```

Here's a less coupled, but similar, example:

```<code>def f(x, y):
    return module1.g(x, y)
</code>```

And a yet less coupled example:

```<code>def f(g, x, y):
    return g(x, y)
</code>```

Coupling can also occur through types:

```<code>String id(String input) {
    return input;
}
</code>```

So why not parameterize those as well?

```<code><T> T id(T t) {
    return t;
}
</code>```

The concept of common interfaces goes hand-in-hand with parameterization -- you can't parameterize something without some idea of its interface.

Title: How to implement loose coupling?

Body:
By parameterizing.

For example, here f is hard-linked to lots of other modules:

def f():
    return module1.g(module2.x, module3.y)

Here's a less coupled, but similar, example:

def f(x, y):
    return module1.g(x, y)

And a yet less coupled example:

def f(g, x, y):
    return g(x, y)

Coupling can also occur through types:

String id(String input) {
    return input;
}

So why not parameterize those as well?

<T> T id(T t) {
    return t;
}

The concept of common interfaces goes hand-in-hand with parameterization -- you can't parameterize something without some idea of its interface.


问:
OOP, domain models, and the user
When developing domain models, I can see two major ways of thinking about the user:

The first one assumes that a program is a kind of "simulation" of what happens in the real world, and the user is an spectator. With that approach you would have a Customer class -for example- with perhaps methods that correspond to the actions a Customer can perform. Whenever the customer wants to do something, the corresponding method is called.

The other approach would be to design the classes as if they were exposed to the user and s/he then has the ability to create and play with the objects “directly”, thinking of the program as a kind of extension of the user’s reality. With this approach, a Customer class would probably make no sense as the customer is already “involved”.

I've read some articles talking about adding security at the method level, which seems to be consistent with the second approach, but I believe the first approach is far more popular.

What's the best way to deal with this?

Thanks.

答:
Two things pop out at me from this question:

the application metaphor (simulation vs API sandbox) has nothing to do with the domain model; until you understand the domain model better that decision should be deferred

You'll probably find that your domain model has more than one way of considering the User.

Security sees users as a potential threat ;)

Data-Processing transactions may see users as Customers and/or Accounts

Configuration/preferences elements may see users as owners of Profiles or Preferences

feature-control elements may see users as members of permission groups

and so on

Title: OOP, domain models, and the user


问:
MVC sending information from view to controller
I am using the MVC pattern.

Lets say I want to create a new object and add it to my database.

Where is it better to create the new object:

View:

```<code>Boo boo = new Boo("awesomness");
Controller.AddDB(boo);
</code>```

Controller:

```<code>public void AddDB(string name)
{
   Boo boo = new Boo(name);
   addtodb(boo);
}
</code>```

答:
The view never directly acts on the model layer. It only uses objects provided by the controller for display. It should not even run read queries, by no means it should ever do anything itself that changes the state of the database.

I use MVC in a web environment where ctrl.Add(new Customer(name, age)) would not be an option anyway. But the view should really have no knowledge about models. Assume it would not only be name and age but you would also want to provide an address. For now all of this is stored in a single customer table. Later you decide that you want to have addresses stored separately. That would be one example why you would not want to have the view to decide what objects to create.

Depending on language and environment the question of object ownership and lifetime would be relevant too. You don't want to spread this over several places where it is not really needed. This especially in languages that do not have garbage collection and the decision when and where to free the objects memory becomes relevant too.


答:
You could also pass delegates to your function.
Your method1,...,method4 seem to have the same signature.
Build a higher order function (your new main method)  which takes multiple delegates as parameters and executes them.
Sorry for missing example, I'm on the phone. I'll edit it tomorrow though

---Example---

```<code>public delegate void ADelegate();

public void someOtherFunction() {

    var methodsToCall = method1 + method2 + method3 + method4;
    newMain(methodsToCall);

    var methodsToCall -= method4;
    newMain(methodsToCall);
}

public void newMain(ADelegate aDelegate){
    aDelegate();
}

public void method1() {...};
public void method2() {...};
public void method3() {...};
public void method4() {...};
</code>```

It's untested, but I think you can get the idea

Title: Problem regarding DRY principle and Polymorphism

Body:
I have a class that is 99% identical to its counter part. Sample code goes below:

```<code>public abstract class BaseClass
{
    void Method1() { }
    void Method2() { }
    void Method3() { }
    public void MainMethod(List<Object1> listObject)
    {
        Method1();
        Method2();
        Method3();
        Method4();
    }

    abstract internal void Method4();

}

public sealed class DerivedClass : BaseClass
{
    internal override void Method4()
    {
        throw new NotImplementedException();
    }
}

public class BaseClass2
{
    void Method1() { }
    void Method2() { }
    void Method3() { }
    public void MainMethod2(List<Object2> listObject)
    {
        Method1();
        Method2();
        Method3();
    }

}
</code>```

As You can see that BaseClass and BaseClass2 are almost identical with Method1 ... Method3.
Is there a better alternative that can be used to minimize duplication of code.

I initially started this polymorphism as an encouraging stuff, I have over 11 derived classes on BaseClass, and because of the second implementation of MainMethod2, I am stuck with duplication of code.

I just cannot think of any clever way to get out of it.

Update:
So this question is potentially containing two parts:

1. How to avoid duplication of code?
I solved this by using Composition successfully as suggested by wonderful answers below.

2. How to avoid leaky abstractions?
With this I am still struggling...

Body:
You could also pass delegates to your function.
Your method1,...,method4 seem to have the same signature.
Build a higher order function (your new main method)  which takes multiple delegates as parameters and executes them.
Sorry for missing example, I'm on the phone. I'll edit it tomorrow though

---Example---

public delegate void ADelegate();

public void someOtherFunction() {

    var methodsToCall = method1 + method2 + method3 + method4;
    newMain(methodsToCall);

    var methodsToCall -= method4;
    newMain(methodsToCall);
}

public void newMain(ADelegate aDelegate){
    aDelegate();
}

public void method1() {...};
public void method2() {...};
public void method3() {...};
public void method4() {...};

It's untested, but I think you can get the idea


问:
Factory for arrays of objects in python
Ok, the title might be a little misleading.

I have a Window class that draws widgets inside itself in the constructor. The widgets are all of the same type.

So I pass a list of dictionaries, which contain the parameters for each widget. This works quite nicely, but I am worried that the interface to callers is obfuscated.

That is, in order to use Window, one has to study the class, construct a correct list of dictionaries, and then call the constructor with only one parameter - widgets_params.

Is this good or bad design? What alternatives does the python syntax provide?

答:
The answer partly depends on exactly what your Widget class does. Is the number of child widgets fixed, or can there be a variable number of child widgets based on the input? Also, once created, does the caller need direct access to these child widgets?

For example, let's assume the number of children is dynamic and based on the number of input parameters. You could make the creation of the parent and children as separate steps. Thus, instead of Widget([list of widget parameters...]) you would do:

```<code>app = Widget()
app.addChild(label="Name:", color="red")
app.addChild(label="Phone:", color="green")
...
</code>```

If the child widgets are first class objects, another solution would be to create them first, and pass them in to the parent class. For example:

```<code>child1 = ChildWidget(label="Name:", color="red")
child2 = ChildWidget(label="Phone:", color="green")
app = Widget(child1, child2)
</code>```

Which is better depends a bit on the nature of the child widgets. If the caller needs complete control, I think the second method is better -- the caller has precise control over the children widgets.

If, on the other hand, the caller should not have complete control and should instead only be allowed to set a few attributes, the first solution might make more sense.

Title: Factory for arrays of objects in python

Body:
The answer partly depends on exactly what your Widget class does. Is the number of child widgets fixed, or can there be a variable number of child widgets based on the input? Also, once created, does the caller need direct access to these child widgets?

For example, let's assume the number of children is dynamic and based on the number of input parameters. You could make the creation of the parent and children as separate steps. Thus, instead of Widget([list of widget parameters...]) you would do:

app = Widget()
app.addChild(label="Name:", color="red")
app.addChild(label="Phone:", color="green")
...

If the child widgets are first class objects, another solution would be to create them first, and pass them in to the parent class. For example:

child1 = ChildWidget(label="Name:", color="red")
child2 = ChildWidget(label="Phone:", color="green")
app = Widget(child1, child2)

Which is better depends a bit on the nature of the child widgets. If the caller needs complete control, I think the second method is better -- the caller has precise control over the children widgets.

If, on the other hand, the caller should not have complete control and should instead only be allowed to set a few attributes, the first solution might make more sense.


问:
Disadvantages to using "associative arrays" in JavaScript
I'm working with some people are are used to making "associative arrays" in JavaScript like this:

```<code>var arr = new Array();
arr.prop_1 = "asdf";
</code>```

or

```<code>arr['prop 2'] = "1234";
</code>```

It works just like an object because it is. for...in loops can be used and accessing the properties is fine using a dot or a square brace. the lack of native array methods seems not to be lamented. I find it sort of semantically irritating however. Maybe I'm being picky, but I want a good argument for arresting the use of this syntax, but I can't understand how to start. Any suggestions?

答:
That's not an associative array. That's an array object abused. It just works because arrays are also objects in JavaScript.

When you're doing arr.prop_1 = "asdf"; or arr['prop 2'] = "1234"; what you're actually doing is monkey patching an object.

People use objects as maps often - but that'll get fixed soon since ES6 (the new version of the standard JS is based on) has Map types.

When to use an Array

When you have sequential data - a list of numbers for example

When to use a map

When you want to store a key-value mapping.


答:
Which do you think looks cleaner?

```<code>object = new Array();
object.prop1 = 1;
object.prop2 = 2;
object.prop3 = 3;
</code>```

or

```<code>object = {
  prop1: 1,
  prop2: 2,
  prop3: 3
}
</code>```

?

Also, if you do something like this:

```<code>if (object.length === undefined) object.length = 10
object.length // 0
</code>```

Then object.length will still be 0, which is definitely not what you would expect. You might think this is just a fake example that will never come up in real life, but look at this:

```<code>words = 'You should join our club because it is a club'.split(' ')
obj = new Array()
words.forEach(function(x) {
  if (obj[x] === undefined) obj[x] = 0
  obj[x] ++
})
for (var x in obj) console.log(x, obj[x])
</code>```

This will log:

```<code>You 1
should 1
join NaN // <-- oops
our 1
club 2
because 1
it 1
is 1
a 1
</code>```

Alternatively, you could make an analogy to any other object, like a function:

```<code>object = function() {}
object.prop1 = 1;
// ...
</code>```

Anyone could immediately tell you that that is wrong, and using an array is just as wrong.

Title: Disadvantages to using "associative arrays" in JavaScript

Body:
I'm working with some people are are used to making "associative arrays" in JavaScript like this:

```<code>var arr = new Array();
arr.prop_1 = "asdf";
</code>```

or

```<code>arr['prop 2'] = "1234";
</code>```

It works just like an object because it is. for...in loops can be used and accessing the properties is fine using a dot or a square brace. the lack of native array methods seems not to be lamented. I find it sort of semantically irritating however. Maybe I'm being picky, but I want a good argument for arresting the use of this syntax, but I can't understand how to start. Any suggestions?

Body:
Which do you think looks cleaner?

object = new Array();
object.prop1 = 1;
object.prop2 = 2;
object.prop3 = 3;

or

object = {
  prop1: 1,
  prop2: 2,
  prop3: 3
}

?

Also, if you do something like this:

if (object.length === undefined) object.length = 10
object.length // 0

Then object.length will still be 0, which is definitely not what you would expect. You might think this is just a fake example that will never come up in real life, but look at this:

words = 'You should join our club because it is a club'.split(' ')
obj = new Array()
words.forEach(function(x) {
  if (obj[x] === undefined) obj[x] = 0
  obj[x] ++
})
for (var x in obj) console.log(x, obj[x])

This will log:

You 1
should 1
join NaN // <-- oops
our 1
club 2
because 1
it 1
is 1
a 1

Alternatively, you could make an analogy to any other object, like a function:

object = function() {}
object.prop1 = 1;
// ...

Anyone could immediately tell you that that is wrong, and using an array is just as wrong.


问:
How do I get people to stop bikeshedding (focusing on trivialities)?
I have been tasked with teaching other teams a new codebase, but I keep running into an issue. Whenever I go to actually walk through the code with people, we don't get very far before the entire exercise devolves into a bikeshedding (members of an organisation giving disproportionate weight to trivial issues) exercise. Since they don't know the codebase, but think they need to help improve it, they focus on the things they can understand:

Why is that named that?
(2 minutes to explain why it's named that, 10+ minutes debating a new name)

Why is that an abstract base class rather than an interface? (2 minutes to explain, 10+ minutes debating the relative merits of this decision)

...and so on. Now, don't get me wrong - good names and good, consistent design are important, but we never get to discussing what the code actually does or how the system is designed in any meaningful way. I've done some meeting refereeing to get people out of these tangents, but they're gone - distracted by what the code will/should be when their pet triviality is fixed, and they miss the bigger picture.

So we try again later (or with a different part of the codebase) and since people didn't get enough knowledge to overcome the bikeshedding effect, it repeats.

I've tried smaller groups, bigger groups, code, whiteboarding, visio diagrams, giant walls of text, letting them just argue it to death, cutting arguments short immediately... some help more than others, but nothing works. Hell, I even tried having other people from my team explain it because I thought it might be that I'm just bad at explaining things.

So how do you educate other programmers enough that they stop fixating on trivialities and can meaningfully contribute to the design?

答:
So how do you educate other programmers enough that they stop fixating on trivialities and can meaningfully contribute to the design?

First, don't think of their concerns as "trivialities" or "bikeshedding".  Those are judgmental words, and they're insulting.  Their concerns are valid.  They're just not important at the moment.

The key to any good meeting is for everyone to know:

why you're having a meeting and

what you hope to get out of it

how long it should last

State these things up front, explicitly, and explain the goals.

For example, you might say: "This meeting is for me to familiarize you with the Foo package and how it's used in our reporting module.  My goal is to have you understand enough about Foo that you can work on the Bar Reports project coming up next week.  I'd like us to be done in the next 90 minutes."

Then, when a topic comes up, it might go like this:

New person: "Why is FooWidget implemented as a facade pattern?"

You: "Well, I think it's because (short explanation of design decision)" or "I don't know."

If the answer is enough, that's great.  If not, and it continues:

NP: "Don't you think it would be better done as a singleton?"

You: "I hadn't really thought about it, but I'd like to keep moving ahead with explaining how FooWidget works."

NP: "But if it's done as a singleton then we can--"

You: "I'm sorry to interrupt, but I need to keep this focused on how FooWidget works.  This meeting is only scheduled until 11:00 and we have a lot to get through.  The design discussion will have to wait for another time."

After you go through that once or twice, you can shorthand it to "That's outside the scope of this meeting."

Note that you are not saying "That's dumb to worry about" or "It doesn't matter" or "Shut up" or "You're too new to have input."  You're simply focusing the meeting on what needs to get done and the time involved.


问:
Improving the Java development workflow
I will like to assist my group standardize to a reproducable Java tooling environment that aligns with some good practices to improve on our workflow.  We are predominantly a .NET shop that has been doing quite a bit of Java development recently and have been burned too many times with our current Java development process.

The process is ad-hoc, since we are kind of new to all things Java.  Each developer decides on their tool of choice (somewhat a good thing) and due to the lack of any kind of procedure in terms of 3rd party dependency management, we more often than not run into build or deployment problems and hit serious setbacks when developer machines have to be rebuilt for one reason or another.  Our Java development environments are simply neither consistent nor repeatable from one machine to another.

We do not have a similar problem with our .NET projects.  Everyone runs the same version of Visual Studio, Resharper, and all 3rd party and open source libraries.  Possibly because we pay for most of the stuff but there is also a consistent pattern across our C# projects where everything one needs is encapsulated into the solution file and all 3rd party dlls required for this solution are checked into sub a directory relative to the parent solution in source control.  Visual Studio helps here too with its version check but this process  is working well and I feel it could be replicated for our Java development efforts.

To help achieve this goal, I have compiled the following list of questions to gauge what the experts are using out there.

What Java development IDE do you use?   Eclipse, NetBeans or IntelliJ ?

Do you use a dependency management tool such as Apache Maven, Gradle, a standardize home grown solution, or does each developer determine what works best for them?  What we have

If the answer to 2, is yes, how do you integrate such tools with your build system?

Do you standardize on a specific version of the IDE, related tools and runtime?   For example, are all devs running Eclipse IDE for Java EE Developers 3.7, IntelliJ 12.1.6, JDK1.7 or 1.8 and are there any policies to enforce that all devs are using the same version?

How do you ensure that projects settings are consistent and repeatable across dev machines?   Do you mandate checking in all of a project settings into source control or just the respective source files?

For each tool, including IDE, dependency management and build, what selection process did you use?

Items highlighted in bold is what we are learning towards based on past experiences.  But it will be good to learn from what others are doing.

I will start by answering some of the questions, listing some of the problems we are facing:

Every developer uses Eclipse.  However Eclipse and JDK versions could differ from one machine to another.  Dev A could be running Eclipse Juno with JDK 1.6 while Dev B is  running Eclipse Galileo with JDK 1.7.  The build machine could be running something different and we will only know there is a problem next morning when build is broken.  WIth resources also distributed across continents, this causes serious headaches.  For IDE standardization, I am leaning towards IntelliJ for usability and consistency, just to name a few.

We do not use any such tool.  Instead all 3rd party libs are stored in a 3rdParty central folder outside of the solution tree.  Then we have an Eclipse project setup to reference these JARs.  This works well but this 3rdparty folder is very large.  So if you do not want to selectively checkout the JARs you need just to get this project compile, you are in for a long morning waiting to check out the entire 3rdParty folder from SVN.  For dependency management, I am leaning towards Maven.

We use raw ANT scripts.  Each developer needs to ensure that all the stuff required to  build the project is checked into source control. But because these resources are all over the place, remember, the 3rd party folder is not part of the project tree, it is very easy  to forget checking in that new dependent JAR downloaded from somewhere.  And if you use Maven, like I do, I need to copy the JAR from my local Maven repo to the relevant centrll 3rdParty folder so that the build machine does not complain.  However, there is still a good chance that this build will fail since the build environment could also be different.  For build and packaging, I am also leaning towards  Maven to ensure that the build environment is similar to the dev environment.  I want to relieve the pain of having to remember where to put dependencies.

No.  See answer 1.

We do not, possibly because we are not saving the entire Eclipse workspace into source control.  So if I receive a new machine and check out an Eclipse project, I will have to spend a good portion of my day configuring project settings that should have been saved in source control.

TIA for all comments.

EDIT:  Just to add that we do have a CI server and use Jenkins/ANT scripts for building.

Klaus

答:
If you are already a .Net shop and don't seem to have these same issues over there. My recommendation is to do what they are doing. My bet is, they have a known IDE version, with a known framework version across all machines.

None of these problems are JAVA specific, although I will admit .NET has not quite embraced dependency management as well as the Java community as a whole. My answer to that one is yes use one of those tools. You lean towards Maven, use that it is a great tool.

Title: Improving the Java development workflow


问:
What should you test with unit tests?
I'm freshly out of college, and starting university somewhere next week. We've seen unit tests, but we kinda not used them much; and everyone talks about them, so I figured maybe I should do some.

The problem is, I don't know what to test. Should I test the common case? The edge case? How do I know that a function is adequately covered?

I always have the terrible feeling that while a test will prove that a function works for a certain case, it's utterly useless to prove that the function works, period.

答:
Among the plethora of answers thusfar no one has touched upon equivalence partitioning and boundary value analysis, vital considerations in the answer to the question at hand.
All of the other answers, while useful, are qualitative but it is possible--and preferable--to be quantitative here. @fishtoaster provides some concrete guidelines, just peeking under the covers of test quantification, but equivalence partitioning and boundary value analysis allow us to do better.

In equivalence partitioning, you divide the set of all possible inputs into groups based on expected outcomes. Any input from one group will yield equivalent results, thus such groups are called equivalence classes. (Note that equivalent results does not mean identical results.)

As a simple example consider a program that should transform lowercase ASCII characters to uppercase characters. Other characters should undergo an identity transformation, i.e. remain unchanged. Here is one possible breakdown into equivalence classes:

```<code>| # |  Equivalence class    | Input        | Output       | # test cases |
+------------------------------------------------------------------------+
| 1 | Lowercase letter      | a - z        | A - Z        | 26           |
| 2 | Uppercase letter      | A - Z        | A - Z        | 26           |
| 3 | Non-alphabetic chars  | 0-9!@#,/"... | 0-9!@#,/"... | 42           |
| 4 | Non-printable chars   | ^C,^S,TAB... | ^C,^S,TAB... | 34           |
</code>```

The last column reports the number of test cases if you enumerate all of them. Technically, by @fishtoaster's rule 1 you would include 52 test cases--all of those for the first two rows given above fall under the "common case". @fishtoaster's rule 2 would add some or all from rows 3 and 4 above as well. But with equivalence partitioning testing any one test case in each equivalence class is sufficient. If you pick "a" or "g" or "w" you are testing the same code path. Thus, you have a total of 4 test cases instead of 52+.

Boundary value analysis recommends a slight refinement: essentially it suggests that not every member of an equivalence class is, well, equivalent. That is, values at boundaries should also be considered worthy of a test case in their own right. (One easy justification for this is the infamous off-by-one error!) Thus, for each equivalence class you could have 3 test inputs. Looking at the input domain above--and with some knowledge of ASCII values--I might come up with these test case inputs:

```<code>| # | Input                | # test cases |
| 1 | a, w, z              | 3            |
| 2 | A, E, Z              | 3            |
| 3 | 0, 5, 9, !, @, *, ~  | 7            |
| 4 | nul, esc, space, del | 4            |
</code>```

(As soon as you get more than 3 boundary values that suggests you might want to rethink your original equivalence class delineations, but this was simple enough that I did not go back to revise them.) Thus, boundary value analysis brings us up to just 17 test cases -- with a high confidence of complete coverage -- compared to 128 test cases to do exhaustive testing. (Not to mention that combinatorics dictate that exhaustive testing is simply infeasible for any real-world application!)

Title: What should you test with unit tests?

Body:
Among the plethora of answers thusfar no one has touched upon equivalence partitioning and boundary value analysis, vital considerations in the answer to the question at hand.
All of the other answers, while useful, are qualitative but it is possible--and preferable--to be quantitative here. @fishtoaster provides some concrete guidelines, just peeking under the covers of test quantification, but equivalence partitioning and boundary value analysis allow us to do better.

In equivalence partitioning, you divide the set of all possible inputs into groups based on expected outcomes. Any input from one group will yield equivalent results, thus such groups are called equivalence classes. (Note that equivalent results does not mean identical results.)

As a simple example consider a program that should transform lowercase ASCII characters to uppercase characters. Other characters should undergo an identity transformation, i.e. remain unchanged. Here is one possible breakdown into equivalence classes:

| # |  Equivalence class    | Input        | Output       | # test cases |
+------------------------------------------------------------------------+
| 1 | Lowercase letter      | a - z        | A - Z        | 26           |
| 2 | Uppercase letter      | A - Z        | A - Z        | 26           |
| 3 | Non-alphabetic chars  | 0-9!@#,/"... | 0-9!@#,/"... | 42           |
| 4 | Non-printable chars   | ^C,^S,TAB... | ^C,^S,TAB... | 34           |

The last column reports the number of test cases if you enumerate all of them. Technically, by @fishtoaster's rule 1 you would include 52 test cases--all of those for the first two rows given above fall under the "common case". @fishtoaster's rule 2 would add some or all from rows 3 and 4 above as well. But with equivalence partitioning testing any one test case in each equivalence class is sufficient. If you pick "a" or "g" or "w" you are testing the same code path. Thus, you have a total of 4 test cases instead of 52+.

Boundary value analysis recommends a slight refinement: essentially it suggests that not every member of an equivalence class is, well, equivalent. That is, values at boundaries should also be considered worthy of a test case in their own right. (One easy justification for this is the infamous off-by-one error!) Thus, for each equivalence class you could have 3 test inputs. Looking at the input domain above--and with some knowledge of ASCII values--I might come up with these test case inputs:

| # | Input                | # test cases |
| 1 | a, w, z              | 3            |
| 2 | A, E, Z              | 3            |
| 3 | 0, 5, 9, !, @, *, ~  | 7            |
| 4 | nul, esc, space, del | 4            |

(As soon as you get more than 3 boundary values that suggests you might want to rethink your original equivalence class delineations, but this was simple enough that I did not go back to revise them.) Thus, boundary value analysis brings us up to just 17 test cases -- with a high confidence of complete coverage -- compared to 128 test cases to do exhaustive testing. (Not to mention that combinatorics dictate that exhaustive testing is simply infeasible for any real-world application!)


答:
What you call bikeshedding, I would call converting someone's flow of thoughts into our own. By discussing names, patterns, they get to understand the code into their own terms and there isn't any way to prevent it, it is needed.

Besides, there isn't any need to go for a very detailed walkthrough of a whole codebase, because details will be forgotten long before they get to work on it.

Based on these two ideas, I would suggest to break up the code base into units, and the learners into two-people groups. For each unit of code, each group will have, say 25 minutes (depends on the LOC of course), to be able to do a 5-10 minutes walkthrough of the code to the others. Three minutes of questions and repeat with the next unit. Explain is the key word; they have to ensure the others have understood all of it.

You would be only there to enforce time, no off-topic and control the unit has been understood enough. They will be actors of their learning and will be more focused on explaining to the others than bikeshedding.

You may require a high-level hand drawn schema from them of the code unit, which will be copied and kept on the team-shared documents, so they have something tangible to refer to in the future. That's good to anchor memories too.

Sorry if you have already tried that...

Title: How do I get people to stop bikeshedding (focusing on trivialities)?

Body:
I have been tasked with teaching other teams a new codebase, but I keep running into an issue. Whenever I go to actually walk through the code with people, we don't get very far before the entire exercise devolves into a bikeshedding (members of an organisation giving disproportionate weight to trivial issues) exercise. Since they don't know the codebase, but think they need to help improve it, they focus on the things they can understand:

Why is that named that?
(2 minutes to explain why it's named that, 10+ minutes debating a new name)

Why is that an abstract base class rather than an interface? (2 minutes to explain, 10+ minutes debating the relative merits of this decision)

...and so on. Now, don't get me wrong - good names and good, consistent design are important, but we never get to discussing what the code actually does or how the system is designed in any meaningful way. I've done some meeting refereeing to get people out of these tangents, but they're gone - distracted by what the code will/should be when their pet triviality is fixed, and they miss the bigger picture.

So we try again later (or with a different part of the codebase) and since people didn't get enough knowledge to overcome the bikeshedding effect, it repeats.

I've tried smaller groups, bigger groups, code, whiteboarding, visio diagrams, giant walls of text, letting them just argue it to death, cutting arguments short immediately... some help more than others, but nothing works. Hell, I even tried having other people from my team explain it because I thought it might be that I'm just bad at explaining things.

So how do you educate other programmers enough that they stop fixating on trivialities and can meaningfully contribute to the design?


答:
1: I use IntelliJ (I'm biased as a prior JetBrains employee); other people use IntelliJ or Eclipse. I tried to use Eclipse and seriously disliked it.

2: Currently we use a custom closed-source tool. Before that, we all used IDEA and used its dependency control. Another team used Maven.

3: Currently there are custom build plugins for both IDEA and Eclipse, but I prefer the command line anyway. (In a Linux environment the command line is a nice friendly place.)

4: Not standardized, since IDEA seems to handle project files from other versions well, as long as versions don't differ too much. Not sure about Eclipse.

4: When we standardized on IDEA, we checked the project file into the VCS. Now we don't, instead we keep our custom tool's build files in the VCS.

5: Developers come with their own preference of an IDE (unless they develop that very IDE, then the choice is obvious). I use the community edition of IDEA.

Title: Improving the Java development workflow

Body:
I will like to assist my group standardize to a reproducable Java tooling environment that aligns with some good practices to improve on our workflow.  We are predominantly a .NET shop that has been doing quite a bit of Java development recently and have been burned too many times with our current Java development process.

The process is ad-hoc, since we are kind of new to all things Java.  Each developer decides on their tool of choice (somewhat a good thing) and due to the lack of any kind of procedure in terms of 3rd party dependency management, we more often than not run into build or deployment problems and hit serious setbacks when developer machines have to be rebuilt for one reason or another.  Our Java development environments are simply neither consistent nor repeatable from one machine to another.

We do not have a similar problem with our .NET projects.  Everyone runs the same version of Visual Studio, Resharper, and all 3rd party and open source libraries.  Possibly because we pay for most of the stuff but there is also a consistent pattern across our C# projects where everything one needs is encapsulated into the solution file and all 3rd party dlls required for this solution are checked into sub a directory relative to the parent solution in source control.  Visual Studio helps here too with its version check but this process  is working well and I feel it could be replicated for our Java development efforts.

To help achieve this goal, I have compiled the following list of questions to gauge what the experts are using out there.

What Java development IDE do you use?   Eclipse, NetBeans or IntelliJ ?

Do you use a dependency management tool such as Apache Maven, Gradle, a standardize home grown solution, or does each developer determine what works best for them?  What we have

If the answer to 2, is yes, how do you integrate such tools with your build system?

Do you standardize on a specific version of the IDE, related tools and runtime?   For example, are all devs running Eclipse IDE for Java EE Developers 3.7, IntelliJ 12.1.6, JDK1.7 or 1.8 and are there any policies to enforce that all devs are using the same version?

How do you ensure that projects settings are consistent and repeatable across dev machines?   Do you mandate checking in all of a project settings into source control or just the respective source files?

For each tool, including IDE, dependency management and build, what selection process did you use?

Items highlighted in bold is what we are learning towards based on past experiences.  But it will be good to learn from what others are doing.

I will start by answering some of the questions, listing some of the problems we are facing:

Every developer uses Eclipse.  However Eclipse and JDK versions could differ from one machine to another.  Dev A could be running Eclipse Juno with JDK 1.6 while Dev B is  running Eclipse Galileo with JDK 1.7.  The build machine could be running something different and we will only know there is a problem next morning when build is broken.  WIth resources also distributed across continents, this causes serious headaches.  For IDE standardization, I am leaning towards IntelliJ for usability and consistency, just to name a few.

We do not use any such tool.  Instead all 3rd party libs are stored in a 3rdParty central folder outside of the solution tree.  Then we have an Eclipse project setup to reference these JARs.  This works well but this 3rdparty folder is very large.  So if you do not want to selectively checkout the JARs you need just to get this project compile, you are in for a long morning waiting to check out the entire 3rdParty folder from SVN.  For dependency management, I am leaning towards Maven.

We use raw ANT scripts.  Each developer needs to ensure that all the stuff required to  build the project is checked into source control. But because these resources are all over the place, remember, the 3rd party folder is not part of the project tree, it is very easy  to forget checking in that new dependent JAR downloaded from somewhere.  And if you use Maven, like I do, I need to copy the JAR from my local Maven repo to the relevant centrll 3rdParty folder so that the build machine does not complain.  However, there is still a good chance that this build will fail since the build environment could also be different.  For build and packaging, I am also leaning towards  Maven to ensure that the build environment is similar to the dev environment.  I want to relieve the pain of having to remember where to put dependencies.

No.  See answer 1.

We do not, possibly because we are not saving the entire Eclipse workspace into source control.  So if I receive a new machine and check out an Eclipse project, I will have to spend a good portion of my day configuring project settings that should have been saved in source control.

TIA for all comments.

EDIT:  Just to add that we do have a CI server and use Jenkins/ANT scripts for building.

Klaus


答:
I feel that you're doing it wrong. You're heading towards a. unmaintainable spaghetti environment.

Java projects tend to grow to tens or hunderds of dependencies. You start from Guava, JodaTime, SLF4J some commons and it grows... and it's OK. Just don't try to maintain it manually. Maven/Gradle is a must!

Never ever commit Eclipse workspace files. It just not work.

Let's start from the beginnig.

Set up a CI server. An independent tool that will pull the code from repository, build it, run the tests and send an e-mail if the build is broken. Jenkins is a pretty straightforward tool.

You definetely need Maven or Gradle. (You can try Ant+Ivy but I woouldn't go that way). Most of IDEs integrate pretty good and transparent with Maven.

It's good to have the same version of JDK 1.7. However you set the source and target version in Maven.

Don't try to force anyone to use any IDE. It does not matter.

So if I was answering your questions:

Does not matter. Let anyone choose the one he/she knows key shortcuts and is most productive with.

Maven! or Gradle but Maven has better IDE integration.

It is a build system. You integrate IDE with it and it just works.

Does not matter.

All you need is sources and pom.xml (if Maven). No other files. You just pick IDE of your choice and import/open Maven project.

Dependency management/build system you need to choose arbitrarily. Maven is easier and has better integration. Gradle may need some work but it's more extensible. Ant is a road of pain. IDE - let everyone choose.

We've just finished migrating Ant+Eclipse-commited-workspace+3rd-paarty-libs-in-SVN project  to Maven projects...

Title: Improving the Java development workflow


答:
R1. We use Eclipse or whatever, including IntelliJ

Eclipse has "first class" support: we make sure that whatever changes we do in the development environment doesn't break anyone, and make sure the developer experience is as smooth as possible. It's also the IDE used for trainings.

That said, people can use whatever environment they like, and we have a sizable crowd using IntelliJ. The deal is that they should still comply with all Eclipse based requirements (such as code formatting conventions, warning settings, etc...) - and that it's on them to figure it out.

We have a 'recommended' version of Eclipse, but you can use something else - you just fall in the 'whatever' category.

R2. We use maven.

The maven command line build is actually the reference. It doesn't matter if something works within Eclipse if it doesn't on the command line.

Both Eclipse and IntelliJ have excellent integrations with maven, so the additional work required to make sure that a maven projects opens smoothly and correctly in either is minimal.

R3. Our build system is based on Jenkins, so equivalent to command line build (which is the reference).

R4. The CI server is always the reference: it doesn't matter so much what you use locally, unless you break the build (or tests) and then it probably means you diverge enough it matters. Fix it.

R5. We generally source control eclipse .project, .classpath and .settings.

While in theory it's not strictly required and those can be generated, checking them in ensure more consistency between developers. It also make accommodations for complex setups where m2e or maven-eclipse-plugins are not quite reliable, or where the IDE needs slightly more information than available in the pom to run smoothly. (It also makes the dev experience of importing projects smoother).

R6. Whatever people liked at the time (or thought was good).

Title: Improving the Java development workflow


答:
Try teaching them the design of the codebase first, guide them round the architecture, BEFORE you start looking at specific examples. That way they might see how the code examples you look at fit into the bigger picture. Think about how your training programme is structured. And include the business motivation behind the design.

I spent several years training other developers, and I never went into the code before showing them how the system fitted together. Then when I got them doing code exercises in the framework the questions were structured and on-topic.


答:
If the model needs updated, this has to be done in the controller--that is, after all, where the actions of the system are contained. In ASP.NET MVC (since you don't specify what kind of MVC you are using), you POST the data back to an action which takes the model and would call some sort of database command (be it through an ORM, stored procedure, or inline SQL call).

Doing any of this in the view would violate the separation of concerns that you establish by using an MVC architecture.

Title: MVC sending information from view to controller

Body:
I am using the MVC pattern.

Lets say I want to create a new object and add it to my database.

Where is it better to create the new object:

View:

```<code>Boo boo = new Boo("awesomness");
Controller.AddDB(boo);
</code>```

Controller:

```<code>public void AddDB(string name)
{
   Boo boo = new Boo(name);
   addtodb(boo);
}
</code>```


问:
What workflow do you find efficient when simultaneously developing multiple inter-dependent GIT branches?
Let me start by saying that my GIT knowledge is fairly shallow, so I'm guessing that there might be something I'm missing.

THE SETUP:

As an example, we have a project which is being developed as a collection of plug-ins/modules.
Some modules, such as contact management, depend on others, such as validation.
Each module has it's own branch.

CURRENT WORK FLOW:

Our validation module is being concurrently developed with our other modules, just in a separate stream. In doing so, I am finding that I am having to do a lot of checking out back and forth (as well as a lot of stashing (and merging, but that I'm fine with)).

For example, say I'm developing module_x which needs a new validation rule (which will have uses in other modules as well) ... I then:

stash my work

checkout the validation branch

write the rule

commit

checkout the module_x branch

pop the stash

merge the validation branch into module_x.

Now, if I come up with an improvement for something in the validation branch (or just need to fix a bug), I have to go through all that all over again.

Between new development, refactoring/improvements, and bug fixing, I feel like I'm spending entirely too much time just switching back and forth between developments streams, and can't help but think that there's a better way.

DO's and DONT's:

Is this really how it's done, or am I completely missing the bigger picture? :)

What works for you?

答:
You may be confusing "module" with "branch."  Just because two classes are in two entirely distinct source code files and wind up in two entirely different distibution files does not mean you need to revise them on different branches.

Ideally, you would have a single personal branch for your entire project, so than when you share your revisions to the various modules they belong to they are done atomically.  (And you share to a development branch with your team once your personal development is in a shareable state, and the development branch is what eventually points to the formal build.)

If the modules are intended to be separate for architectural reasons, you probably don't want to be working on both implementation and validation.  Someone else should be the one to write the validation of what you did, so that you get an automatic check against unspoken assumptions.  And while that "should" is of the "everyone should pay their taxes on time and in full" kind, you can get a smiliar effect by simply working in sequence.

A branch in git is meant to represent a period of change to the whole project, not just to part of it.


答:
Count individual web pages. For example, "user registration" probably means there's a "sign up" page - is there also an "edit my profile" page? A "look at someone else's profile" page? Can managers edit their people? Is there a "change password" page? A "forgot my password" page? Do they have to provide secret questions and answers, in which case are there also pages for that? Repeat all this for your other bullets. You come up with some number, like 7 or 27 or 93 or whatever, of web pages. (This list will form part of your proposal and show the client you've already started to design the project.)

If you have built web pages before using the tech you plan to use, you should have a rough feel for average effort per page. 1 hour, half a day, 1 day - it depends not only on your tech but on how much time you put into look and feel, validations, accessiblity - but you should know this number already. Multiply the two. Possibly add time to "design database and write procs" or "design report layouts" if it prints fancy stuff. Add a contingency of 10-25% depending on what you think the client will tolerate. Done.

If you haven't used the tech before to make web pages, decline this work. If for some reason you can't, then prepare to lose money because you will not be able to bill for your learning time and you won't be ready to make good estimates. As a desparation approach if you really feel you must take the job, offer to do a "feasibility study" in which you will design the project and estimate a fixed-bid price to implement your design. Either ask to be "on the clock" for the feasibility study, or offer a flat bid like 1 day or 1 week or 2 weeks.

Title: How to estimate cost with very little information?

Body:
I have a client who wants a web app that will let him do the following (as he told me word for word):

User registration

Recurring payments for users

Online conference room reservation

I am supposed to give him a cost estimate very fast and I don't have any time to do any deeper requirements analysis! How would you deal with that kind of situation? Should I just give a very broad estimate and work out the exact requirements once he has accepted the estimate? At which point do you usually gather requirements, after or before getting a contract?


答:
Using Array object in this manner feels very, very wrong. It completely removes the benefits of Array class and adds no value whatsoever.

The whole point of using arrays is to.. well.. treat them like arrays. So you get access to goodies such as push, pop, shift, splice, sort, join, .length etc.

Just consider what happens when you add few properties to your array this way:

```<code>var test = new Array();
test.prop1 = 'hi';
test.prop2 = 'ho';
test.prop3 = 'ha';

test.length; // returns 0
test.join() // returns ""
test.pop() // returns undefined ... and so on
</code>```

You completely obliterated the true function of an array.

Even looping through this monstrosity is not trivial, as you need to pass each property through hasOwnProperty to check if it is a property you set, or is it something coming from Array.prototype. - as Doorknob pointed out internal array properties are not visible.

I'm not even going to start with what happens when someone tries to assign a property called length on this object, etc.

Now, there is a right way to store properties like this, using a simple Object.

```<code>var test = {};
test.prop1 = 'hi';
test.prop2 = 'ho';
test.prop3 = 'ha';
</code>```

Here, you can still loop through it retrieving the keys and values but most important part of this syntax and what it is often used for, is that you can look up value directly, without looping: test['prop1']. This is great, because you don't have to loop through big object/array to find the property you're looking for.

So once again - if you want to store bunch of values and treat them as an array where you can add/remove items easily and use .length to check number of elements etc - use Array class.

If you want to access item directly by the key, and you don't need any of the array functionality (think hashmap), use simple Object.

But for God's sake do not use Array class for your hashmap base.

Body:
Using Array object in this manner feels very, very wrong. It completely removes the benefits of Array class and adds no value whatsoever.

The whole point of using arrays is to.. well.. treat them like arrays. So you get access to goodies such as push, pop, shift, splice, sort, join, .length etc.

Just consider what happens when you add few properties to your array this way:

var test = new Array();
test.prop1 = 'hi';
test.prop2 = 'ho';
test.prop3 = 'ha';

test.length; // returns 0
test.join() // returns ""
test.pop() // returns undefined ... and so on

You completely obliterated the true function of an array.

Even looping through this monstrosity is not trivial, as you need to pass each property through hasOwnProperty to check if it is a property you set, or is it something coming from Array.prototype. - as Doorknob pointed out internal array properties are not visible.

I'm not even going to start with what happens when someone tries to assign a property called length on this object, etc.

Now, there is a right way to store properties like this, using a simple Object.

var test = {};
test.prop1 = 'hi';
test.prop2 = 'ho';
test.prop3 = 'ha';

Here, you can still loop through it retrieving the keys and values but most important part of this syntax and what it is often used for, is that you can look up value directly, without looping: test['prop1']. This is great, because you don't have to loop through big object/array to find the property you're looking for.

So once again - if you want to store bunch of values and treat them as an array where you can add/remove items easily and use .length to check number of elements etc - use Array class.

If you want to access item directly by the key, and you don't need any of the array functionality (think hashmap), use simple Object.

But for God's sake do not use Array class for your hashmap base.


答:
It works "like an object" because near everything in JS IS an object.

Observe the following legit but mostly completely pointless property assignments:

```<code>function doSomething(){};
doSomething.someProperty = 'bob';

6..someProperty = 'bob'; //(6). would have worked too

'bob'.someProperty = 'bob';
</code>```

Any object can also have properties via bracket notation, which allows for property names not regularly allowed by regular JS var/property naming restrictions. This comes in very handy for doing things like mapping URLs to methods or objects.

In your friends' case, there are two things they're doing that are kind of silly.

They're using the Array constructor when they should be using an array literal. It's not a huge deal but it creates pointless overhead and some warn that somebody could override the Array constructor func but that would be a really stupid thing to do that would get noticed in most code bases anyway. General convention if you need a JS array is to simply do this.

var arrayFoo = [];

It serves zero benefit to use an array for what they perceive to be associative array-like behavior because any object in JS can have properties assigned in this manner and arrays are objects too. Using an object literal makes intent more clear and you don't inherit all that array stuff you won't be using with your object properties set with bracket notation anyway.

```<code>var nameValuePairs = {
    'someValue': 'bob',
    anotherValue: 'joe',
    'string properties are like bracket notation' : 'bar'
};
</code>```

And of course you can add as many more on as you want:

```<code>nameValuePairs['some other value'] = 'bob 2';
</code>```

Note that it is not always bad behavior to tack properties on to features of JS that aren't normally referred to as objects. For instance function constructors frequently have properties set directly on them. This is similar to how you might put static methods on a class in Java or C#. For instance you create timestamps with new Date but you can also parse milliseconds into a date object with Date.parse. In the right circumstances it might make sense to put extra properties on an array too but I wouldn't make a habit of it.

JS really only has two data structures. {} and []. That might sound limited but given how flexible and fully-featured they are, there's really not much you can't do readily with a combination of the two. There's no need for associative arrays because object literals have that covered.

So to get them to stop I would tell them it makes their intentions unclear or worse, it makes them look like JS noobs.

Body:
It works "like an object" because near everything in JS IS an object.

Observe the following legit but mostly completely pointless property assignments:

function doSomething(){};
doSomething.someProperty = 'bob';

6..someProperty = 'bob'; //(6). would have worked too

'bob'.someProperty = 'bob';

Any object can also have properties via bracket notation, which allows for property names not regularly allowed by regular JS var/property naming restrictions. This comes in very handy for doing things like mapping URLs to methods or objects.

In your friends' case, there are two things they're doing that are kind of silly.

They're using the Array constructor when they should be using an array literal. It's not a huge deal but it creates pointless overhead and some warn that somebody could override the Array constructor func but that would be a really stupid thing to do that would get noticed in most code bases anyway. General convention if you need a JS array is to simply do this.

var arrayFoo = [];

It serves zero benefit to use an array for what they perceive to be associative array-like behavior because any object in JS can have properties assigned in this manner and arrays are objects too. Using an object literal makes intent more clear and you don't inherit all that array stuff you won't be using with your object properties set with bracket notation anyway.

var nameValuePairs = {
    'someValue': 'bob',
    anotherValue: 'joe',
    'string properties are like bracket notation' : 'bar'
};

And of course you can add as many more on as you want:

nameValuePairs['some other value'] = 'bob 2';

Note that it is not always bad behavior to tack properties on to features of JS that aren't normally referred to as objects. For instance function constructors frequently have properties set directly on them. This is similar to how you might put static methods on a class in Java or C#. For instance you create timestamps with new Date but you can also parse milliseconds into a date object with Date.parse. In the right circumstances it might make sense to put extra properties on an array too but I wouldn't make a habit of it.

JS really only has two data structures. {} and []. That might sound limited but given how flexible and fully-featured they are, there's really not much you can't do readily with a combination of the two. There's no need for associative arrays because object literals have that covered.

So to get them to stop I would tell them it makes their intentions unclear or worse, it makes them look like JS noobs.


答:
It sounds like what you want is the Strategy Pattern. Your methods are your "Strategy" following an interface. I'm going to make your methods return float and take two float as arguments to help illustrate the strategy pattern:

```<code>interface MathsStrategy {
    float execute(float a, float b);
}
</code>```

and you have some classes that implement this interface:

```<code>// Method1
class Add implements MathsStrategy {
    public float execute(float a, float b) {
        return a + b;
    }
}

// Method2
class Subtract implements MathsStrategy {
    public float execute(float a, float b) {
        return a - b;
    }
}

// Method3
class Multiply implements MathsStrategy {
    public float execute(float a, float b) {
        return a * b;
    }
}
</code>```

and you could wrap Method1, Method2, and Method3 together as you use them in a group:

```<code>// Composite of Method1, Method2 and Method3
class CompositeOf123 implements MathsStrategy {
    public float execute(float a, float b) {
        return new Add().execute(a, b) + new Subtract().execute(a, b) + new Multiply().execute(a, b);
    }
}
</code>```

Okay, contrived but hopefully you get the point.

Then we have the methods that vary:

```<code>// First example of Method4
class Divide implements MathsStrategy {
    public float execute(float a, float b) {
        return a / b;
    }
}

// Second example of Method4
class Exponentiation implements MathsStrategy {
    public float execute(float a, float b) {
        return a ^ b;
    }
}
</code>```

Summing up, we have a few methods that we use frequently and want to use in composite and some different implementations that we want to use sometimes so we create different strategies for these.

Now, if we pass these to the class as part of the constructor then we don't really even need the inheritance. It is the behaviour of the method that needs to change, not the class itself. This way we don't need to alter the class to implement a different strategy, we just pass the strategy to the class' constructor when we create an instance of the class.

So your class becomes:

```<code>public class MyClass
{
    private MathsStrategy strategy;

    public MyClass(MathsStrategy maths) {
        strategy = maths;
    }

    public float MainMethod(float a, float b) {
        return strategy.execute(a, b);
    }
}
</code>```

Now you just have to create instances of MyClass that will use the different strategies as required:

```<code>float a = 15.0F;
float b = 25.0F;
float result;

MyClass addition = new MyClass(new Add());  // This instance does addition
result = addition.MainMethod(a, b);

MyClass composite = new MyClass(new CompositeOf123()); // This instance does addition, subtraction and multiplication
result = composite.MainMethod(a, b);

MyClass exp = new MyClass(new Exponentiation());  // This instance does one version of Method4
result = exp.MainMethod(a, b);
</code>```

These instances of the classes will execute the appropriate strategy (in this case a simple maths equation) when you call the MainMethod method. This gives a much cleaner class structure and separation of concerns.

Body:
It sounds like what you want is the Strategy Pattern. Your methods are your "Strategy" following an interface. I'm going to make your methods return float and take two float as arguments to help illustrate the strategy pattern:

interface MathsStrategy {
    float execute(float a, float b);
}

and you have some classes that implement this interface:

// Method1
class Add implements MathsStrategy {
    public float execute(float a, float b) {
        return a + b;
    }
}

// Method2
class Subtract implements MathsStrategy {
    public float execute(float a, float b) {
        return a - b;
    }
}

// Method3
class Multiply implements MathsStrategy {
    public float execute(float a, float b) {
        return a * b;
    }
}

and you could wrap Method1, Method2, and Method3 together as you use them in a group:

// Composite of Method1, Method2 and Method3
class CompositeOf123 implements MathsStrategy {
    public float execute(float a, float b) {
        return new Add().execute(a, b) + new Subtract().execute(a, b) + new Multiply().execute(a, b);
    }
}

Okay, contrived but hopefully you get the point.

Then we have the methods that vary:

// First example of Method4
class Divide implements MathsStrategy {
    public float execute(float a, float b) {
        return a / b;
    }
}

// Second example of Method4
class Exponentiation implements MathsStrategy {
    public float execute(float a, float b) {
        return a ^ b;
    }
}

Summing up, we have a few methods that we use frequently and want to use in composite and some different implementations that we want to use sometimes so we create different strategies for these.

Now, if we pass these to the class as part of the constructor then we don't really even need the inheritance. It is the behaviour of the method that needs to change, not the class itself. This way we don't need to alter the class to implement a different strategy, we just pass the strategy to the class' constructor when we create an instance of the class.

So your class becomes:

public class MyClass
{
    private MathsStrategy strategy;

    public MyClass(MathsStrategy maths) {
        strategy = maths;
    }

    public float MainMethod(float a, float b) {
        return strategy.execute(a, b);
    }
}

Now you just have to create instances of MyClass that will use the different strategies as required:

float a = 15.0F;
float b = 25.0F;
float result;

MyClass addition = new MyClass(new Add());  // This instance does addition
result = addition.MainMethod(a, b);

MyClass composite = new MyClass(new CompositeOf123()); // This instance does addition, subtraction and multiplication
result = composite.MainMethod(a, b);

MyClass exp = new MyClass(new Exponentiation());  // This instance does one version of Method4
result = exp.MainMethod(a, b);

These instances of the classes will execute the appropriate strategy (in this case a simple maths equation) when you call the MainMethod method. This gives a much cleaner class structure and separation of concerns.


答:
There are a couple of estimating systems out there, and they aren't particularly new.

Function Points

The idea of "function points" is basically all programs have the same 5 features: outputs, inquiries, inputs, internal files, and external interfaces. You have already used a "user registration" scheme, so you have a good idea how one of those looks. As for the "recurring payment system" this is going to be more complicated and you'll probably want to look into an existing API (many folks go with PayPal until paypal screws them, so have a "Plan B" in mind when you go that route).

There are a number of "for money" function point tools, but one free one is here.

COCOMO

COnstructive COst MOdel uses historical data for estimating, but I guess you lack historical data to figure out how much time and effort this project will entail.

Weasel words: COCOMO is not related to the city in Indiana named Kokomo. When the Beach Boys were doing commercials for Delco Electronics (a division of GM now spun off and called Delphi Electronics), they said they liked the name of the town so much they wanted to put it into a song.

These estimating methods need historical data, which most developers won't collect by themselves. One method to do so, for a sole practitioner would be PSP. While that won't help you to put out this particular fire, it will help with your future estimating. Part of the reason that estimating is so hard for people is that they don't keep track of their estimations (thus can't tell where they went wrong, or need to adjust in future projects). And another significant part of why estimating is so hard is that folks have been badly burned by mismanagers playing political games with the developers. Off the cuff estimations are always horribly wrong with the sole exceptions of "we did that one before and it took exactly X to complete."


问:
What's the best Git workflow for working with an open source project with employer-specific changes?
At my current employer, we are using an open-source project hosted on Github as a component of our application. I have been working on this project to both add some features that we need and to integrate it with our build systems. My manager and I are in agreement that we would like to submit as much of our work on this component as is reasonable back to the open-source project. My question is about what the best workflow/technique is to maintain my Git commits in such a way that I can easily seperate out things that make sense to add back to the open-source project - bug fixes and new features that are sufficiently general - from things that are specific to our project, like build locations and application constants.

What I have been doing so far is to maintain a private Git branch where I commit all of my changes, with appropriate granularity. I then use cherry-pick to add the open-sourceable commits to the master branch, and submit those back to Github.

It seems like I ought to be using merge to do this, so that I don't keep creating separate commits with identical contents, but I'm not sure how to do this while excluding the company-specific commits and keeping a reasonable workflow.

For example, I suppose I could commit open-sourceable things on master and company-specific things on the private branch, and then merge master into that branch as needed, leaving the master branch pointing at the commit before the merge, such that I could commit open-sourceable things to it again and then merge again. What seems awkward about this workflow is that I would need to decide in advance for everything I do which branch it belonged on, work on that to what seemed like completion, then commit it and merge before testing. One of the things that I really like about Git is how easy it is to just do whatever you need to make your application work, and then decide later how and where to commit your changes. As far as I can tell, if you're currently on a branch and have some work done, there's no easy way to just submit some of that work to another branch, since changing to that branch would require a clean working directory.

Is what I'm doing a reasonable workflow for long-term contributions? Can anybody recommend a different workflow that might be better, and why it's better?

答:
Depending on the nature of the open-source codebase and what you need to achieve by making changes to it, you might get a lot of mileage by separating your concerns. In your fork of the project, only add things that you intend to contribute back to the original. Add hooks or extension points to allow you to do your company work that will not be shared.

This way you will never have to worry about dividing up or deciding in advance what to share and what not to share. Because you added flexibility to the original project, you could always choose to share some parts of your company work later on.


问:
Novice to node.js, what is the advantage gained using callbacks over events?
I am a novice JavaScripter and have no real knowledge of what goes on inside the V8 engine.

Having said that, I am really enjoying my early forays into the node.js environment but I find that I am constantly using events.EventEmitter() as a means to emit global events so that I can structure my programs to fit a notifier-observer pattern similar to what I would write in say an Objective-C or Python program.

I find myself always doing things like this:

```<code>var events = require('events');

var eventCenter = new events.EventEmitter();

eventCenter.on('init', function() {
    var greeting = 'Hello World!';
    console.log('We're in the init function!);
    eventCenter.emit('secondFunction', greeting);
});

eventCenter.on('secondFunction', function(greeting) {
        console.log('We're in the second function!);
        console.log(greeting);
    eventCenter.emit('nextFunction');
});

eventCenter.on('nextFunction', function {
    /* do stuff */
});

eventCenter.emit('init');
</code>```

So in effect I'm just structuring 'async' node.js code into code that does things in the order I expect, instead I'm kind of "coding backwards" if that makes sense. Would there be any difference in doing this in a callback-heavy manner, either performance-wise or philosophy-wise? Is it better to do the same thing using callbacks instead of events?

答:
I've never used events in NodeJS, but generally what I use clientside JS events for is signaling that something has happened, e.g. an AppointmentBookedEvent, so that different parts of an SPA view can react to that (show it in a timeline, load it in a panel, etc).

But using events to signal a method has completed can be a dangerous road to travel. You can't rely on events to arrive in the same order they were fired, so that could lead to all sorts of randomness...

There's nothing wrong with using events, but there's a certain level of granularity that you shouldn't go under; if you stick to domain-ish events, that's fine. But notifying that methods have finished is too granular.


问:
Why do modern websites still insist on archaic username/password requirements?
I was signing up for a website last night, and once again was greeted with the fact that my username cannot contain certain characters (including spaces), and neither could my password.

Is there a historic reason for this, or is there no particular reason?  Passwords that are phrases have higher entropy and are harder to crack than simple letter/number substitution (see image below):

And on the username front, no spaces?  Really?  It's just a string.  I could understand historic concerns against SQL Injection attacks but modern websites are passed that now (I hope!)

答:
No particular reason at all. It's as arbitrary as "your password may not be longer than 8 characters". It's programmers or product owners that don't know what they are doing.

There can be some legacy reason for this, when the authentication system is linked to some credential system that has had certain limitations for historical reasons (something like a really old crypt() implementation skipping all password input after the 8th character as mentioned here), but given the vast majority of (web) applications is built on top of custom authentication systems and credentials are stored in relational databases, this really shouldn't be an issue nowadays.


答:
Besides the historical reason of disk space (yes, there was a time when disk space mattered!), there is always the encoding/escaping problem. When facing with special characters and spaces you always have to make sure that they are properly escaped (to prevent injection attacks) and encoded (to ensure you password actually works in the end). Nowadays, tool support for this is good; best practices are known and wide spread. Back in the days, excluding all special characters made life tremendously easier. Note that "easier" almost always means "less secure"...

In the end, there are two reasons for such restrictions in a modern application:

The app depends on some legacy system that has this restrictions.

Someone chose the "easy way out".

It sums up to: Someone didn't care enough for security. Why else would bank still work with online-banking systems that have 4 digits(!) fixed-length passwords?

Title: Why do modern websites still insist on archaic username/password requirements?

Body:
I was signing up for a website last night, and once again was greeted with the fact that my username cannot contain certain characters (including spaces), and neither could my password.

Is there a historic reason for this, or is there no particular reason?  Passwords that are phrases have higher entropy and are harder to crack than simple letter/number substitution (see image below):

And on the username front, no spaces?  Really?  It's just a string.  I could understand historic concerns against SQL Injection attacks but modern websites are passed that now (I hope!)


答:
Something you might explore is usage of the events outside the object which is emitting them. In your example, eventCenter appears to both emit and handle its own events. Consider how the structure of your application might change if other objects begin to handle the events.

So, eventCenter might emit "init", which other objects could then handle to do their startup code, etc.

Title: Novice to node.js, what is the advantage gained using callbacks over events?

Body:
I am a novice JavaScripter and have no real knowledge of what goes on inside the V8 engine.

Having said that, I am really enjoying my early forays into the node.js environment but I find that I am constantly using events.EventEmitter() as a means to emit global events so that I can structure my programs to fit a notifier-observer pattern similar to what I would write in say an Objective-C or Python program.

I find myself always doing things like this:

```<code>var events = require('events');

var eventCenter = new events.EventEmitter();

eventCenter.on('init', function() {
    var greeting = 'Hello World!';
    console.log('We're in the init function!);
    eventCenter.emit('secondFunction', greeting);
});

eventCenter.on('secondFunction', function(greeting) {
        console.log('We're in the second function!);
        console.log(greeting);
    eventCenter.emit('nextFunction');
});

eventCenter.on('nextFunction', function {
    /* do stuff */
});

eventCenter.emit('init');
</code>```

So in effect I'm just structuring 'async' node.js code into code that does things in the order I expect, instead I'm kind of "coding backwards" if that makes sense. Would there be any difference in doing this in a callback-heavy manner, either performance-wise or philosophy-wise? Is it better to do the same thing using callbacks instead of events?


问:
What is the use of Association, Aggregation and Composition?
I have gone through lots of theories about what is encapsulation and the three techniques of implementing it, which are Association, Aggregation and Composition.

What I found is:

Encapsulation

Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods. If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding.

Encapsulation can be described as a protective barrier that prevents the code and data being randomly accessed by other code defined outside the class. Access to the data and code is tightly controlled by an interface.

The main benefit of encapsulation is the ability to modify our implemented code without breaking the code of others who use our code. With this feature Encapsulation gives maintainability, flexibility and extensibility to our code.

Association

Association is a relationship where all object have their own lifecycle and there is no owner. Let’s take an example of Teacher and Student. Multiple students can associate with a single teacher and a single student can associate with multiple teachers, but there is no ownership between the objects and both have their own lifecycle. Both can create and delete independently.

Aggregation

Aggregation is a specialized form of Association where all objects have their own lifecycle, but there is ownership and a child object cannot belong to another parent object. Let’s take an example of a Department and teacher. A single teacher cannot belong to multiple departments, but if we delete the department the teacher object will not be destroyed. We can think of it as a “has-a” relationship.

Composition

Composition is again a specialized form of Aggregation and we can call this as a “death” relationship. It is a strong type of Aggregation. Child object does not have their lifecycle and if parent object deletes all child object will also be deleted. Let’s take again an example of relationship between House and rooms. House can contain multiple rooms but there is no independent life of a room and any room cannot belong to two different houses. If we delete the house, the room will automatically be deleted.

The question is:

Now these all are real world examples. I am looking for some description about how to use these techniques in actual class code. I mean what is the point for using three different techniques for encapsulation, How these techniques could be implemented and How to choose which technique is applicable at time.

答:
Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods. If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding.

```<code>    public class Test{

    private String name;

       private int age;

       public int getAge(){
          return age;
       }

       public String getName(){
          return name;
       }
    }
</code>```

Refer this question also.

Association indicates the relationship between objects.
eg: Computer uses keyboard as input device.

An association is used when one object wants another object to perform a service for it.

Aggregation is a special case of association. A directional association between objects. When an object ‘has-a’ another object, then you have got an aggregation between them.

eg: Room has a table, but the table can exist without the room.

```<code>    class Room {

      private Table table;

      void setTable(Table table) {
        this.table = table;
      }

    }
</code>```

Composition is a special case of aggregation.
Composition is more restrictive. When there is a composition between two objects, the composed object cannot exist without the other object. This restriction is not there in aggregation.
eg: rooms in a house, which cannot exist after the lifetime of the house.

```<code>    class House {

      private  Room room;

      House(Room roomSpecs) {
        room = new Room(roomSpecs);
      }

    }
</code>```

Composition is a design technique to implement has-a relationship in classes, either by Inheritance or object Composition for code reuse.

One of the best practice in Java programming is to use composition over inheritance

ContentLicense: CC BY-SA 4.0

Body:
Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods. If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding.

    public class Test{

    private String name;

       private int age;

       public int getAge(){
          return age;
       }

       public String getName(){
          return name;
       }
    }

Refer this question also.

Association indicates the relationship between objects.
eg: Computer uses keyboard as input device.

An association is used when one object wants another object to perform a service for it.

Aggregation is a special case of association. A directional association between objects. When an object ‘has-a’ another object, then you have got an aggregation between them.

eg: Room has a table, but the table can exist without the room.

    class Room {

      private Table table;

      void setTable(Table table) {
        this.table = table;
      }

    }

Composition is a special case of aggregation.
Composition is more restrictive. When there is a composition between two objects, the composed object cannot exist without the other object. This restriction is not there in aggregation.
eg: rooms in a house, which cannot exist after the lifetime of the house.

    class House {

      private  Room room;

      House(Room roomSpecs) {
        room = new Room(roomSpecs);
      }

    }

Composition is a design technique to implement has-a relationship in classes, either by Inheritance or object Composition for code reuse.

One of the best practice in Java programming is to use composition over inheritance


问:
Why don't xUnit frameworks allow tests to run in parallel?
Do you know of any xUnit framework that allows to run tests in parallel, to make use of multiple cores in today's machine?

If none (or so few) of them does it, maybe there is a reason...  Is it that tests are usually so quick that people simply don't feel the need to paralellize them?

Is there something deeper that precludes distributing (at least some of) the tests over multiple threads?

答:
MBUnit is able to run tests in parallel simply by specifying some assembly level attributes.

[assembly: DegreeOfParallelism(6)]

[assembly: Parallelizable(TestScope.All)]

I've been using that project to run selenium tests in parallel quite successfully for some time. Unfortunately the project is not very much alive anymore.

xUnit 2.0 should also support parallel unit testsing but i haven't tried it out yet.


答: I don't think it matters too much - no matter what we allow end user's - they will still end-up using passwords like 123456 and password.</p>