问:
Dependency ordering algorithm of a compiler
Let's say, hypothetically, I'm writing a Java compiler. And we assume that in my case a class can't be fully compiled until all signatures of dependencies (imports and other used classes) are known. Because I don't want to keep the source code and AST of all classes in memory at the same time, I'll need an algorithm to manage those dependencies and process them all in the right order.

What would be a good algorithm for ordering all dependencies?
That:

is not recursive

does not keep all source code and/or ast nodes in memory

is linear in both space and time

can handle cyclical dependencies

Or maybe more general, how is this normally done?

My approach looks like the following:

```<code>abstract class Compiler {

    TypeSystem ts;

    Type compile(String className) {

        if (ts.containsType(className)) {
            return ts.getType(className);
        }

        // Create skeleton type for this class:
        Type type = ts.createType(className);

        // Parse the class file:
        Node ast = parse(className);

        // Create signature:
        for (Node attribute : ast.findAll("AttributeDeclaration")) {

            // Get the text value of the name of the attribute:
            String attributeName = attribute.find("Identifier").text();

            // Get the text value of the type of the attribute:
            String attributeTypeName = attribute.find("Type").text();

            // Call compile recursive!
            Type attributeType = compile(attributeTypeName);

            type.createAttribute(attributeName, attributeType);
        }

        return type;
    }

    abstract Node parse(String className); // This method can find the file by class name.
}
</code>```

For sake of simplicity, does this code only process attributes and simple structs.
Note that this algorithm is recursive!

答:
To compile a source file, you do not need to have compiled all dependencies before it. However, you do need something to link against: a kind of interface or header. In languages like Java, this is fairly simple since all user defined types have reference semantics. The structure and implementation of a type do not matter, only that it is named. Therefore, you can hoist all type names that occur in a compilation unit and its dependencies to the “top”.

E.g. assume that I have two classes in two separate files:

Foo:

```<code>class Foo {
  public void frobnicate(Bar b) {
    if (rand) b.frobnicate(this);
  }
}
</code>```

Bar:

```<code>class Bar {
  public void frobnicate(Foo f) {
    if (rand) f.frobnicate(this);
  }
}
</code>```

The type and definition of frobnicate is mutually recursive. This can be compiled by doing an initial pass that extracts the interface of these classes. The interface is then referenced when compiling the actual implementations in a second pass. Although this strategy does multiple passes, it's still linear, and it need not keep the whole AST in memory – only the type signatures.

Header:

```<code>// predeclare type names
class Foo;
class Bar;

// predeclare available operations
class Foo {
  public void frobnicate(Bar); // type Bar is known
}
class Bar {
  public void frobnicate(Foo); // type Foo is known
}
</code>```

Foo:

```<code>#include Header
// implement the pre-declared function
void Foo::frobnicate(Bar b) {
  if (rand) b.frobnicate(this); // method Bar::frobnicate(Foo) is known
}
</code>```

Bar:

```<code>#include Header
void Bar::frobnicate(Foo f) {
  if (rand) f.frobnicate(this);  // method Foo::frobnicate(Bar) is known
}
</code>```

In languages such as C or C++, these dependencies have to be resolved manually using such predeclarations. C was specifically designed around space-efficient single-pass compilation, though this trades in compilation speed since all header dependencies will be re-parsed again for each compilation unit.

This pre-declaration strategy only works for user-defined types that have reference semantics. If a type has value semantics, it must be completely defined before it can be used. Switching to C++, this pre-declared Incomplete type can be used in a Complete type since the size of a pointer is known:

```<code>struct Incomplete;

struct Complete {
  Incomplete* thing;
};
</code>```

However, embedding an incomplete type without a pointer would not work; the embedded type would have to be completely defined first.

Body:
To compile a source file, you do not need to have compiled all dependencies before it. However, you do need something to link against: a kind of interface or header. In languages like Java, this is fairly simple since all user defined types have reference semantics. The structure and implementation of a type do not matter, only that it is named. Therefore, you can hoist all type names that occur in a compilation unit and its dependencies to the “top”.

E.g. assume that I have two classes in two separate files:

Foo:

class Foo {
  public void frobnicate(Bar b) {
    if (rand) b.frobnicate(this);
  }
}

Bar:

class Bar {
  public void frobnicate(Foo f) {
    if (rand) f.frobnicate(this);
  }
}

The type and definition of frobnicate is mutually recursive. This can be compiled by doing an initial pass that extracts the interface of these classes. The interface is then referenced when compiling the actual implementations in a second pass. Although this strategy does multiple passes, it's still linear, and it need not keep the whole AST in memory – only the type signatures.

Header:

// predeclare type names
class Foo;
class Bar;

// predeclare available operations
class Foo {
  public void frobnicate(Bar); // type Bar is known
}
class Bar {
  public void frobnicate(Foo); // type Foo is known
}

Foo:

#include Header
// implement the pre-declared function
void Foo::frobnicate(Bar b) {
  if (rand) b.frobnicate(this); // method Bar::frobnicate(Foo) is known
}

Bar:

#include Header
void Bar::frobnicate(Foo f) {
  if (rand) f.frobnicate(this);  // method Foo::frobnicate(Bar) is known
}

In languages such as C or C++, these dependencies have to be resolved manually using such predeclarations. C was specifically designed around space-efficient single-pass compilation, though this trades in compilation speed since all header dependencies will be re-parsed again for each compilation unit.

This pre-declaration strategy only works for user-defined types that have reference semantics. If a type has value semantics, it must be completely defined before it can be used. Switching to C++, this pre-declared Incomplete type can be used in a Complete type since the size of a pointer is known:

struct Incomplete;

struct Complete {
  Incomplete* thing;
};

However, embedding an incomplete type without a pointer would not work; the embedded type would have to be completely defined first.


问:
Why do build tools use a scripting language different than underlying programming language?
I've recently been using some build tools for a Nodejs project at work when I realized that most languages' main build tool/system use a different language than the underlying programming language itself.

For example, make does not use C or C++ to write scripts and ant (nor Maven) doesn't use Java as their language for scripting.

Newer languages like Ruby do use the same language for build tools like rake, which makes sense to me. But why hasn't this always been the case? What't the advantage to having a build tool that uses a different language from the underlying language?

答:
Let’s give you a real world example.

About 15 years ago I worked on porting a large system written in C from Unix to Windows, it was about 3 million lines of code.   To give you some idea of scale, it took over 24hr to compile on some of our unix systems (RS6000), windows could compile the system in about 4hrs.

(We also had 2 million line of code in our own interpreted language, but decided not to use our language for the build systems as it was never designed for file processing.  Also we needed a build system to compile the C code that implemented our language.)

At the time the build system was written in a mix of shell scripts and make files, these were not portable to windows – therefore we decided to write our own build system.

We could have used C, however we decided to use python, there was few reasons.   (We also rewrote our source code control system in python at the same time, this is was very intergraded with the build system, so object files for checked in modules could be shared by developers.)

Most of our code could be built with a few simple rules (only a few thousand lines of python for all platforms, Windows, VMS, and 6 versions of Unix) that were drived from the naming conventions of the files.

At the time RegEx was not very standard between C systems on different platforms, Python had built in RegEx.

A few modules needed custom build steps, Python allowed class files to be loaded dynamically.   We allowed a custom class to be used to build a module (lib), based on having the python file with a magic name in the folder.   This was the killer reason to use python.

We considered Java, but it was not shipping on all the platforms at that point.

(The UI for our source code control system used a web browser as that was portable across all the platform.   This was 6 months before we had a internet connection.     We had to download the browser over X25!)

ContentLicense: CC BY-SA 3.0


问:
Is this taking DRY too far?
A colleague and I are working together on a Meteor app.

One of us thinks that the following code in two places should be wrapped in a function to avoid duplication -- the other thinks that it leads to needless indirection/complexity.

I won't tell you which is me, because I would like the answers to be unbiased :).

We disagree on this particular point and would like some help coming to a conclusion which is beneficial to our codebase.

One file has:

```<code>Email.send({
    from: sender,
    to: recipient,
    subject: "Message from our company",
    message: message
});
</code>```

Another file has the same code:

```<code>Email.send({
    from: sender,
    to: recipient,
    subject: "Message from our company",
    message: message
});
</code>```

Please be keep your comments respectful.

Question:
Should this code be abstracted out into a function?

Clarification/Edit: The "Message from our company" is the same in both Email.send calls.

答:
If its just these two places in the code, I don't think it makes much difference.

But in most projects I've worked on, sending mail is rarely just sending mail.  Often it also involves adding headers, merging with templates, generating unique id's, adding unsubscribe links, and logging the message to the database.  In those cases, all attempts to send mail are piped into a single function that handles those tasks.

So, if you expect the system to be sending email from more places, or if you expect to eventually need to 'fancy up' the emails that get sent, yes, I'd wrap it in its own function.

Title: Is this taking DRY too far?


问:
Storing PageViews Count Data in MongoDB
I would like to ask for feedback for some programming logic concept & ideas. I am building a site where i would like to keep track on how many pageviews a page has daily. I have thought of 2 ways to do it, would like to get feedback from fellow experts on which approach you would recommend.

Approach 1

Keep a field in the document called pageviews. On every page load, i would increment this value by 1. This seems to be the most naive way of doing it. However, i am concern on the database performance. Imagine i have 10000 concurrent users on that page, or a hacker is auto-refreshing this page every millisecond.

Approach 2

Create a file (maybe .txt). And push data into it every pageview. I can tabulate the pageviews based on the data stored in the txt file. Using this approach, there will be no database load, will this be a better approach?

Appreciate more expert views on how you would go about doing this.

答: Your web server probably already keeps an access log somewhere, and so has solved the problem of repeated editing the same file from multiple sources efficiently (e.g. Apache access log, nginx access log). You should be able to use that instead of approach #2, in which the only question is whether approach #1 can be made faster (unlikely) or could record more useful data than your web server does (maybe). There are also third-party page view trackers, such as Google Analytics and Statcounter. I'd try any of those options before attempting to roll your own solution.</p>

Title: Storing PageViews Count Data in MongoDB


问:
anonymous/ghost users in database
This questions is related to this one : anonymous checkout

My company bought a CRM software and I am concerned by the way it stores customers' information.

The website allows anonymous users to have a shopping cart and add products. The website asks them to log in once they want to pay.

The thing is: anonymous customers are stored in the same table than authenticated customers, the only difference is: their email, password, saltkey is empty. The only information we keep is the IP address; when the user logs in we can convert this account into a real one. This table also contains a 'isAdmin' flag.

EDIT: indeed, an asp.net authentication cookie is created to maintain user session.

The question I have: is it a ok practice or is there a possible security issue with this ?

More information: we have 20k 'ghost' users in the database, a maintenance system is available to clean useless records after some time.

EDIT2: my main concerns are :

anonymous, authenticated and admin users are in the same table

Anonymous users are considered as authenticated users by asp.net, the CRM has its own way to detect if they are really authenticated.

答: So once the ghost user is authenticated, is the ghost record removed or modified? Either way I see no risk here as no personal information is stored until the user is wanting to check out. Amazon has similar functionality if I'm understanding the situation correctly. </p>

Title: anonymous/ghost users in database


答:
You always have to be careful not to confuse or intermingle Authorization and Authentication. Customers are accounts who can buy stuff on your website and not necessarily ones who can login.

The security risk can come into play if for some reason your code somehow could come up with a customer record for an anonymous customer and grant privileges that require a login.

If your app really needs anonymous customers to have a customer table record then consider having a user table to handle all the login stuff.

Title: anonymous/ghost users in database

Body:
This questions is related to this one : anonymous checkout

My company bought a CRM software and I am concerned by the way it stores customers' information.

The website allows anonymous users to have a shopping cart and add products. The website asks them to log in once they want to pay.

The thing is: anonymous customers are stored in the same table than authenticated customers, the only difference is: their email, password, saltkey is empty. The only information we keep is the IP address; when the user logs in we can convert this account into a real one. This table also contains a 'isAdmin' flag.

EDIT: indeed, an asp.net authentication cookie is created to maintain user session.

The question I have: is it a ok practice or is there a possible security issue with this ?

More information: we have 20k 'ghost' users in the database, a maintenance system is available to clean useless records after some time.

EDIT2: my main concerns are :

anonymous, authenticated and admin users are in the same table

Anonymous users are considered as authenticated users by asp.net, the CRM has its own way to detect if they are really authenticated.


问:
OAuth2 ROPC vs Basic Auth for public REST APIs?
The specific use case I'm interested in here is authenticating REST clients against publicly-available server endpoints (such as a public REST API).

The simplest solution here is Basic Auth. But I often hear OAuth2 touted as a superior auth solution in almost all circumstances.

The thing is, the only OAuth2 grant type that is feasible for a REST client authenticating against a REST server is Resource Owner Password Credentials (ROPC), because Code Grants and Implicit Grants require a UI/webpage (hosted by the Auth Server) for the user to login to and manually authorize the client app.

The way ROPC works is, by sending the resource owner's username/password, and the client ID as query string params?!? This is even less secure (IMHO) then Basic Auth, which at least base-64 encodes the credentials and sends them inside a header which can be encrypted by TLS!

So I ask: in the context of public REST APIs, is OAuth2 ROPC really any better than Basic Auth? What is more secure than OAuth2 ROPC?

Update

I just read this excellent article which explains Amazon's non-OAuth2 based REST security for AWS. It is essentially a private key-based solution where hashes of each REST request are generated and sent as sidecars along-side the normal (un-encrypted) request. Only the client and the server know the private key, so when the server receives the request (again, containing the normal request + the hashed request), the server looks up the client's private key, applies the same hash to the normal request, and then compares the two hashes.

This sounds way more complicated, complex and secure than OAuth2's ROPC! Unless I'm missing something major here, OAuth2 ROPC is just sending client_id, username and password as query string params...totally and utterly unsecure! This HMAC/hashed-based solution seems to be much more impressive and secure.

The thing is, even the author of that article goes on to say:

You [will] also slowly realize and accept that at some point you will have to implement OAuth...

Ba-ba-bwhat?!?! If OAuth2 is less secure than this clever HMAC/hash-based solution, why does the author of this article feel OAuth needs to be embraced at some point. I'm so confused.

答:
It's either secure or not secure. No more, no less. Having base64 doesn't make Basic Auth (or anything) more secure.

There's nothing wrong in sending anything unencrypted if it's using encrypted pipe like Https.

OAuth has more features, use it if you need it. For anything else, e.g. banking, using basic challenge-response is fine and secure.


问:
How to keep documentation up to date and accessible
The problem: Documentation is in code in the form of docs, its in wiki websites, its written down on notes, in diagrams and issue management systems.

When documentation is so spread out, how does one manage to keep it up to date and relevant?

答:
What you need to do is develop a single source of information.

Depending on the tools and processes that you use, you probably don't need it in all of those places. I'm not sure what your requirements for documentation are, but that will likely drive what tool you use as the single point of reference. Minimally, you should start collating everything electronically and make it generally available to the team - get it out of physical paper and into electronic sources that are searchable, indexed, and backed up.

From there, decide on the best methods of capturing information for your needs.


答:
Alas, few organizations actually succeed at curating and then keeping documentation both accessible and up-to-date.

I am a contract engineer who has worked for more than 120 distinct companies, some of which you know of.

Large (50,000+ employee) companies might have effectively no standards or systems for documentation.  Or they have an onerous, one-size-fits-all system.  Neither works very well in practice.  The former because it just doesn't get done.  The latter because the difficulty of providing useful writing is high and updating it is even more painful.

Small companies (less than 50 employees), on average, do a much better job of requesting and maintaining internal and external documentation for computer software.  I note that the best documentation is the internal flavor written by the engineer and inserted into the source code at the time the code is written.  Automatic extraction tools nicely encourage this practice being followed.

One- or two-person projects also usually do quite a good job of keeping documentation together with the source code and keeping it relevant.

Open source software perhaps have the best functional examples.  Look at the Linux kernel:  The architectural and how-to information is part of the git repository and appears in the Documentation/ subfolder at the root of the project.

Title: How to keep documentation up to date and accessible

Body:
The problem: Documentation is in code in the form of docs, its in wiki websites, its written down on notes, in diagrams and issue management systems.

When documentation is so spread out, how does one manage to keep it up to date and relevant?


问:
How to suggest a specification to w3c?
As the title says, how can someone suggest a specification to the World Wide Web Consortium (w3c)? Is it even possible? Can someone at least suggest the w3c to have a discussion on the specifications suggested?
Or is it done by the voting system, as in Area 51 of StackExchange?

I did some googling but couldn't find anything helpful.

答:
You'd start a W3C community group.

The path from there is to build support so that it gets adopted by a Working Group. Working Groups are harder to join since they require that you be either an employee of one of the members of the W3C or an invited expert.

Getting something to a standard is a fairly lengthy process.

Title: How to suggest a specification to w3c?


答:
A very good place to start these days is at https://discourse.wicg.io/. That’s the Web discussion forum for the Web Platform Incubator Community Group (WICG), a W3C Community Group (CG).

The WICG is open to participation from absolutely anyone, and was created through collaboration with all major browser-engine projects (Webkit/Safari, Gecko/Firefox, Edge/MSIE, Blink/Chrome) expressly for the purpose of providing everybody with “a lightweight venue for proposing and discussing new Web-platform features”.

The WICG just started recently but has already published Contributing New Proposals guidelines.

Here from those guidelines are the key steps it outlines for the development of a new feature:

State the problem

Join the group

Evaluation

Use cases

Advocate

Specify it

(Bonus points) Implementation

That outline’s based on looking at previous successes in getting new features into the platform (e.g., the responsive-images <picture> element and srcset attribute) and sort of reverse-engineering the steps that led to those successes, documenting them, and optimizing for them.

As somebody who’s been closely involved in work on the platform for a lot of years now, I cannot overstate the importance of step #1 from that outline, State the problem.

The most progress gets made with the least amount of acrimony when people show up with very clear problem descriptions first, and ask others for ideas about how to solve the problem—as opposed to, say, showing up with a solution already in hand themselves, and being already over-invested in their own idea of what the right solution is.

There’s lots of positive energy behind the WICG and it’d be great to get more people involved in it.

Title: How to suggest a specification to w3c?

Body:
As the title says, how can someone suggest a specification to the World Wide Web Consortium (w3c)? Is it even possible? Can someone at least suggest the w3c to have a discussion on the specifications suggested?
Or is it done by the voting system, as in Area 51 of StackExchange?

I did some googling but couldn't find anything helpful.


问:
Securing service calls
I have a ServiceCallContext object that must be passed in as the first parameter of any service call. I would like to put a User object on the context object but I know I can't force the caller to send back the User object they received from the service and I can't prevent them from filling that in with any information they like.

So as I understand it, I would need to use a security token (via something like OAuth) to authenticate them and would always need to look up any User information I need on the service side after authentication rather than putting it on the context object.

However, I know it's common to make a hash for a data file in order to verify that its contents haven't been tampered with. Would it be reasonable to do this for user information I put on a context object so that I don't have to make a call to the persistence layer for every service call? What are the risks of doing it that way?

答:
Once you perform the expensive function (authenticating a user) you would setup a token that is stored in a much faster, and less expensive place (ie- Memcache).

That way you always re-authenticate the user on every request and you're able to automatically force a full re-authentication by flushing the memory for any users with a current session.

You could also store all the user's data that you will require on every service call in Memcache (or similar) for a fast retrieval.

Title: Securing service calls


答:
I believe you are misinformed about the encryption around GET variables in a URL

The only people that can view the GET variables in a request are the original computer and the receiving server (link).

Only the DNS lookup based on the domain the HTTPS request is sent to is not encrypted.  Everything else, the ports, the GET variables, the resource ID, is encrypted.

The only caveat to that is that the receiving server may log out the full request path, but you are in control of that so you can protect that data however you see fit.

Title: OAuth2 ROPC vs Basic Auth for public REST APIs?

Body:
The specific use case I'm interested in here is authenticating REST clients against publicly-available server endpoints (such as a public REST API).

The simplest solution here is Basic Auth. But I often hear OAuth2 touted as a superior auth solution in almost all circumstances.

The thing is, the only OAuth2 grant type that is feasible for a REST client authenticating against a REST server is Resource Owner Password Credentials (ROPC), because Code Grants and Implicit Grants require a UI/webpage (hosted by the Auth Server) for the user to login to and manually authorize the client app.

The way ROPC works is, by sending the resource owner's username/password, and the client ID as query string params?!? This is even less secure (IMHO) then Basic Auth, which at least base-64 encodes the credentials and sends them inside a header which can be encrypted by TLS!

So I ask: in the context of public REST APIs, is OAuth2 ROPC really any better than Basic Auth? What is more secure than OAuth2 ROPC?

Update

I just read this excellent article which explains Amazon's non-OAuth2 based REST security for AWS. It is essentially a private key-based solution where hashes of each REST request are generated and sent as sidecars along-side the normal (un-encrypted) request. Only the client and the server know the private key, so when the server receives the request (again, containing the normal request + the hashed request), the server looks up the client's private key, applies the same hash to the normal request, and then compares the two hashes.

This sounds way more complicated, complex and secure than OAuth2's ROPC! Unless I'm missing something major here, OAuth2 ROPC is just sending client_id, username and password as query string params...totally and utterly unsecure! This HMAC/hashed-based solution seems to be much more impressive and secure.

The thing is, even the author of that article goes on to say:

You [will] also slowly realize and accept that at some point you will have to implement OAuth...

Ba-ba-bwhat?!?! If OAuth2 is less secure than this clever HMAC/hash-based solution, why does the author of this article feel OAuth needs to be embraced at some point. I'm so confused.


问:
PHP MySQL unique user data
I'm trying to create a php website that users log into and they can submit data to a MySQL database. How do I make it so the users can only see data they've submitted and not everyone else's data?
Should I use:

```<code>Echo $_sessions[user][piece of data]
</code>```

Am I on the right track or is there an easier way to go about this? Is there a template or tutorial that shows how this is accomplished? It seems all the demos on the web show you how to log in then stop after that point. I've been researching for a while and have not come across a way to implement this.

答:
The solution is to have two tables in your database.  The first table, "user", can have two columns, "user-id" and "name".  The second table, "data", can then have two columns, "submitted-by" and "info".

Whenever a user submits some new data, you update the "data" table with the information and the user-id of the user.  This way, when the user wants to read all the data they have submitted, you can simply limit the query to only return records with their user-id

Title: PHP MySQL unique user data


问:
Is there anything wrong with putting comments in an HTML closing tag?
I often write comments like this

```<code><div id="wrapper">
...
</div> <!-- id="wrapper" -->
</code>```

But what if I wrote them like this?

```<code><div id="wrapper">
...
</div id="wrapper">
</code>```

At first it seems dangerous to put an id attribute that has the same value on another tag, but then, doesn't the browser throw out that information? As far as I can see Chrome and Firefox both disregard any "attributes" in the closing tag.

Also seems unfortunate that it's not a real comment. It wont be parsed semantically as a comment. But I don't think anyone is using that space for anything else, right? Closing tags only close, right?

Is there any reason not to do this other than it's not a standard?

答:
Along with the section of the HTML Standard that defines the syntax for a valid end tag, as cited in another answer to this question, the HTML Standard also defines the presence of attributes in end tags as a parse error that error-reporting parsers should report.

See the beginning of the Tokenization section of the HTML parsing algorithm, which says:

When an end tag token is emitted with attributes, that is a parse
  error

(Note that the word emitted here means in the product of the tokenization phase, which emits tokens that are then consumed by the Tree Construction phase.)

Also in the spirit of having a record of information available at point of use here at StackOverflow when possible—rather than requiring users to follow links to the get the information—here are the details from the section of the HTML Standard that defines the syntax for valid end tag:

The first character of an end tag must be a U+003C LESS-THAN SIGN character (<).

The second character of an end tag must be a U+002F SOLIDUS character (/).

The next few characters of an end tag must be the element's tag name.

After the tag name, there may be one or more space characters.

Finally, end tags must be closed by a U+003E GREATER-THAN SIGN character (>).

Somewhat interestingly, that allows end tags like  that contain whitespace, and also things like this:

```<code>  <a href=foo>prefix-</a
  ><i>something following w/o space between, on a separate line for readability</i>
</code>```

Body:
Along with the section of the HTML Standard that defines the syntax for a valid end tag, as cited in another answer to this question, the HTML Standard also defines the presence of attributes in end tags as a parse error that error-reporting parsers should report.

See the beginning of the Tokenization section of the HTML parsing algorithm, which says:

When an end tag token is emitted with attributes, that is a parse
  error

(Note that the word emitted here means in the product of the tokenization phase, which emits tokens that are then consumed by the Tree Construction phase.)

Also in the spirit of having a record of information available at point of use here at StackOverflow when possible—rather than requiring users to follow links to the get the information—here are the details from the section of the HTML Standard that defines the syntax for valid end tag:

The first character of an end tag must be a U+003C LESS-THAN SIGN character (<).

The second character of an end tag must be a U+002F SOLIDUS character (/).

The next few characters of an end tag must be the element's tag name.

After the tag name, there may be one or more space characters.

Finally, end tags must be closed by a U+003E GREATER-THAN SIGN character (>).

Somewhat interestingly, that allows end tags like </body       > that contain whitespace, and also things like this:

  <a href=foo>prefix-</a
  ><i>something following w/o space between, on a separate line for readability</i>


问:
Inheritance when following the Repository Pattern in PHP
I am trying to build a PHP application using the Repository Pattern but I'm not sure how I should implement the save method.

I have an abstract class called ItemRepository which have the following method:

```<code>abstract class ItemRepository
{
    public function save(Item $item);
}
</code>```

Where Item also is an abstract class.

Now I want to implement the class MovieRepository which extends ItemRepository. Here I want to save instances of the Movie class which extends Item.

Though doing it like this in PHP

```<code>// MovieRepository.php
class MovieRepository extends ItemRepository
{
    public function save(Movie $movie)
    {
        ...
    }
}
</code>```

gives the following error

Declaration of MovieRepository::save() should be compatible with ItemRepository::save(Item $item)

What is the right way to do this?

答:
You might benefit from studying Doctrine2.  While it also uses the "Repository Pattern", it also uses the "Data Mapper Pattern".

The following is an example of using the entity manager:

```<code>/* $movieRepository = MovieRepository -> extends EntityRepository -> implements ObjectRepository */
if (null !== $movie = $movieRepository->findOneBy(array('name' => 'Mad Max'))) {
    $movie = new Movie();
    $movie->setName('Mad Max');

    /* $entityManager = EntityManager -> implements ObjectManager */
    $entityManager->persist($movie);
}

$movie->setViews($movie->getViews() + 1);

$entityManager->flush();
</code>```

Notice here that Doctrine2 defines two major classes (one abstract).

```<code>abstract class EntityRepository implements ObjectRepository
{
    ...
}

class EntityManager implements ObjectManager
{
    ...
}
</code>```

Traditionally the repository is only used to make queries, i.e. for selections, rarely updates or inserts.  ObjectRepository interface defines common select methods:

find($id)

findBy(array $criteria)

findOneBy(array $criteria)

The entity manager however, has the methods pertaining to persistance:

persist($entity)

flush($entity = null)

The entity manager never requires a specific type of entity besides the "range" of classes registered as being mapped to it's database.

If you want to create your own persistence library, you could use the Doctrine\Common\Persistance interfaces to help you design it.

ObjectRepository

ObjectManager

A reason you might choose to persist entities and flush all at once, is to create a coherent transaction which "finalizes" the process.  Opposed to "saving" each entity individually during the process, which would gradually build up the amount of IO in your application, effecting performance.

TL;DR

Incorporate the Data Mapper Pattern in your design, and migrate the persistence away from your repositories, and instead encapsulate it into a single manager for your database.  Then limit the repository to selection queries.

Body:
You might benefit from studying Doctrine2.  While it also uses the "Repository Pattern", it also uses the "Data Mapper Pattern".

The following is an example of using the entity manager:

/* $movieRepository = MovieRepository -> extends EntityRepository -> implements ObjectRepository */
if (null !== $movie = $movieRepository->findOneBy(array('name' => 'Mad Max'))) {
    $movie = new Movie();
    $movie->setName('Mad Max');

    /* $entityManager = EntityManager -> implements ObjectManager */
    $entityManager->persist($movie);
}

$movie->setViews($movie->getViews() + 1);

$entityManager->flush();

Notice here that Doctrine2 defines two major classes (one abstract).

abstract class EntityRepository implements ObjectRepository
{
    ...
}

class EntityManager implements ObjectManager
{
    ...
}

Traditionally the repository is only used to make queries, i.e. for selections, rarely updates or inserts.  ObjectRepository interface defines common select methods:

find($id)

findBy(array $criteria)

findOneBy(array $criteria)

The entity manager however, has the methods pertaining to persistance:

persist($entity)

flush($entity = null)

The entity manager never requires a specific type of entity besides the "range" of classes registered as being mapped to it's database.

If you want to create your own persistence library, you could use the Doctrine\Common\Persistance interfaces to help you design it.

ObjectRepository

ObjectManager

A reason you might choose to persist entities and flush all at once, is to create a coherent transaction which "finalizes" the process.  Opposed to "saving" each entity individually during the process, which would gradually build up the amount of IO in your application, effecting performance.

TL;DR

Incorporate the Data Mapper Pattern in your design, and migrate the persistence away from your repositories, and instead encapsulate it into a single manager for your database.  Then limit the repository to selection queries.


问:
Use TFS to track bugs from Production Support
I have just moved to a new company and they are using TFS 2010 (2012 in a couple of months) as their version control system and recently started to use it as a work tracking system for the developers.

However, there doesn't seem to be a bug tracking system for use by people outside development & test.  Production support are getting reports of issues, fixing them on the fly and reporting back to their users at the moment.  This needs to be changed but I don't really want to have a sperate system for tracking bugs and tracking dev work.

Is there a way that I can create a very light weight way of entering bugs into TFS similar to the way that FogBugz does?  Logging into TFS to fill out a bug report seems to be a lot heavier and you have to associate it with a particular application.  Support may be able to do this but I want to be able to triage the item and potentially change the association to something other than an application.

I have used FogBugz in the past and when adding a bug, you can add a much/little as you want to the item so it is at least recorded and later you can bounce it back to get more information when you come to triage the ticket.

答:
This Microsoft blog post describes planned improvements in TFS that should help support lower-overhead:

New work item form that's easier on the eyes and includes discussion and mention options, similar to facebook and twitter.

Custom fields

Improved Kanban support, eg quick add tasks on a work item.

Also mentions dashboards and metrics.

ContentLicense: CC BY-SA 4.0


问:
Uncaught TypeError: Cannot read property 'add' of null
I am novice developer.

While development is going on, we come across different error issues. However for the novice of programming, it is always hard to directly understand them & solve them.

I believe, errors are generally related to typing error OR data structure error OR run-time memory error - which is related to hardware OR else.

How to elaborate and solve those errors very fast ?

答:
A lot, rather most of what you do as a programmer is debugging. You are either debugging your code or someone else's. As a novice, you don't want to focus on faster. You need to focus on detail, organization, and correctness:

Study the details. Don't just debug, seek to know why something isn't working.

Well-organized code makes maintenance and debugging much easier.

Be correct in usage: just throwing code together to save time never does.

Additionally, ask questions...ask, ask, ask. The speed at which you debug is not near as important as your skill at resolving the bug once found. Speed will come over time; however, accuracy should be your primary concern.

ContentLicense: CC BY-SA 2.5


答:
Make updating the various documents part of your "definition of done".

Assuming you are using agile methods, your work will be broken down into tasks. Any change to the primary documentation (the code) will likely trigger the need for changes to supplementary docs (tests, wiki entries, comments, diagrams, word docs etc). So as part of the task, the assigned person should update affected docs and those docs should be checked as part of the reviews of the changes made by that task. Only once everything (not just the code) is updated, checked-in, reviewed and tested, should the task be considered complete.


问:
In the GNU Affero GPL, do paying customers count as the 'public'?
In the GNU Affero General Public License, there is a section that reads:

The GNU Affero General Public License is designed specifically to
  ensure that, in such cases, the modified source code becomes available
  to the community. It requires the operator of a network server to
  provide the source code of the modified version running there to the
  users of that server. Therefore, public use of a modified version, on
  a publicly accessible server, gives the public access to the source
  code of the modified version.

So clearly I couldn't make a modified version of a piece of software and then put it on the public internet for everyone to access (assuming network software living on a server) without also making the source code available.

But what is defined by "public" here? Do subscription based services where only select paying customers have access count as "public"?

答:
The text you quoted is part of the preamble, it is not part of the legally binding terms and conditions.

The relevant part is article 13, which states that you have to make the source code available to everybody to whom you make the object code available. Note that this is no different from the "normal" GPL. The difference between the normal and the Affero versions of the GPL is not to whom you make the source code available, but rather what counts as making the object code available. In the normal GPL, only giving the object code away counts, whereas in the Affero GPL also making it available as a service counts.

To repeat: no version of the GPL requires you to make the source code available to the public. In fact, no version of the GPL requires you to make the source code available at all.

All versions of the GPL only require you to make the source code available iff you also make the object code available and only to those people to whom you make the object code available.

What the Affero GPL adds is the idea that Software-as-a-Service is also a form of making the object code available and thus also requires making the source code available to the users of the service.


答:
@ThomasOwens mentioned the most important part, Single Source

So you should start,

Adding all new docs to a single source,

When making schedules, add move current documentation to new source bullet to todo list. Spending a separate time to move all documents from all around to a single source is hard, but people may update docs when then maintain related service, update the related code base, need the document but have hard time finding or another employee may had hard time finding docs. Doing the move and merge thing when you are dealing with the related doc or service is easier.

You can also have a distributed source system which is managed from a single place!

You can have a document server, place all docs there. Any you can have a script which runs every midnight and inspect files, creating wiki directories and wiki headlines according to folder/file structure and update the wiki pages according to related files using file names.

You can have a web-based documentation tool where you prepare and update documents on a software and the software can create/update docs (on hard drives) on local or remote machines, update wiki pages etc.

If you managed to keep all of your docs in the same place, then you can distribute read-only copies to anywhere you want.


答:
The short answer to this question is that this is what a build tool is. A tool that automates the use of other tools, with the aim of building an end product from some source files. If we're writing the build script in the same language as the product itself, we're into the realms of language-specific tools, which would not be considered build tools in the same way.

This raises the question -- why don't compilers provide the sort of build automation that we're used to from tools like make? To which the answer is simply because make exists. The Unix philosophy of "do one thing, and do it well" suggests that it is not the responsibility of the compiler to provide this*. That said, I have personally been through my share of make headaches, and would be interested to try a compiler that provides it's own quote-unquote "native" build system.

For an example of a compiler designed this way, see Jon Blow's (as yet unreleased) Jai, a language intended as a C++ replacement. Links to talks and demos of the compiler are collected here. This language compiles to byte-code that runs within the compiler, with compilation to binary being a standard library provided function, accessible from the byte-code. The intention is to allow for both build automation and meta-programming within the language's native syntax.

* A look at Microsoft's Visual Studio will show you an example of the opposite philosophy. :)

Title: Why do build tools use a scripting language different than underlying programming language?

Body:
I've recently been using some build tools for a Nodejs project at work when I realized that most languages' main build tool/system use a different language than the underlying programming language itself.

For example, make does not use C or C++ to write scripts and ant (nor Maven) doesn't use Java as their language for scripting.

Newer languages like Ruby do use the same language for build tools like rake, which makes sense to me. But why hasn't this always been the case? What't the advantage to having a build tool that uses a different language from the underlying language?


问:
How to prevent changes to an internal API from breaking other projects?
We have like 20 - 30 independent modules/solutions. Each of these has about 7 - 10 projects with different classes, components, etc.  These are all used internal to our company.

Our problem is when we make a change in one module, we then need to make sure to update all other modules which are accessing this code. This is difficult to know because it is in different codebases.

How can we document where all external uses of an API are? Or otherwise prevent small changes from breaking other modules?

答:
Our problem is when we make a change in one module, we then need to make sure to update all other modules which are accessing this code. This is difficult to know because it is in different codebases.

I would suggest that this is impossible to know.

You are responsible for the Components and their Interfaces.

You are not responsible for anything and everything that might make use of them.

How can we document where all external uses of an API are?  Or otherwise prevent small changes from breaking other modules?

Short answer?  Tests.

Write Tests that exercise the published Interfaces.  Re-run them whenever you make a change.  So long as the tests "Pass", you haven't broken anything.  When a test breaks (and it will) either (a) find and fix the problem or (b) if you can justify the change as legitimate, then re-write the test to accommodate it.


答: Having an intelligent IDE and learning how to use a debugger, I'd say. Without these basic things, you are probably either hopelessly executing code in your head and seeing if it works, or inserting trace statements all over the place. This can make debugging simple mistakes take forever, when, in a better environment, it would be pointed out to you in glowing red before you even ran the project (or shortly thereafter).</p>

Title: Uncaught TypeError: Cannot read property 'add' of null

Body:
I am novice developer.

While development is going on, we come across different error issues. However for the novice of programming, it is always hard to directly understand them & solve them.

I believe, errors are generally related to typing error OR data structure error OR run-time memory error - which is related to hardware OR else.

How to elaborate and solve those errors very fast ?


答:
The build tool is first and foremost a tool, just like 'gcc', 'ls', 'awk' or 'git'. You feed the tool an input (filename, parameters, etc) and it will do some stuff accordingly.

All of these tools allow you to pass in your input in ways that should be simple enough to write and understand. In the particular case of build tools, the input is a recipe file, a file that describes how your project goes from the source files to the finished product.

If your recipe is as simple as passing in the folder that contains the project and the compiler to use, then a declarative "language" is enough. Once the recipe becomes more and more complicated, with more logic, it becomes troublesome to handle it with declarative languages and more general purpose languages are used.

It should now be apparent that there is no connection between the language used to write your build recipes and the languages used to write your product code simply because they have different purposes and requirements. There is no connection even between the language the build tool is written in and the "language" the build recipes should be written in. Always use the best tool for the job!


问:
How important are UML diagrams for a successful project?
I'm in the middle of a project and I was asked to write UML diagrams (use cases,class diagram,etc). The project isn't very complex.

I was wondering if this be a waste of my time? Should I just be doing other fun stuff like writing code? And when is it not ok to build something without going through all of the conceptual phase? Is it all about complexity? And if so, how to measure it?

答:
Don't know if the question is about the merit of UML,
or about the merit of designing the architecture of programs.

About UML. You usually only need: use cases, class diagrams, and sequence diagrams. Simple and easy, although you could do it certainly with your own types of diagrams. In this regard UML is a standard everyone will understand.

About designing programs.

Every program has a design, even if you don't plan it. When the code is written, just reverse-engineer it. If you didn't planned it, bet it will be a bad design.

Design will save you time, by using known patterns for recurring problems.

If you work in a team, design is necessary to discuss solutions, to transmit ideas, and very practical but necessary, to distribute work.


问:
Could submitting a Pull Request ever constitute accepting a Contributor Licence Agreement?
Some software projects have a Contributor Licence Agreement. The agreement could, for instance, assign copyright of 3rd-party contributions to the original project creator.  Could submitting a Pull Request on github ever constitute accepting such an agreement?</p>

答:
A few alternatives which might be safer:

make first time committers write an "I agree to the CLA" line on a CLA.md file. Commit message then identifies the person.

https://github.com/clahub/clahub


答:
Under UK law, a contract exists where one party makes an offer, and the other party accepts that offer.  So, to answer your question, yes, there are situations where a judge would decide that by making their software available for people to access, and publishing license terms for doing so, they are making a contractual offer.  Then when you choose to access the source code you have demonstrated your acceptance of the contract that grants you the legal access to the source code.

However, the exact circumstances matter considerably.  Its hard to enter into a legally binding agreement with a 12 year old child, likewise, its hard to argue that a professional software developer would not expect the source code to be licensed.

Title: Could submitting a Pull Request ever constitute accepting a Contributor Licence Agreement?

Body: Some software projects have a Contributor Licence Agreement. The agreement could, for instance, assign copyright of 3rd-party contributions to the original project creator.  Could submitting a Pull Request on github ever constitute accepting such an agreement?</p>


问:
What's the name for the 'spec' of a function/method?
I'm pretty sure there is a special name for the 'spec' of a function/method.  It's a word that refers to

how many arguments it takes

the order of arguments

which arguments are optional

Is there a name for that?

答:
Usually this is called a type signature.

A type signature includes the function's return type, the number of
  arguments, the types of arguments, or errors it may pass back.


问:
Onion architecture in client-server application
I'm staring new project, cross-platform. I want to use onion architecture there. It will be a simple game (tic tac toe), just for education purposes. This app will be client-server type.

Now, I read a lot about onion architecture, but I'm still not exactly sure how to deal with it in client-server.

Should I create two different repositories(1) for server and for client? Or should I keep them both in single solution(2) (since many class/interfaces in Core/Domain are the same for both)?

(1) - source code repositories (on bitbucket or sth like that)

(2) -    Visual Studio Solution

EDIT:

It will be cross-platform app (C# via xamarin) with single server also in C#. Communication via WCF. Server will just store user accounts, watch every move, save history of games - not important, it's just for education.

Answering @Kasper, how do I see OA in client-server app:

I thought, I could share as much code as possible in Core of Onion - like Entities, Helpers, Logger(?), Interfaces... Then, I will have another layer - project for Client API (Application and Domain services) and Server API (Application services - consuming and sending messages from/to clients), then Interface layers. Separated for Clients and for Server.

So, single VS solution, two apps, single Core. I know it's technically possible - but is that a good practice?

答:
It is not clear what you mean by "repositories".  Do you mean Source Code Repositories ?  In this case, definitely use only one repository.

Also, it is not clear what you mean by "solution".  You are using C#, so presumably Visual Studio, and in visual studio "Solution" is a container of all your projects.  So, definitely use one solution.  This solution would contain multiple projects.

So, your "Tic Tac Toe" solution would contain:

One "Client" project for your client (perhaps of type WinForms application ?)

One "Server" project for your server (perhaps of type Console application ?)

One "TicTacToe" project with all code that is common for both (of type Class Library.)

The "Client" project will depend on (make use of) your "TicTacToe" project, and your "Server" project will also depend on (make use of) your "TicTacToe" project.

Furthermore, even though your client project does not directly invoke (cannot make use of, at the source code level) your server project, you should still define the client as depending on the server, because every time you want to run the client, you want Visual Studio to make sure that the server is up to date. (Has been compiled.)  Then, you could have a mechanism in place which automatically restarts the server each time it gets recompiled, but that's beyond the scope of this question.

So, the TicTacToe Class Library project can be thought of as the center of your onion, the Server Application project can be thought of as a middle layer of your onion, and the Client Application project can be thought of as the outer layer of your onion.


问:
Service oriented web architecture speed
Imagine a simple service architecture setup: single server where I have one service acting as a REST API (PHP), another service for rendering frontend (nodejs), and maybe a database service.

They all communicate through localhost requests, so for example frontend gets data from API by calling http://localhost:{API PORT}/v1/products. Now the request flow would be frontend -> rest api -> database -> rest api -> frontend -> response to client.

Is there a performance penalty when using this approach vs using one monolithic application, where everything is together? Or is it better to utilize something like RabbitMQ for this kind of setup?

答:
Any form of abstraction has performance penalty. For instance, the HTTP requests between different layers would cost you a few micro- or milliseconds every time. The question you should ask yourself is rather how important are those microseconds of runtime compared to the eventual benefit you get from micro-services (or a simple multitier architecture). Is it worth it?

Usually, larger applications which are expected to scale are better candidates for micro-services. Small applications which don't need to scale quickly across multiple servers fit better in a monolithic model (monolithic here means a single application and a database; this doesn't prevent you from setting proper multitier architecture!)

Title: Service oriented web architecture speed


答:
There is some overhead in calling services on the same server, but its not huge. Any performance problems that you would face would be related to poor logic in one of the layers, or the server is being taxed by the combined weight of all the processes.

The ease to allow the system to expand generally outweighs the minor overhead costs at the single server level. Also its good practice to build apps in this manor, because it is a common way for enterprise apps to be architected and being familiar with it is good for employment opportunities.

Title: Service oriented web architecture speed

Body:
Imagine a simple service architecture setup: single server where I have one service acting as a REST API (PHP), another service for rendering frontend (nodejs), and maybe a database service.

They all communicate through localhost requests, so for example frontend gets data from API by calling http://localhost:{API PORT}/v1/products. Now the request flow would be frontend -> rest api -> database -> rest api -> frontend -> response to client.

Is there a performance penalty when using this approach vs using one monolithic application, where everything is together? Or is it better to utilize something like RabbitMQ for this kind of setup?


问:
Debug function input vs expecting code users to read the documentation - How far do I go?
I could write an endless amount of debugging code to handle the various components of input for a function, check that the correct data types are used, make sure things are decendants of the proper prototype objects, the data is within a certain value range or set... The list could go on and on.

But also of course I can use documentation comment APIs to generate good documentation on the expected input and usage.

My question is, how far/in-depth should I go as far as debugging/checking input for code users versus expecting them to read the funtion / method's documentation for proper use?

We could say "That's up to whoever's in charge" but I'm interested in best  practice for maximum efficiency.

答:
There are two sides of the problem.

As a developer, you have to sanitize your inputs. Don't trust the users to read your documentation in-depth, and don't trust the users to follow the documentation at all. Security-wise, if it's a public API and you expect the users to sanitize the input, things will go very wrong very quickly. For non-public APIs, trusting the inputs is problematic as well; if your code makes bad things to happen when given an invalid input, it's your code which will be blamed, not the caller's.

If the input is invalid, throw an exception.

As an API provider, you may want to simplify the work of the callers who may not be familiar with your API (and find your documentation too difficult, impractical or boring to read). One way to simplify their life is to provide explicit error messages. This is the difference between:

```<code>throw new Exception("Invalid input.");
</code>```

which simply means RTFM, and:

```<code>throw new ArgumentOutOfRangeException("price", "The price cannot be negative.");
</code>```

which gives a convenient way to know exactly what is wrong with the caller's code.

If the input is invalid and you have enough time to explain why is it invalid, do that in the exception.

If the input error is easily done and is encountered often, focus on that to either eliminate the possibility for the callers to do the error, or provide a very detailed error message.

Body:
There are two sides of the problem.

As a developer, you have to sanitize your inputs. Don't trust the users to read your documentation in-depth, and don't trust the users to follow the documentation at all. Security-wise, if it's a public API and you expect the users to sanitize the input, things will go very wrong very quickly. For non-public APIs, trusting the inputs is problematic as well; if your code makes bad things to happen when given an invalid input, it's your code which will be blamed, not the caller's.

If the input is invalid, throw an exception.

As an API provider, you may want to simplify the work of the callers who may not be familiar with your API (and find your documentation too difficult, impractical or boring to read). One way to simplify their life is to provide explicit error messages. This is the difference between:

throw new Exception("Invalid input.");

which simply means RTFM, and:

throw new ArgumentOutOfRangeException("price", "The price cannot be negative.");

which gives a convenient way to know exactly what is wrong with the caller's code.

If the input is invalid and you have enough time to explain why is it invalid, do that in the exception.

If the input error is easily done and is encountered often, focus on that to either eliminate the possibility for the callers to do the error, or provide a very detailed error message.


答:
Of course it depends on the way things are done in your organization, (policy of quality work vs. policy of quick and dirty throw-away work, presence or absence of a culture of respect shown by middleware programmers towards application programmers, etc.,) but in general:

The "best" thing is considered to be to write self-documenting APIs whose usage is as clear as possible with just a brief skim through the interface, and to never expect callers of your API to have memorized, or even to have bothered in any great length with, the documentation.  Callers of your API will invoke it in weird ways while examining "what if" scenarios. Callers of your API will invoke it in ways that you never even imagined.

APIs are generally expected to be bulletproof and idiotproof.

And this is a good thing.  Why? Because:

A "Null Pointer Exception" or a "Division by Zero" exception thrown somewhere within your code is always considered to be your fault.  So, for every single bug in the caller's code, the bug gets nonetheless assigned to you. You have to reproduce it, you have to troubleshoot it, you have to discover that it is their fault instead, and you have to convince them that it is so.

An "Invalid Argument" exception thrown by your code is always considered to be the caller's fault.  The bug report goes directly to them.  Peace of mind.

Excessive arguments between application programmers and middleware programmers where each is trying to prove that it's the other one's fault are generally indicative of sloppy work on behalf of the middleware programmer.

Edit:

I just noticed the term "maximum efficiency" in the question.  It is not clear what you mean by efficiency.  Inefficiencies in the development process (quarrels about whose fault it is) can often waste huge amounts of time.  Now, inefficiencies in the runtime are generally not an issue, because you can always use assertions, which are only enabled on the debug build of the application.  But if you do not want to use assertions, the inefficiencies that stem from hard-coded parameter checking are generally not an issue in modern, multi-core, multi-pipelined, multi-level-cached, multi-gigaherz machines. If someone has an issue, tell them to buy better hardware. This is often considered to also be a best practice.

Title: Debug function input vs expecting code users to read the documentation - How far do I go?

Body:
I could write an endless amount of debugging code to handle the various components of input for a function, check that the correct data types are used, make sure things are decendants of the proper prototype objects, the data is within a certain value range or set... The list could go on and on.

But also of course I can use documentation comment APIs to generate good documentation on the expected input and usage.

My question is, how far/in-depth should I go as far as debugging/checking input for code users versus expecting them to read the funtion / method's documentation for proper use?

We could say "That's up to whoever's in charge" but I'm interested in best  practice for maximum efficiency.


问:
What are the benefits of dependency injection in cases where almost everyone needs access to a common data structure?
There are plenty of reasons why globals are evil in OOP.

If the number or size of the objects needing sharing is too large to be efficiently passed around in function parameters, usually everyone recommends Dependency Injection instead of a global object.

However, in the case where almost everyone needs to know about a certain data structure, why is Dependency Injection any better than a global object?

Example (a simplified one, to show the point generally, without delving too deep in a specific application)

There is a number of virtual vehicles which have a huge number of properties and states, from type, name, color, to speed, position, etc. A number of users can remote control them, and a huge number of events (both user-initiated and automatic) can change a lot of their states or properties.

The naive solution would be to just make a global container of them, like

```<code>vector<Vehicle> vehicles;
</code>```

which can be accessed from anywhere.

The more OOP-friendly solution would be to have the container be member of the class which handles the main event loop, and be instantiated in its constructor. Every class which needs it, and is member of the main thread, will be given access to the container via a pointer in their constructor.
For example, if an external message comes in via a network connection, a class (one for each connection) handling the parsing will take over, and the parser will have access to the container via a pointer or reference. Now if the parsed message results in either a change in an element of the container, or requires some data out of it to perform an action, it can be handled without the need of tossing around thousands of variables through signals and slots (or worse, storing them in the parser to be later retrieved by the one who called the parser). Of course, all classes which receive access to the container via dependency injection, are part of the same thread. Different threads will not directly access it, but do their job and then send signals to the main thread, and the slots in the main thread will update the container.

However, if the majority of classes will get access to the container, what makes it really different from a global? If so many classes need the data in the container, isn't the "dependency injection way" just a disguised global?

One answer would be thread safety: even though I take care not to abuse the global container, maybe another developer in the future, under the pressure of a close deadline, will nevertheless use the global container in a different thread, without taking care of all the collision cases.
However, even in the case of dependency injection, one could give a pointer to someone running in another thread, leading to the same problems.

答:
There are three main reasons you should consider.

Readability. If every unit of code has everything it needs to work on either injected or passed in as a parameter, it's easy to look at the code and instantly see what it's doing. This gives you a locality of function, which also enables you to separate concerns better and also forces you to think about...

Modularity. Why should the parser know about the entire list of vehicles and all their properties? It probably doesn't. Maybe it needs to query whether a vehicle id exists or whether vehicle X has property Y. Great, that means you can write a service that does that, and inject only that service into your parser. Suddenly you end up with a design that makes far more sense, with every bit of code only handling data that is relevant to it. Which leads us to...

Testability. For a typical unit test you want to set up your environment for many different scenarios and injection makes this very easy to implement. Again, returning to the parser example, do you really want to always hand-craft an entire list of fully-fledged vehicles for every test case you write for your parser? Or would you just create a mock implementation of the aforementioned service object, returning varying numbers of ids? I know which one I'd choose.

So to sum it up: DI isn't a goal, it's just a tool that makes it possible to achieve a goal. If you misuse it (like it appears you do in your example), you won't get any closer to the goal, there is no magical property of DI that will make a bad design good.


问:
What are you telling yourself if you can't understand new concept, paradigm, feature ...?
Programming always required to learn new concepts, paradigms, features and technologies and I always have been failed at first attempt to understand new concept what i encounter. I start to blame and humiliate myself without remember before how i understood new concept which i hadn't understand it before.

I can hardly stop to tell myself "why i cant understand ? Am i stupid or idiot ? Yes, i am stuppiiddddd!!!"

What your inner voice tells if you can not understand new concept after spend long time till been tired or hopeless ?

How do you handle your self-esteem in such situations ?

答: I think "Finally, programming is interesting again!" and search the Internet for tutorials. The last time that happened was when I stumbled upon monads. Many programmers hit a brick wall when they read about monads for the first time, because it is unlike every other concept you have encountered so far as a programmer, especially if you're new to functional programming.</p>


答:
In addition to answers already u have,

There is a number of virtual vehicles which have a huge number of
  properties and states, from type, name, color, to speed, position,
  etc. A number of users can remote control them, and a huge number of
  events (both user-initiated and automatic) can change a lot of their
  states or properties.

One of characteristic of OOP programming is to only keep properties you really need for a specific object,

NOW IF your object has too many properties - you should break your object down further into sub-objects.

Edit

Already mentioned why global objects are bad, I would add one example to it.

You need to do unit testing on a windows form's GUI code, if you use global, you will need to create all of button and it's events for example to create a proper test case...

Title: What are the benefits of dependency injection in cases where almost everyone needs access to a common data structure?

Body:
There are plenty of reasons why globals are evil in OOP.

If the number or size of the objects needing sharing is too large to be efficiently passed around in function parameters, usually everyone recommends Dependency Injection instead of a global object.

However, in the case where almost everyone needs to know about a certain data structure, why is Dependency Injection any better than a global object?

Example (a simplified one, to show the point generally, without delving too deep in a specific application)

There is a number of virtual vehicles which have a huge number of properties and states, from type, name, color, to speed, position, etc. A number of users can remote control them, and a huge number of events (both user-initiated and automatic) can change a lot of their states or properties.

The naive solution would be to just make a global container of them, like

```<code>vector<Vehicle> vehicles;
</code>```

which can be accessed from anywhere.

The more OOP-friendly solution would be to have the container be member of the class which handles the main event loop, and be instantiated in its constructor. Every class which needs it, and is member of the main thread, will be given access to the container via a pointer in their constructor.
For example, if an external message comes in via a network connection, a class (one for each connection) handling the parsing will take over, and the parser will have access to the container via a pointer or reference. Now if the parsed message results in either a change in an element of the container, or requires some data out of it to perform an action, it can be handled without the need of tossing around thousands of variables through signals and slots (or worse, storing them in the parser to be later retrieved by the one who called the parser). Of course, all classes which receive access to the container via dependency injection, are part of the same thread. Different threads will not directly access it, but do their job and then send signals to the main thread, and the slots in the main thread will update the container.

However, if the majority of classes will get access to the container, what makes it really different from a global? If so many classes need the data in the container, isn't the "dependency injection way" just a disguised global?

One answer would be thread safety: even though I take care not to abuse the global container, maybe another developer in the future, under the pressure of a close deadline, will nevertheless use the global container in a different thread, without taking care of all the collision cases.
However, even in the case of dependency injection, one could give a pointer to someone running in another thread, leading to the same problems.


答:
Its really about testability - normally a global object is very maintainable and easy to read/understand (once you know its there, of course) but it is a permanent fixture and when you come to split your classes into isolated tests, you find that your global object is stuck saying "what about me" and thus your isolated tests require the global object to be included in them. It doesn't help that most test frameworks don't easily support this scenario.

So yes, its is still a global. The fundamental reason for having it has not changed, only the manner in which it is accessed.

As for initialisation, this is still a problem - you still have to set the configuration so your tests can run, so you're not gaining anything there. I suppose you could split a large dependant object into many smaller ones and pass the appropriate one to the classes that need them, but you're probably getting even more complexity to outweigh any benefits.

Regardless of all that, its an example of the 'tail wagging the dog', the need to test is driving how the codebase is architected (similar problems arise with items such as static classes, eg current datetime).

Personally I prefer to stick all my global data in a global object (or several) but provide accessors to get the bits my classes need. Then I can mock those to return the data I want when it comes to testing without the added complexity of DI.


答:
Focusing on writing "efficient" code without actually defining efficiency is a common trap developers fall into.

Efficiency isn't always reducing the number of CPU cycles required to accomplish a task.  In fact, for most programmers, in most cases, obsessing over shaving CPU cycles is a complete waste of time.

Where Efficiency = minimizing CPU cycles

The majority of business software contains trivial logic.

Imagine spending 30 minutes shaving a few CPU cycles off your code.  Let's just say you had a good day and shaved off a 2000 cycles.  Your typical 2GHz CPU will go through 2,000,000,000 cycles every second which means your 2000 cycles saved amount to 0.000001 seconds or 1 microsecond saved.

Your application would need to run that optimized code 30,000,000 times before you break even on your time investment.

In all my time in the business software world, I can't think of one instance where that initial 30 minute investment would have been paid off before I left that role for another job.

Where Efficiency = time saved IN GENERAL

On the other hand, if you define efficiency in terms of time saved in general then your ROI sky rockets.

So, in this scenario, time saved includes (but is not limited to) the following:

Your time testing your API

API Consumer's time debugging issues with your API

Your time debugging issues with your API Consumer

Your time handling calls about a brittle and broken API (no, the consumer didn't read your documentation)

With this definition of efficiency, a little bit of defensive programming goes a long way.  Making your API fail early and fail hard on bad input data requires very little upfront time and saves you and your consumers' a boatload of downstream time.

The big thing to remember is that your time and your API consumer's time is much more valuable (read: expensive) than CPU time.

Other domains

There are however domains where efficiency can mean minimizing CPU cycles.  But, keep in mind that those domains are fewer and fewer nowadays.

Two that come to mind are coding for realtime systems and high volume data analysis.

TL;DR

So, unless you know for sure that you need to shave off CPU cycles, and better approach would be code in such a way that you save yourself and others as much time as possible.  In the API world you can accomplish this with clear code contracts and defensive programming.


问:
Common Repository design

What I have:

I am developing an Active Directory layer which will be used by a huge application with several modules having several solutions and projects...

I am fairly new to developing large scale solutions.

Because the current requirements are mostly to deal with User and Group objects in AD, my current solution looks like this,

Extensions

UserPrincipalExtension  (inherting from System.DirectoryServices.AccountManagement.UserPrincipal to add custom attributes and override FindByIdentity methods)

GroupPrincipalExtension (same as above but with GroupPrincipal...)

Models (models have override methods, e.g. toString, constructors etc.)

ADUser

ADGroup

User

SomeUserObject

and so on...

Repositories

ADUserRepo (CRUD for user, + isUserInGroup sort of methods)

ADGroupRepo (CRUD for group, + GetUsersInGroup sort of methods)

General

Utilies (Get Context, etc..)

What I want OR confusion is at:

Because some methods are sort of common between User and Group Repositories, Would it be any beneficial to move all methods out of UserRepo and GroupRepo into a single DirectoryRepo class and delete these repositories ?

At the moment this is creating confusion for me who is developing this, but it may confuse or either FORCE a consumer of this code to add duplicate methods.

How can I overcome this problem?

I named these repositories but these are just static methods accessing AD, sorry if that created any confusion.

Here are few of my previous questions on SO, if you want to look at some of the related code

https://stackoverflow.com/questions/32689228/how-to-extract-a-method-which-is-using-using-keyword-and-is-disposable

https://stackoverflow.com/questions/32649304/repository-class

答:
The key to answering that question is the use of the repositories.  Are there cases where only the User or only the Group repository would be used?  Are you more likely to in most situations access both the User and Groups at the same time?  Once you can answer those questions you will be able to determine which is "Right" for application design.

In one application I was working on the repositories were very fragmented (1 per database table) and using them was very cumbersome.  After some refactoring we were at less repositories but with more logical access patterns.  IE: A user always needed what groups they were a part of and groups were never accessed except when accessing users so we combined the 2 together as they logically went together.

Since this is a new application I would look at keeping them seperate since it will be easier to combine them (IMO) than break them appart later.  If you find after some development that having them seperate causes you to always instantiate both repositories, I would combine them at that point.  No point instantiating 2 objects in 90% of your code just to instantiate 1 object in 10%.

Title: Common Repository design


答:
There are plenty of reasons why non-mutable globals are evil in OOP.

That is a dubious claim. The link you use as evidence refers to state - mutable globals. They are decidedly evil. Read only globals are just constants. Constants are relatively sane. I mean, you're not going to inject the value of pi into all your classes, will you?

If the number or size of the objects needing sharing is too large to be efficiently passed around in function parameters, usually everyone recommends Dependency Injection instead of a global object.

No, they don't.

If your functions/classes have too many dependencies, people recommend stopping and taking a look at why your design is so bad. Having a boatload of dependencies is a sign that your class/function is probably doing too many things and/or you do not have sufficient abstraction.

There is a number of virtual vehicles which have a huge number of properties and states, from type, name, color, to speed, position, etc. A number of users can remote control them, and a huge number of events (both user-initiated and automatic) can change a lot of their states or properties.

This is a design nightmare. You have a bunch of stuff that can be used/abused with no manner of validation, no manner of concurrency limitations - it's just coupling all over.

However, if the majority of classes will get access to the container, what makes it really different from a global? If so many classes need the data in the container, isn't the "dependency injection way" just a disguised global?

Yes, having coupling to common data everywhere isn't too different from a global, and as such, still bad.

The upside is that you're decoupling the consumers from the global variable itself. This provides you with some flexibility in how the instance is created. It also doesn't force you into having only one instance. You could make different ones to be passed along into your different consumers. You can also then create different implementations of your interface per consumer should you need to.

And due to change that inevitably comes with the shifting requirements of software, such a basic level of flexibility is vital.


答:
in the case where almost everyone needs to know about a certain data structure, why is Dependency Injection any better than a global object?

Dependency injection is the best thing since sliced bread, while global objects have been known for decades to be the source of all evil, so this is a rather interesting question.

The point of dependency injection is not simply to ensure that every actor who needs some resource can have it, because obviously, if you make all resources global, then every actor will have access to every resource, problem solved, right?

The point of dependency injection is:

To allow actors to access resources on a need basis, and

To have control over which instance of a resource is accessed by any given actor.

The fact that in your particular configuration all actors happen to need access to the same resource instance is irrelevant.  Trust me, you will one day have the need to reconfigure things so that actors will have access to different instances of the resource, and then you will realize that you have painted yourself in a corner.  Some answers have already pointed such a configuration: testing.

Another example: suppose you split your application into client-server. All actors on the client use the same set of central resources on the client, and all actors on the server use the same set of central resources on the server.  Now suppose, one day, that you decide to create a "standalone" version of your client-server application, where both the client and the server are packaged in a single executable and running in the same virtual machine. (Or runtime environment, depending on your language of choice.)

If you use dependency injection, you can easily make sure that all the client actors are given the client resource instances to work with, while all the server actors receive the server resource instances.

If you do not use dependency injection, you are completely out of luck, as only one global instance of each resource can exist in one virtual machine.

Then, you have to consider: do all actors really need access to that resource?  really?

It is possible that you have made the mistake of turning that resource into a god object, (so, of course everyone needs access to it,) or perhaps you are grossly overestimating the number of actors in your project that actually need access to that resource.

With globals, every single line of source code in your entire application has access to every single global resource.  With dependency injection, each resource instance is only visible to those actors that actually need it.  If the two are the same, (the actors that need a particular resource comprise 100% of the lines of source code in your project,) then you must have made a mistake in your design.  So, either

Refactor that great big huge god resource into smaller sub-resources, so different actors need access to different pieces of it, but rarely an actor needs all of its pieces, or

Refactor your actors to in turn accept as parameters only the subsets of the problem that they need to work on, so they do not have to be consulting some great big huge central resource all the time.


问:
Should every member of a team use the same IDE?
Do you think it makes sense to enforce that every member of a team must use the same IDE?

For instance all engineers that are already on the team use IDE X. Two new engineers come and want to use IDE Y instead because that's what they have been using for several years now.

Do you have any experience with "mixed IDE" teams? If so what is it?

答: Well yes I have some experiecne in that regards being a part of mixed windows/unix & c++/java team. I think this is not an issue provided either everyone is comfortable working with the other IDE or there is never going to be a situation when anyone who is not familiar with IDE Y needs to work on the other guy's (that is the guy with IDE Y) system. </p>


答:
As the developer of an API you have to decide and to document what valid inputs are, and you have to decide and document what you do with invalid inputs. You also need to decide what are things that don't work, and what are programmer errors. For example, a path to a non-existing file may "not work", while a null pointer or empty string as the path may be a "programming error". And finally, this should be discussed with the users of the API (unless you are experienced enough to decide without their input).

If possible, detect programming errors (that is errors where you expect someone to change their code) and stop your program. If possible, detect other problems, avoid crashing or doing something bad, and report the problem so that it can be fixed or handled by the caller.

Readable documentation helps making users read your documentation :-)


问:
C++ Header files design : just like defining an API?
I'm kind of new to large scale software development in C++, and I was wondering on the design side of things.

I was reading this question, and I thought that, overall, once we get past constant definitions and other trivial matters, C++ header files are just API definitions :

They define what other programmers (or yourself from other modules) will be able to use (classes, public functions), but no private class or function should be defined in it.
It's like the header file defines the abstractions (interfaces ...) and the source file implements it. Once the source file is compiled, the implementation details are hidden away, and remain the publicly available headers defining what the module can do.

I felt this view of header/source file separation was a lot easier to understand and follow than the usual explanations, since you can just think "would XXX be publicly available API material, or is it a sausage-making detail to be hidden away in an undisclosed source file ?"

Is my mental model of header files roughly correct ?
What did I miss ?

答:
Pretty much, there's little difference between a header file and an interface as used by other languages for the main part. Obviously though there are differences in implementation in that the header will also contain private information, but fundamentally they are used to describe the features the class or module will provide.

In a way then, its also a mental model of data structures combined with the API so it can be more useful when you're doing the kind of initial design you describe.

Ideally a header defining an API would contain just the pure interface but as C++ doesn't have an ABI, this doesn't really matter. If you build a higher level system that does provide a pure client interface, you'll be using a different mechanism such as an IDL or WSDL to define that anyway.


问:
Rebol refinements vs. dialects vs. objects
I occasionally get conflicted when using a language that isn't Rebol (happens from time to time) and get to thinking, hm—would life be easier in Rebol if this thing worked this way?

To illustrate my current instance, in Rebol you send a message as follows:

```<code>send foo@bar.baz "A Message"
</code>```

It's always been one of the killer one-liners, very concise, most elegant. Using refinements, you can start to build up a more complex message:

```<code>send/subject/attach foo@bar.baz "Hi Foo!" "A Message" %me.jpg
</code>```

Still relatively concise, but starting to fill out a little. As you sculpt your message, it starts to get a bit messy:

```<code>send/subject/attach/header
    [foo@bar.baz eric@bar.baz]
    "Hi Folks! – Chris"
    "A Message"
    make object! [X-User-Agent: join "Rebol " system/version]
</code>```

That's the current prescribed way to send an email (line feeds are optional here, but become essential as component parts start to add up).

Rebol is nothing if not versatile though, we can dream of an alternate approach using dialects:

```<code>send [
    ; no delimiters required, we can discern recipients
    ; by the use of the email! datatype:
    foo@bar.baz eric@bar.baz

    ; two string! values indicate the first as the subject
    ; second as the message
    "A Message"
    "Hi Folks!"

    ; a few attachments courtesy of the file! datatype
    %me.jpg %you.jpg %the-world.jpg

    ; and then some set-word!/value headers
    X-User-Agent: "Rebol"
]
</code>```

Sans comments:

```<code>send [
    foo@bar.baz eric@bar.baz
    "A Message"
    "Hi Folks!"
    %me.jpg %you.jpg %the-world.jpg
    X-User-Agent: "Rebol"
]
</code>```

Pretty spiffy, but dialects get a bit tricky as you start to pull in conditional arguments, external data, further customisation. We can build that up somewhat procedurally:

```<code>send collect [
    keep foo@bar.baz
    if "Monday" = pick system/locale/days now/weekday [
        keep eric@bar.baz
    ]
    keep subject ; 'subject defined elsewhere
    keep {A Long Message}
    keep read %photos/
    keep compose [X-User-Agent: (join "Rebol " system/version)]
]
</code>```

Seems reasonable, except we lose a bit of expressivity as the implicit metadata offered by datatypes is obscured by the additional code. Even just the addition of words not of our current domain (collect, keep).

Which brings me to the object-based world (which seemingly covers the way the popular languages out there approach things). In this composite, non-existent Language X, we recover some of the expressivity through the explicit use of named actions:

```<code>message = mailer.new

// pity poor language X, only one string type:
message.addRecipient 'foo@bar.baz'
if (today = 'Monday') { // assumed 'today value
    message.addRecipient 'eric@bar.baz'
}

message.subject = "A Message"
message.body = "Hi Folks!"
message.attach filesystem.read 'photos/'
message.header['X-User-Agent'] = 'Language X'

message.send

// Rebol's SEND function needs a return value with some
// status feedback. For another day...
if (message.isSentOk) {
    print "Hooray!"
}
</code>```

Beauty is in the eye of the beholder: this approach leaves you in no doubt what each line is for, yet simultaneously (to my eyes) appears heavy-handed. We get to our destination procedurally, send happens after we've established the details of the message. In my moments of doubt, I wonder if having send [...] states the intent before we're ready.

You could easily transliterate the Language X approach to Rebol, or have it inform the approach taken by a dialect:

```<code>mailer [
    new message
    add recipient foo@bar.baz
    if today = "Monday" [
        add recipient eric@bar.baz
    ]
    subject: "A Message"
    body: "Hi Folks!"
    attach read %photos/
    send
    probe status
]
</code>```

My question then is: Is the Language X object approach/influence something to covet, or does one or other Rebol approach retain enough expressivity as complexity increases?

PS: Not just mail—I think about this with regard to the <canvas> tag and the idea of a procedural graphic format as opposed to the explicit <svg>.

答:
The Language X object approach/influence makes the instruction context explicit for each instruction. Dialects can make that context implicit, not having to repeatedly reference "message" as in the language "X" example. In the object world, "fluent interfaces" (noted by Robert in his comment) have been become popular to achieve a similar result.

A Rebol dialect can be arbitrarily powerful so I don't see that the language X object approach is one to covet. However, the object approach should be used as a benchmark - "is my dialect adding value over a simple object interface?", "does my dialect express the intent more clearly and simply?", "does the benefit of the dialect outweigh it's implementation cost?". If the dialect does not add value is it really required, or is there a better purpose for a dialect?

The hard part of dialects and of fluent interfaces is designing the interface/grammar. Goals like working out what expressions are useful to the client code, providing enough flexibility, robustness in the face of future changes and retaining "enough expressivity as complexity increases" do not seem to be easy.

Rebols value types are easy for a dialect interpreter to recognise, the type becomes a single value expression - set this variable with this value, like you've shown in your declarative dialect. Using the value types this way is really about using shortcuts (syntatic sugar) for some expressions. As complexity increases I think the approaches you've shown may have a problem because they are mixing conceptual contexts. For example, conceptually, the recipient email addresses will be used for two concepts: SMTP and RFC822. The file references are shortcuts for MIME expressions. If the dialect continues to mix multiple conceptuals contexts within it's keywords/values maybe it will become overly complex losing expressivity as more complex expressions are tried. Perhaps a way forward is to think of how dialects from different conceptual contexts will integrate so that expressivity is not lost as complexity increases. Shortcuts can be retained, but delving into a specific dialect as needed for expressions specific to that concept. The dialect might be embedded within another as a block introduced by its name represented as a word. As an aside, a MIME dialect could be reused outside of emails, for web purposes.

So I guess I'm suggesting a third approach, and I admit one I have not properly explored, in which shortcuts are provided for the simplest easiest uses as you've done and for finer control for a specific context call a named embedded dialect.