问:
What is abstraction?
Is there a generally agreed upon definition for what a programming abstraction is, as used by programmers? [Note, programming abstraction is not to be confused with dictionary definitions for the word "abstraction."] Is there an unambiguous, or even mathematical definition? What are some clear examples of abstractions?

答:
Interesting question. I don't know of a single definition of abstraction that is considered authoritative when it comes to programming. Though other folks have provided links to some definitions from various branches of CS theory or math; I like to think of it in a similar way to "supervenience" see http://en.wikipedia.org/wiki/Supervenience

When we talk about abstraction in programming, we are essentially comparing two descriptions of a system. Your code is a description of a program. An abstraction of your code would also be a description of that program but at a "higher" level. Of course you could have an even higher level abstraction of your original abstraction (e.g. a description of the program in a high-level system architecture vs. the description from the program in its detailed design).

Now what makes one description "higher-level" than another. The key is "multiple realizability" -- your abstraction of the program could be realized in many ways in many languages. Now you might say that one could produce multiple designs for a single program as well -- two people could produce two different high-level designs that both accurately describe the program. The equivalence of the realizations makes the difference.

When comparing programs or designs you must do so in a way that allows you do identify the key properties of the description at that level. You can get into complicated ways of saying a design is equivalent to another, but the easiest way to think about it is this -- can a single binary program satisfy the constraints of both descriptions?

So what makes one level of description higher than the other? Let's say that we have one level of description A (e.g. design documents) and another level of description B (e.g. source code). A is higher level than B because if A1 and A2 are two non-equivalent descriptions at level A, then realizations of those descriptions, B1 and B2 must also be non-equivalent at level B. However, the reverse doesn't necessarily hold true.

So if I can't produce a single binary program that satisfies two distinct design documents (i.e. the constraints of those designs would contradict each other), then source code that implements those designs must be different. But on the other hand, if I take two sets of source code that couldn't possibly be compiled into the same binary program, it still could be the case that the binaries resulting from compiling those two sets of source code both satisfy the same design document. Thus the design document is an "abstraction" of the source code.

Title: What is abstraction?


问:
What naming convention should you use for data objects solely meant for parameters
This is my pseudocode for DAL:

```<code>CusOrderDTO GetCustomerOrder(DateTime OrderDate, string customerCode)
    CusOrderDTO orderSet = new CusOrderDTO()
    * query data from database, populate CusOrderDTO
    return orderSet
</code>```

Now the parameters for the DAL have grown so large that I should pass a custom data object for parameter

```<code>CusOrderDTO GetCustomerOrder(SomeParameterClassName orderParameters)
</code>```

What naming convention is generally used for SomeParameterClassName? Naming it DTO seems weird since it's solely used for parameter purposes only and service layer is only going to work on CusOrderDTO object.

For the above, please assume that CusOrderDTO and orderParameters have nothing in common.

答:
I agree with MainMa: group locally connected objects. In case there is no other connection, there is still the request / query:

```<code>CusOrderDTO GetCustomerOrder(CustomerOrderQuery query)
</code>```

I add Request or Query to parameter objects.

ContentLicense: CC BY-SA 3.0

Body:
I agree with MainMa: group locally connected objects. In case there is no other connection, there is still the request / query:

CusOrderDTO GetCustomerOrder(CustomerOrderQuery query)

I add Request or Query to parameter objects.


问:
Content delivery design
I'm designing a system where users can access files stored in an external content storage service such as AWS's S3. Here's a simple diagram:

```<code> ------       ------------       -----------------
| User | <=> | Web Server | <=> | Content Storage |
 ------       ------------       -----------------
</code>```

The files are stored with a (long) unique ID. I'm concerned mainly about two things: performance and information security.

There are two options that come to mind but I'm sure it can be done in a better way (performance and security-wise):

Give the user a url with which the file can be downloaded directly from the content storage service. Cons: the URL could be brute forced. This could be solved putting a password to the file, but I'd like to use that as a last resort.

The web server downloads the file from content storage service and then serves it to the user. Cons: too much traffic.

Is there a way to make an HTTP redirect without exposing the file's resolved URL? Something like proxying packets?

I don't want to make this technology-specific (that's what SO is for), but just in case it adds any value, I'm using Rails a rails server behind nginx. I have full control over the web server, but I'm limited on the content storage service since I'm using S3.

答:
The only way I see now is to use REST authentication provided by Amazon

It creates expiring URLs that can be given to third-party. So, basically the idea is to login user to your website, check his permissions and then generate URL for him to download file from.

AWS IAM also can be used for that, but that limits the number of options, actually.

Title: Content delivery design


问:
Using and referencing external executables in a solution
I have an application written in AS3 which I need to be able to start up from my C# application. I have a prototype that does this just fine but my question is in relation to how I would arrange my solution to accommodate for this.

The way I had it in the prototype was using a post build script to copy the AS3 program directory into the output directory (Release or Debug), I then referenced it using Path.Combine as below:

```<code>private const string AS3_APP = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "ApplicationDir", "AS3App.exe");
</code>```

For something that's going into full development with long term support (probably a few years supporting this project, minimum) I'm wondering if there's a cleaner way of doing this. Something that is quite obvious to other working on the project but also isn't overly brittle.

The current thinking is that we will have a requirement to compile this AS3 application and then bring it into the solution; however as it is basically a Program Files folder, it'll be on the .gitignore. We will then use a post build script as I have done already which will copy the AS3 application into the output directory, but this feels quite hidden and awkward.

Are there any easier ways to do this in C# or any better ideas?

答:
In the end I put the compiled version into the main repository. The binary is required for it to run and so it's an actual dependency we decided.

We're only ever running the latest version of that executable so decided using tests etc against it's functionality won't be a problem. The approach just feels messy but we decided this would be the best approach for now.


问:
What is it called when you set properties on object initialization?
What is it called when you set properties on object initialization?

```<code>var customer = new Customer() {RequestID = request.ID, AddressID = 5};
</code>```

Is it considered good practice?

答:
One advantage of these initializers that noone has mentioned is that they prevent silly mistakes:

```<code>FileTransfer transfer = new FileTransfer();
transfer.ID = request.ID;
transfer.SourcePath = request.DownloadLink;
transfer.FileName = FileNameFromLink(request.DownloadLink);
transfer.SourcePath = request.Destination;
</code>```

This will compile, and be buggy.

```<code>FileTransfer transfer = new FileTransfer
{
    ID = request.ID,
    SourcePath = request.DownloadLink,
    FileName = FileNameFromLink(request.DownloadLink),
    SourcePath = request.Destination
};
</code>```

Now this will not, and so it'll help you spot that SourcePath is being set twice by mistake (instead of TargetPath)

Body:
One advantage of these initializers that noone has mentioned is that they prevent silly mistakes:

FileTransfer transfer = new FileTransfer();
transfer.ID = request.ID;
transfer.SourcePath = request.DownloadLink;
transfer.FileName = FileNameFromLink(request.DownloadLink);
transfer.SourcePath = request.Destination;

This will compile, and be buggy.

FileTransfer transfer = new FileTransfer
{
    ID = request.ID,
    SourcePath = request.DownloadLink,
    FileName = FileNameFromLink(request.DownloadLink),
    SourcePath = request.Destination
};

Now this will not, and so it'll help you spot that SourcePath is being set twice by mistake (instead of TargetPath)


问:
How to organize code which converts from one type to another
If I have a DateRange class, and I want to translate a DateRange into SQL (e.g. some_col >= '2015-3-5' AND some_col <= '2015-3-5'), where should I put the method that does the translating? Nothing I've come up so far with seems very good.

Option #1: Put a method in the DateRange class. (Downside: close coupling of the DateRange class and SQL?)

```<code>class DateRange {
    public function toSQL ($colName) {...}
}
</code>```

Opton #2: Make a class that only has one method in it?

```<code>class DateRangeTranslator {...}
</code>```

Option #3: a standalone function

```<code>function dateRangeToSQLWhereCondition (DateRange $dr, $colName) {...}
</code>```

I'm leaning towards option #2. But is there a better way?

EDIT:

It's a bit tedious but here's what I've got now:

```<code>class DateRangeSQLBuilder {
    public $dateRange;
    public function buildWhereCondition ($colName) {...}
}
</code>```

And you would use it like so:

```<code>$dateRange = new DateRange($fromDate, $toDate);
$builder = new DateRangeSQLBuilder($dateRange);
$whereConditions[] = $builder->buildWhereCondition('runDate');
</code>```

答:
tl;dr answer: DON'T.

PHP supports parameterised queries; make the most of their ability both to handle all the nasty implementation details of converting dates between PHP and SQL forms, because it will be quicker to do so and far more solidly tested than rolling your own.

In addition, you automatically get protection from SQL injection attacks that you didn't have before.

https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php


问:
Calling Web API vs adding reference to underlying dlls
This is more of an Architecture question, and I want to know all the possible pros and cons of the approach.

In my org, we have an ASP.NET Application say "A", a Web API Project say "W", and underlying DLLs say "D" which calls "E" which is physically on different server.

For most of the things (in SPA), we are making ajax call from A to W to access underlying functionality that is in D.

A and W are both deployed and hosted on same Web Server as different applications and W has reference to D so D is deployed with W.

For one of the functionality some server side processing needs to be done on ASPX page's code behind.

I am suggesting to my team to do keep calling from A to W using http client and maintain loose coupling that we have between Application A and the dlls D, but many (I would say everybody else in my team) is in favor of adding reference of D to A, so now D will be deployed with A alongside.

Is my suggestion not so good provided ease of implementation that we would be getting with adding direct reference for D in A? Let me know if I am not explanatory enough.

答:
Using a Web API allows you to program to an interface rather than a concrete implementation.

Need to generate an invoice (for example)?  Just call the Web API method to generate that invoice.  Should the need arise in the future to change the way invoicing works, you can just change the code behind the interface, (or swap it out for a completely different billing practice all together).

Tightly coupling your front end to a DLL introduces a dependency where none need exist.  This translates to a high maintenance cost when requirements change as both the application and the DLL will need to be updated.  Using a Web API allows you to change the business logic of the application without having to refactor the front end application.


问:
Validate polymorphic votes - Controller or Model?
I have a question because I don't want to do something wrong.

I have a polymorphic relation called votes. Well, I want to save votes but I need to validate if a user already has voted. But even if, in some cases a user can vote multiple times. It depends on the type (as said, polymorphic relation). I've set this data in a config file.

Now, where should I validate the votes? I thought I could do it in the model with a static method but then I'd be retrieving the config files in the model and also I'd have to return multiple errors. Something like "you have already voted" or "you can vote again in 1 hour".

I'd do that with some kind of error codes which I'd pass to the controller and then to the view to inform the user. But it seems wrong to me.

What would be the right way of doing this?

答:
I think you should validate your models in... model validators ;)

In my current architecture each model has an associated validator class, which contains validation logic. (Controllers have validators as well, but that's not the point). This is because validation logic can sometimes be complex enough, especially when models receive states.

To validate a model I just pass the result of $model->getAttributes() to a validator. The part, responsible for creating a validator and passing it attributes is now a part of my custom BaseModel class.

I've set it up so validation runs when model is saved. If model is invalid, exception is occured. So, the controller or service, saving the model, are responsible for it's validation.

Validation result is empty when validation succeeds or a hash of errors ('fieldName1' => ErrorsArray1). ErrorsArray is a standard Laravel's MessageBag, using which it's easy to render errors to user.

So, to model/controller it doesn't matter if User can't vote at all, or will be able to vote again in 1 hour. Model validator creates an error message (cannot_vote or cannot_vote_tmp) and just bubbles it to controller, which passes it to view. View translates message if needed and presents it to the user.

Currently errors are just enumerated and presented to user using a simple list next to the input field it is related to. But this logic can be extended. If it becomes complex enough, you can place some of it into a ViewComposer, which will take errors from controller, calculate some state from them and then pass this state into a View freeing it from complex calculations.


问:
Big graph traversal with OOP
I'm trying to solve a algorithmic contest's problem. I have a matrix 2000x2000. I want to represent it as graph and traverse it with BFS/DFS. I have time limits on app running (2s). Simple vertices creation took more than 2s! Just think of it - I'll need to create Adjacency matrix + run BFS/DFS + do some business logic so time will be increased more! Here is my attempt to create Graph vertices:

Map<Integer, Vertex> allVertices = new HashMap<>();

final long b = System.currentTimeMillis();
for (int i = 0; i < n; i++)
{
    for (int j = 0; j < m; j++)
    {
        final int id = i * m + j + 1;
        Vertex v = allVertices.get(id);
        if (v == null)
        {
            v = new Vertex(id);
            allVertices.put(id, v);
        }
    }
}
final long a = System.currentTimeMillis();
final long d = a - b;
System.out.println(String.format("took <%s> ms", d));

class Vertex
{
    Color color;
    final int id;

    public Vertex(final int id)
    {
        this.id = id;
    }
}
```

I wonder is this common practice to use OOP to represent big graph's vertices or I need to use arrays only?

答:
First of all, when you're creating your initial map, you can be confident each vertex isn't already present in it.  You're wasting a lot of time checking for that.

Second, in algorithm contests with that large of input and relatively small time constraints, the best solution usually only requires you to store one row of input at a time, plus some sort of cumulative result around the size of a row.  You should look for those kinds of solutions first.

Title: Big graph traversal with OOP


问:
Design: How to handle user permissions across a system
My team is currently working on a massive refactor of a medium-sized application in PHP. We are doing our best to refactor our code on a module (Orders, Users, Products) basis. The issue that I am currently wondering about has to do with handling what a user is allowed to do on our system.

Currently, this hinges on mostly on the User's Access Level to our system. Sometimes, we may have to reference their owning group to see if the higher level group is allowed to do something (place an order) and pass that permission on transitively to the user.

What I have come up with so far is a class called "Guardian". Guardian takes a User in and then has functions like "canPlaceOrder" or "canViewOrderReport". One benefit to this approach is that we are able to then see all of the actions on our system that require permissions in one place. In addition, this will allow us to separate our permission logic from our front-end and domain models.

However, I could see this not being an entirely scalable solution. Following the OOP principle that a class should be open for extension, closed for modification, I can see that as we add more permissions to our system, our Guardian class will have to add more methods as well.

I do like the benefit of having all of our permissions well defined in a human-readable way using one class, so that we always know that we are checking the correct criteria. However, I'm worried about scalability. Are there other approaches to this problem?

My question is really: What is a good way to handle this? Is my solution okay?

答:
The guardian shold have a

```<code>public boolean checkPermission(String permissionTag, int userID);
</code>```

method.

That way the guardian doesn't have to change when new permissions come to exist.

Usage

```<code>if (guardian.checkPermission("PLACE_ORDER",loggedUser)) {
    // place order
}
</code>```

Body:
The guardian shold have a

public boolean checkPermission(String permissionTag, int userID);

method.

That way the guardian doesn't have to change when new permissions come to exist.

Usage

if (guardian.checkPermission("PLACE_ORDER",loggedUser)) {
    // place order
}


答:
Your solution is okay.

Security and accessibility are pervasive in your system so having to add methods as permissions are added is workable.

Using character strings to identify permissions is okay in a PHP program since you won't ever find out that your code is wrong until run-time anyway. Character strings can be composed as well:

```<code>if ( guardian.checkPermissions(["PLACE_ORDER", "MODIFY_ORDER"]) ) {
  // place a modified order
}
</code>```

Title: Design: How to handle user permissions across a system

Body:
My team is currently working on a massive refactor of a medium-sized application in PHP. We are doing our best to refactor our code on a module (Orders, Users, Products) basis. The issue that I am currently wondering about has to do with handling what a user is allowed to do on our system.

Currently, this hinges on mostly on the User's Access Level to our system. Sometimes, we may have to reference their owning group to see if the higher level group is allowed to do something (place an order) and pass that permission on transitively to the user.

What I have come up with so far is a class called "Guardian". Guardian takes a User in and then has functions like "canPlaceOrder" or "canViewOrderReport". One benefit to this approach is that we are able to then see all of the actions on our system that require permissions in one place. In addition, this will allow us to separate our permission logic from our front-end and domain models.

However, I could see this not being an entirely scalable solution. Following the OOP principle that a class should be open for extension, closed for modification, I can see that as we add more permissions to our system, our Guardian class will have to add more methods as well.

I do like the benefit of having all of our permissions well defined in a human-readable way using one class, so that we always know that we are checking the correct criteria. However, I'm worried about scalability. Are there other approaches to this problem?

My question is really: What is a good way to handle this? Is my solution okay?

Body:
Your solution is okay.

Security and accessibility are pervasive in your system so having to add methods as permissions are added is workable.

Using character strings to identify permissions is okay in a PHP program since you won't ever find out that your code is wrong until run-time anyway. Character strings can be composed as well:

if ( guardian.checkPermissions(["PLACE_ORDER", "MODIFY_ORDER"]) ) {
  // place a modified order
}


问:
What do design and implementation mean?
The words "design" and "implementation" have been used widely. But I am not sure that I understand them.

What do design and implementation of a computer-related system (e.g.
a computer system, an OS, a programming language, a DBMS, a software
program) mean?

Think "design of a system" as a process, is its input the
requirements of the users of the system, and is its output the user
interface?

Think "implementation of a system" as a process, is its input a
design of the system, and is its output the system?

What are common in the design for a computer system, an OS, a
programming language, and a DBMS?

What are common in the implementation for a computer system, an OS,
a programming language, and a DBMS?

Thanks!

答:
In the context you are making this questions, 'design' is the process that is followed in the beginning of a project, where the requirements are defined, the technologies that will be used, the resources that are needed and the organization of the component that will be constructed. The 'implementation' is the next stage, when all the info from the 'design' step is used to begin constructing the component.

However, especially in Web applications, the difference between design and implementation slightly changes. The 'implementation' refers to the functionality of the application and how each function is being executed "backstage". The 'design' refers to aesthetic decisions about the Web app (such as styling, fonts, images etc.)

Title: What do design and implementation mean?


问:
What is the purpose of Code analysis and when do I need to use it?
I heard about Visual Studio's Code analysis but never used one. I've read MSDN, but still don't understand the real use of Code analysis.

Isn't it the same as StyleCop?

Somewhere, FxCop was also mentioned. What is the difference with Code analysis?

Do I need to use Code analysis for every project? Are code reviews done by my colleagues insufficient?

答:
What is Code analysis?

Code analysis (previously FxCop) is a static analysis tool which searches for common patterns which may indicate that something is wrong in the source code. For example, if an instance of a class which implements IDisposable is not disposed properly, Code analysis will emit a warning:

private void DoSomething()
{
    var connection = new SqlConnection(...);
    this.ChangeSomeData(connection);
}
```

<p>This is the correct implementation of the previous piece of code:</p>

<pre class="lang-cs prettyprint-override"><code>private void DoSomething()
{
    using (var connection = new SqlConnection(...))
    {
        this.ChangeSomeData(connection);
    }
}
</code>```

As any static analysis tools, Code analysis is intended to find patterns which are cumbersome (or simply boring) to find manually. For instance, in the previous example, it may be quite boring for a developer to check if any class he uses implements IDisposable (or to remember all .NET Framework classes which implement it).

Which projects qualify?

Although it is subject to false positives, as any static analysis tools, it is usually beneficial to target zero warnings for business-critical code without using suppressions. Within Visual Studio, Code analysis can be configured to run at compile-time; if project settings also specify that warnings should be treated as errors, violations of Code analysis rules won't stay unnoticed.

Since static analysis can take some time for medium or large projects, it is often a good idea to move it from developer's machines to the TFS build server. While running Code analysis during pre-commit is not a good idea (unlike StyleCop), it can still run on build and fail it if warnings are found.

For non-business-critical code, Code analysis may be run manually from Visual Studio or command line. The checks and warnings can be fine-grained in project properties to suit your needs. For instance, globalization warnings can be turned off if your project is not intended to be localized.

As with StyleCop, it is essential to decide whether the project will target zero warnings from Code analysis from the beginning of the project. Introducing it in an existent project may be too painful.

Is it different from StyleCop?

Note that code analysis is not the same thing as StyleCop. The first difference is that Code analysis works with the compiled assembly, while StyleCop works with the source itself. The second (and most important) difference is that Code analysis searches for patters which may indicate a bug, while StyleCop is simply enforcing style rules—a simple convention used by your team.

Code analysis is also particularly useful for beginners who don't know the language very well, since it can often lead to "Aha!" moments. For example, CA2105: Array fields should not be read only may lead somebody to a discovery that even if an array is marked as read-only, it doesn't make it immutable, since nothing forbids to change the elements within the array. StyleCop don't lead to discoveries: there is nothing interesting in knowing that fields start with a lowercase letter or that local calls should be prefixed with this.

Even if some rules are enforced by both Code analysis and StyleCop (such as CA1707: Identifiers should not contain underscores vs. SA1310: Field names must not contain underscore), those two tools are complementary and often used side by side.

We already have code reviews

The presence of code reviews is not a reason to avoid Code analysis. Both Code analysis and StyleCop are excellent at finding things automatically before a code review. There is nothing worse than spending a code review pinpointing style problems or problematic patterns which could have been found automatically. Keep code reviews for interesting stuff.

Another aspect is that human reviewers are not necessarily good at spotting problems found by Code analysis. For instance, an instance of a class implementing IDisposable may be created in one location, and then disposed in a different location. It will take some time for a reviewer to find it, while it takes just a few milliseconds for a static analysis tool to discover it.

Body:
What is Code analysis?

Code analysis (previously FxCop) is a static analysis tool which searches for common patterns which may indicate that something is wrong in the source code. For example, if an instance of a class which implements IDisposable is not disposed properly, Code analysis will emit a warning:

private void DoSomething()
{
    var connection = new SqlConnection(...);
    this.ChangeSomeData(connection);
}

This is the correct implementation of the previous piece of code:

private void DoSomething()
{
    using (var connection = new SqlConnection(...))
    {
        this.ChangeSomeData(connection);
    }
}

As any static analysis tools, Code analysis is intended to find patterns which are cumbersome (or simply boring) to find manually. For instance, in the previous example, it may be quite boring for a developer to check if any class he uses implements IDisposable (or to remember all .NET Framework classes which implement it).

Which projects qualify?

Although it is subject to false positives, as any static analysis tools, it is usually beneficial to target zero warnings for business-critical code without using suppressions. Within Visual Studio, Code analysis can be configured to run at compile-time; if project settings also specify that warnings should be treated as errors, violations of Code analysis rules won't stay unnoticed.

Since static analysis can take some time for medium or large projects, it is often a good idea to move it from developer's machines to the TFS build server. While running Code analysis during pre-commit is not a good idea (unlike StyleCop), it can still run on build and fail it if warnings are found.

For non-business-critical code, Code analysis may be run manually from Visual Studio or command line. The checks and warnings can be fine-grained in project properties to suit your needs. For instance, globalization warnings can be turned off if your project is not intended to be localized.

As with StyleCop, it is essential to decide whether the project will target zero warnings from Code analysis from the beginning of the project. Introducing it in an existent project may be too painful.

Is it different from StyleCop?

Note that code analysis is not the same thing as StyleCop. The first difference is that Code analysis works with the compiled assembly, while StyleCop works with the source itself. The second (and most important) difference is that Code analysis searches for patters which may indicate a bug, while StyleCop is simply enforcing style rules—a simple convention used by your team.

Code analysis is also particularly useful for beginners who don't know the language very well, since it can often lead to "Aha!" moments. For example, CA2105: Array fields should not be read only may lead somebody to a discovery that even if an array is marked as read-only, it doesn't make it immutable, since nothing forbids to change the elements within the array. StyleCop don't lead to discoveries: there is nothing interesting in knowing that fields start with a lowercase letter or that local calls should be prefixed with this.

Even if some rules are enforced by both Code analysis and StyleCop (such as CA1707: Identifiers should not contain underscores vs. SA1310: Field names must not contain underscore), those two tools are complementary and often used side by side.

We already have code reviews

The presence of code reviews is not a reason to avoid Code analysis. Both Code analysis and StyleCop are excellent at finding things automatically before a code review. There is nothing worse than spending a code review pinpointing style problems or problematic patterns which could have been found automatically. Keep code reviews for interesting stuff.

Another aspect is that human reviewers are not necessarily good at spotting problems found by Code analysis. For instance, an instance of a class implementing IDisposable may be created in one location, and then disposed in a different location. It will take some time for a reviewer to find it, while it takes just a few milliseconds for a static analysis tool to discover it.


问:
Version number for a pre release software that will be the second major release
If we have an app that is not finished already, but we release it, we use a version number like 0.x.x and when it is finished it will be published as 1.0.0.

Now the app's latest version is 1.2.6 and since then it wasn't updated for years, because we rewrite it from scratch and that will be the 2.0.0 release, but we would like to make a pre release like we did it with the first version. What should be the version number?

1.x.x would indicate that it is an update for the first major version, and 2.x.x would say it is a finished second major version. Both statements would be wrong. What to do?

答:
You may follow the:

major.minor[.build[.revision]]

schema, which means that the version 2.0.0 will be the first build of the rewritten project. It doesn't matter if it is released in production, given to the testers or kept in secrecy.

Then, an actual pre-release may be, for instance, 2.0.19.527, and the actual public release may be 2.0.37.692. This will clearly indicate to your customers that this is a second version of your product, given that nobody will ask for 2.0.37.691 or 2.0.36.

This is also used in Windows: the actual release version is never n.0.0.0. For instance, from Wikipedia:

A post-RTM build of Windows 8, build 9364, leaked in March 2013.

or:

Build 9600 of Windows 8.1 was released to OEM hardware partners on August 27, 2013.


答:
There are pre-release phases for software products: alpha, beta, and release candidate. It depends on how mature your product is. An alpha release would tend to indicate that the application is still relatively unstable and perhaps buggy. This would be anything up to a feature-complete release. As you move toward feature-complete, you may want to consider your software a beta release. It may still be buggy at this point, but it should be stable enough for demonstrations and previews. A release candidate should be feature complete, but may still have some bugs.

You would apply these to your "2.0.0" version. So your "2.0.0 Alpha" is an alpha release of what will become 2.0.0 software. You can change Alpha to Beta and then Release Candidate (or RC) as your software becomes more stable. Sometimes, instead of spelling the words out, it is shortened to "2.0.0a", "2.0.0b", and "2.0.0rc" for the alpha, beta, and release candidate versions of 2.0.0. If you did multiple builds that could be considered a release, you could also append a number after the letters. For example, if you did three beta releases leading up to 2.0.0, they would be 2.0.0b, 2.0.0b1, and so on (you could index from 0 or even call your first beta b1, if you wanted).

Wikipedia also has a length discussion of software versioning. It discusses various versioning schemes used by different applications. It includes a brief discussion of pre-release versions as well. Considering that this is a rewrite of an application, you could throw away the old versioning scheme and choose a more appropriate one if you wanted to.

Title: Version number for a pre release software that will be the second major release

Body:
If we have an app that is not finished already, but we release it, we use a version number like 0.x.x and when it is finished it will be published as 1.0.0.

Now the app's latest version is 1.2.6 and since then it wasn't updated for years, because we rewrite it from scratch and that will be the 2.0.0 release, but we would like to make a pre release like we did it with the first version. What should be the version number?

1.x.x would indicate that it is an update for the first major version, and 2.x.x would say it is a finished second major version. Both statements would be wrong. What to do?


问:
One commit in two branches: what happened?
I work on a project using maven and svn.

Today after a svn update, the maven build was failing on the svn trunk. When I looked in the svn logs, I saw something strange: a commit affecting two branches. Few files were commited on the foo branch - the expected result of this commit - and one were commited on the trunk (the reason of the maven fail), all of this in one commit.

This commit was made on Eclipse using a SVN plugin (I don't know which one). Merges between this two branches had already been made few days ago, and the developer had an up to date working copy.

This was fixed easily by reverting the delictuous file, but I don't understand what happend and I would like to understand it. Is this the result of an unfixed conflict, or an auto-commited unstaged file from a switched branch ? On svn, isn't a working copy "linked" to one branch ?

答:
As previously noted in the comments, a commit which affects a branch and a trunk at the same time is technically possible, so it looks more like PEBCAK.

I can see two reasons.

The person had both the trunk and the branch checked out, and the person mistakenly changed the trunk when thinking he was working on the branch. It happens.

There is a symlink pointing at the files in the trunk, so changing the branch actually affected the trunk as well.


问:
Agile: QA without dedicated test resource
I'm currently working in a small internal software development team of four people. Having had a lot of success with Agile in the past (which none of my colleagues have used before), I'm keen to try and move toward a more Agile process.

The problem is that we have no dedicated QA resource. This isn't as dangerous as it sounds: 90% of the work we do is on internal projects and the "test team" ends up being the users doing UAT. Obviously it's not ideal - they're not as fast or as thorough as dedicated QA, but in essence, it works.

We currently do incremental releases and demos, after which the users do some testing and mark stuff as done. However, I'm struggling to see how we could fit this process into the traditional Agile framework.

I understand the importance of finishing a task within a sprint, and of not marking a feature as complete until its been tested. I also appreciate we can do a lot of automated testing but, in my experience, there are often a lot of requirements that aren't suitable for an automated test and need some sort of QA.

As it stands, we can't have any testing done until after release. And we can't have any control over when that testing gets done (the users have other jobs to do). And we can't have a dedicated QA resource (I have asked, but I'm in a chicken and egg situation of needing to prove this works before we get budget).

What can I do? Is it good enough just to do our meager internal/automated tests and mark things as "done" for now, with UAT being a separate stage? Or is there any way we can better integrate UAT into sprint cycles?

There are other questions

Coding and testing in the same sprint

Dilemma of QA vs. iterations

Viability of a Development Team with no *dedicated* Tester role

These appear similar to the issue central to this one, however, those answers all presume an existing QA team, just one that doesn't work in sync with the developers. In this situation there is no QA. In effect, the usual middle layer of testing is entirely absent.

答:
I would recommend having your development team try to take on the role of user acceptance testing, at least to the extent possible. It may not be as effective as the actual users, at least until the developers have a strong understanding of the domain and how the users carry out their work in the software, but it will help catch the big things before you get your users involved and will help drive an understanding of the domain.

As a story is complete, someone on the development team can take on the role of testing that story. Depending on your development process, perhaps even someone who wasn't previously involved in the story previously could be responsible for the final UAT. This would allow the development team to gain some insight into how the users are actually using the software and will drive design decisions.

There are some downsides, though. Your velocity will be reduced as you will need to allocate developers to perform this UAT role. However, I think that the increase in understanding of the users roles and needs and the ability to deliver higher quality software will outweigh the reduced velocity.


问:
What architecture/design to adopt when consuming a RESTful API? (iOS App)

TL;DR

Part 1)

I want to refactor the biggest part of the app on which I work - and it is pretty much spaghetti. It's a single class that makes the requests to the server, parses the JSON, and saves the data in the database (it also has knowledge of some UI that needs to change when specific business rules are met and it definitely shouldn't know all this stuff). It has somewhere below 5000 LOC :(.

One way of breaking the class in smaller pieces would be to separate the requests by semantics (for example User requests, Search requests etc). Would that be useful or not really?

Also, I think that networking code should be decoupled from the parsing code and also from the DB code. The problem is that I don't really know what approach (architecture/design pattern) should I use to do this the best way. (for example, our JSON parsing library is old and is not maintained anymore - we wanted to change it because it produced some problems and we were stuck because of the tight-coupling).

Part 2)

I also would like to receive some suggestions for the following issue:
We use the DB mostly for offline mode & caching. The user can see data in offline mode, modify it (and requests get serialized) and when he gets back online, the requests will be made to the server. We also use it as a cache to show something on the UI while we do a request in the background to see if there is new/modified data (we use a similar mechanism like ETag to check with the server).

So this is the flow when a user enters a screen:

```<code>enter_screen ->
check_cache + background_request ->
show_UI with cache data ->
update_UI when the background request finishes and new/modified data is available.
</code>```

Can this stuff be abstracted away somehow? I was thinking of some kind of delegate pattern where I get an immediate callback when I hit the cache and then get a later callback when the request finishes (with optional flags to distinguish between cache and fresh data).

A bit of a background story

I currently work for an iOS app that is aprox. 4 years old. I only joined the team a year ago. In my opinion, the code is ugly, full of hacks, and has a very shaky architecture. We are 2 iOS developers working on it. The client doesn't have the technical expertise and may not understand all the implications of some issues that we have. Making a client understand why "refactoring" is needed, is a hard task. I struggle to refactor how much I can, but we still have a lot to go trough.

The app also has a lot of features that increases the complexity of the app: deeplinks, push notifications, offline mode, non blocking UI etc. all combined with a rather large and hairy data model.

Because the client requests features in a constant manner, I feel that we have a lot of technical debt.

The mobile world is changing pretty fast and new technologies appear (Size classes, Auto Layout, Swift, etc.). This is true for all technologies, but I somehow feel that the race is a bit more intense in the mobile world. Currently, I only dream of using Swift at work (although  I play with it at home in my spare time).

答:
I can see some sensible answers to this question already, but I thought I would expand and offer my opinion.

You've described a system that appears to couple logic into large classes, and be tightly coupled across many different functions. The first way to try and refactor this is to first ensure you understand what a 'good' architecture/codebase would look like.

Hopefully you are familiar with SOLID development principles, but if not this is going to really apply here. I will pick a couple of the principles that will ultimately apply to you, but you should ensure you understand them all.

Single Responsibility Principle (SRP - or the S in SOLID) advises ensuring that you create classes that only deal with one thing, and one thing only. Using this principle, you should see code that is focused on individual tasks, and are ignorant to anything outside of their scope. For instance, your networking code should not have anything to do with JSON parsing, as that is a separate responsibility entirely.

Dependency Inversion (DI - of the D in SOLID) states that classes should 'depend upon abstractions. Do not depend on concretions'. This goes hand in hand with ISP, in that a consuming class should use a dependency on an interface, leaving an IOC container to inject the appropriate concrete class as required. This removes dependencies from your code, and helps enforce SRP, as well as making testing much easier.

Hopefully that gives you an idea of what good code quality consists of. If SOLID is followed in the codebase, you should see classes coding against interfaces, with dependencies injected in. Classes should be singularly focused on their domain, and not performing other tasks.

So with regards to the architecture, you can begin to separate logic into distinct layers, with logic between the layers being handled via service calls. A very common approach to this is the Model-View-Controller architecture, which separates UI into a View, data into a model, and wiring logic into a controller. This is typically supported with a lower 'service' level, which provides specialised functionality, such as JSON parsing, data access etc. The service layer should be separate from the above, and expose an interface, most commonly through a RESTful API.

With the above in place, your example of replacing the JSON parser would now require that you simply write a new concrete class that implements the IJsonParser interface (or whatever it may be) and is wired up through your IOC (Dependency Injection) container. So long as the new class implements all of the logic in the interface, then that should be the only change required.

I think the second question warrants a seperate question on this thread, as it could potentially lead to some confusion in this answer, and certainly has a lot of options to it.

ContentLicense: CC BY-SA 4.0


答:
It sounds like there's little difference in terms of coupling. If you're coding against the WebAPI directly, you're dependent on its interfaces. If you code directly against the DLL, you're dependent on its interfaces.

Make the distinction irrelevant. Your application ideally shouldn't have to know or care whether it's ultimately leveraging a web service, local service, or local library -- or even what language or technology that underlying functionality is built on. Pick your favorite type of wrapper and really decouple the application from both the API and the DLL. You can build (or extend) wrappers for both and test both for performance, maintainability, etc.

Title: Calling Web API vs adding reference to underlying dlls

Body:
This is more of an Architecture question, and I want to know all the possible pros and cons of the approach.

In my org, we have an ASP.NET Application say "A", a Web API Project say "W", and underlying DLLs say "D" which calls "E" which is physically on different server.

For most of the things (in SPA), we are making ajax call from A to W to access underlying functionality that is in D.

A and W are both deployed and hosted on same Web Server as different applications and W has reference to D so D is deployed with W.

For one of the functionality some server side processing needs to be done on ASPX page's code behind.

I am suggesting to my team to do keep calling from A to W using http client and maintain loose coupling that we have between Application A and the dlls D, but many (I would say everybody else in my team) is in favor of adding reference of D to A, so now D will be deployed with A alongside.

Is my suggestion not so good provided ease of implementation that we would be getting with adding direct reference for D in A? Let me know if I am not explanatory enough.


问:
Should a Java Boolean be used for ternary (3-state) logic?
I'm trying to make a basic cache of a boolean value, and I did it like such:

private Boolean _valueCache = null;
private boolean getValue() {
    try {
        if (_valueCache == null) { // if cache was never filled
            return _valueCache = getReader().getMyBooleanProperty(); // fill it and return the new value
        }
        return _valueCache; // else, return the cache
    } catch (NullPointerException ex) { // getReader() returned null
        return false; // that return may not be null in the future, so set nothing
    }
}
```

Does this go against best practices? (letting a Boolean have 3 values: true, false, and null) I only want to cache this value, so I don't want to make an entire custom HashMap that mimics this behavior with a get-or-default method. That said, I've never done a cache this small so I don't know the downsides to it.

To clarify, I meant "ternary" as in "3-state", as opposed to "binary" as in "2-state". Sorry for any confusion.

答:
You're not doing ternary logic, you're just using null as a placeholder for a missing value that happens to be of type Boolean. (Not having true nor false isn't quite the same as having one of the two but not knowing which.) Using null this way is a fairly common practice, but I wouldn't call it a good one.

It's unlikely to cause you problems in this particular case because it's only used internally within a very small scope, but in general you would want to use Optional instead. Since any non-primitive variable could have null, it's very difficult to keep track of it in a large code base. The easiest way to avoid the issue is to not use null in the first place.


问:
Building Data abstraction for rational numbers using "objects"
I follow this definition of "object":An object is a value exporting a procedural interface to data or behavior. Objects use procedural abstraction for information hiding, not type abstraction. Object and and their types are often recursive. Objects provide a simple and powerful form of data abstraction. They can be understood as closures, first-class modules, records of functions, or processes. Objects can also be used for procedural abstraction. from this paper

It is taught in class that data abstraction is the methodology to create barrier between "how data values are used" and "how data values are represented". It is taught that, an abstract data type(ADT) is some collection of selectors and constructors, together with some behaviour conditions (invariants).

It is compound data that needs data processing which actually enables to think about data abstraction because the user would like to use this compound data as single unit.

Building "data abstraction" and "ADT" for "rational number" using python objects

#Use
def mulRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    return Rational(getNumer(x)*getNumer(y), getDenom(x)*getDenom(y)) #x and y are abstract data

def addRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    nx, dx = getNumer(x), getDenom(x)
    ny, dy = getNumer(y), getDenom(y)
    return Rational(nx * dy + ny * dx, dx * dy)

def eqRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    return getNumer(x) * getDenom(y) == getNumer(y) * getDenom(x)

def toString(x):
    """Violate abstraction by using other than constructor and selectors"""
    return '{0}/{1}'.format(getNumer(x), getDenom(x))

#Representation
# Representation is provided by constructors and selectors using tuples

#Constructor
from fractions import gcd
def Rational(n, d):
    """Construct a rational number x that represents n/d."""
    g = gcd(n, d)
    return (n // g, d // g) #this is concrete representation of a rational number

#Selector
from operator import getitem
def getNumer(x):
    """Return the numerator of rational number x."""
    return getitem(x, 0)

#Selector
def getDenom(x):
    """Return the denominator of rational number x."""
    return getitem(x, 1)
```

<p>Rational number has compound data <code>(n,d)</code> that enables to build data abstraction, Because user would like to use this compound data as single unit.</p>

<p>Below implementation is done with different "representation".</p>

<pre class="lang-py prettyprint-override"><code>#Use
def mulRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    return pair(getitem_pair(x,0) * getitem_pair(y,0), getitem_pair(x,1) * getitem_pair(y,1))

def addRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    nx, dx = getitem_pair(x,0), getitem_pair(x,1)
    ny, dy = getitem_pair(y,0), getitem_pair(y,1)
    return pair(nx * dy + ny * dx, dx * dy)

def eqRational(x, y):
    """Violate abstraction by using other than constructor and selectors"""
    return getitem_pair(x,0) * getitem_pair(y,1) == getitem_pair(y,0) * getitem_pair(x,1)

def toString(x):
    """Violate abstraction by using other than constructor and selectors"""
    return '{0}/{1}'.format(getitem_pair(x,0), getitem_pair(x,1))

#Representation
#Representation is provided by constructors and selectors using higher order functions

#Constructor
def pair(x, y):
    from fractions import gcd
    g = gcd(x, y)
    """Return a functional pair"""
    def dispatch(m):
        if m == 0:
            return x // g

        elif m == 1:
            return y // g
    return dispatch

#Selector
def getitem_pair(p, i):
    """Return the element at index of pair p"""
    return p(i)
</code>```

In the above code, Constructors & selectors constitute ADT.

In the above two implementations:

There is an abstract data type that supports an invariant:

a) If we construct rational number x from numerator n and denominator d, then  getNumer(x)/getDenom(x) must equal n/d.

b) If we construct rational number x from numerator n and denominator d then getitem_pair(p, 0)/getitem_pair(p, 1) must equal n/d

In the above 2 implementations we have 3 abstraction barriers:

Parts of the program that work with rational numbers to perform computation use mulRational(..), addRational(..), eqRational(..) && toString(..) computation processes only.

Parts of the program that implement mulRational(..) use constructor and selectors only.

Parts of the program that implement constructors & selectors would use built in datatypes or built-in functions.

My question:

Is my understanding correct on designing data abstraction and ADT for rational numbers? I disagree with below three points.

1)
This paper says: "While objects and ADTs are fundamentally different, they are both forms of data abstraction."

2)
This paper: "An abstract data type is a structure that implements a new type by hiding the  representation of the type and supplying operations to manipulate its values."

3)
This paper says:  "Abstract data types depend upon a static type system to enforce type abstraction."

Reason,

In the above code,

Firstly,  Data abstraction has it's own identity by enforcing a barrier between "representation" and "use". Each above implementation has set of "objects" that build Data abstraction and  supply operations[mulRational]

Secondly, ADT is just the collection of "constructor" and "selectors" which support some invariants to validate the "representation". ADT in the above code did not implement a new type. ADT did not supply operations. ADT does not require type system.

答:
Let's first clear up some of your terminology.

Abstraction is a technique for managing complexity of computer systems. It works by establishing a level of complexity on which a person interacts with the system, suppressing the more complex details below the current level.

So, for example, writing a method that hides some complex functionality is an abstraction.  You call the method and it performs its function, without concerning you about the details hidden in the method.

Data abstraction is just that same process applied to data, in the form of data structures.

An Abstract Data Type (ADT) is a mathematical model for a certain class of data structures that have similar behavior; or for certain data types of one or more programming languages that have similar semantics.

An abstract data type is defined only by the operations that may be performed on it and by mathematical pre-conditions and constraints on the effects (and possibly cost) of those operations.

Now then.  Let's look at your assertions:

Parts of the program that work with rational numbers to perform computation use mulRational(..), addRational(..), eqRational(..) && toString(..) computation processes only

Right, so you've defined an API that provides certain operations, hiding the complexity behind method calls.

Parts of the program that create rational number use, "constructor" and parts of the program that implement more new rational operations like divideRational(..) use, "selectors" only.

That seems consistent with the idea of an ADT being defined by its operations (among other things).

Parts of the program that implement constructors & selectors would use built in datatypes or built-in functions.

I would consider that self-evident.  Every programming language eventually resolves to a set of primitives upon which all other abstractions are built.

If you're getting the feeling that Abstract Data Types are merely a sophisticated form of encapsulation, you're right.


问:
What are good interview questions for a Software Tester with focus on automation?
Today's testing is not much like yesterday's testing. More services, more distributed systems, more automation. I want the kind of testers that are self-starters and will constantly work themselves out of the job by writing test code. What are good interview questions for the modern software tester?</p>

答:
Beyond the technical stuff (ensuring they have the skills to do the job), I tend to be most concerned with three things:

Can they learn? - Good testers learn quickly and make a significant effort to learn. Ask them how they learn - or to give an example of when they had to learn something quickly and what the learning allowed them to do.

Can they deal with ambiguity? Testing relies a lot on figuring out how things work and the ability to ask the right clarifying questions to not head off in the wrong direction. Any sort of ambiguous question would work well for this, but I sometimes double up this with actual testing by asking "How would you test {foo}?" where {foo} is a web page, windows notepad, or something else small enough to discuss in full, but with enough meat where they should ask questions about the context and scope.

Can they see the big picture? - systems thinking - or at least a notion of seeing beyond what's right in front their faces is a good indicator of successful testing. For example, when they run into a problem, do they see it at the surface level only, or can they see how the pieces of the system interact and understand why the problem happened. This, while important for debugging, is more important for isolating issues - especially intermittent issues. You may get an inkling for this from the web page question above, but any question on dealing with complexity and interaction will help get a feeling for this.

ContentLicense: CC BY-SA 2.5


答:
From Martin Fowler

My First Law of Distributed Object Design: Don't distribute your objects

Why opt to incur the overhead and instability of a web service if the business logic you want is in a DLL? Reference the DLL and keep all methods calls local, snappy and stable.

If you were creating your web site in a non .NET language then you've got a good case to use a web service, but this is not the case.

Even if you didn't have access to the DLL code base, you can stand up an internal Nuget package server and use Nuget to manage that dependency.

If the web service has additional business logic that you need then use it. If not, use the DLL.


问:
How to ensure a new Unit Test is for the correct Test Case?
When writing a unit test for a scenario believed to be already covered, ie, the first run of the test would be green, what is a good guideline to ensure that it is in fact testing the proper test case, and not a test that 'always' passes, or passes for reasons that have nothing to do with the test case being considered ?

I believe the best practice is to change your class under test, so that it fails first, and then remove the intentional bug to see if it turns green, however that explanation is too vague. At an extreme, I could simply make my constructor throw an exception to get a red test, then remove the throw to make it green. I know the breaking change should be something 'close' to the scenario under test, but am not sure how to word it as a proper guideline that my juniors could follow.

答:
what is a good guideline to ensure that it is in fact testing the proper test case

This falls back to the old "who tests the tests?" line of thinking.

And in general, nobody can test the tests. Unit tests have proven themselves so successful in part because they are small enough that they can be implemented without error. A good guideline is that another developer can look at the test and say "yes, that appears to test what it says it does".

That is enough to catch the majority of issues. The rest is part of a good layered approach to software quality. Even if the test is wrong, QA or user acceptance testing can help catch things that escape the test. That reduces the risk of a bug escaping into production to an acceptable amount.


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

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

or should it be

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

or even

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

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

答:
Ah, the One True Brace Style.

It has everything neded for a Holy Way - even a prophet (Richard "my way or the highway" Stallman).

The guy was so wrong about so many things, but GNU is spot-on when it comes to braces.

[Update] I have seen the light, and now worship Allman


问:
Avoiding std::forward and Rvalue References
I recently read the Google C++ Style Guide and especially one part catched my eye.

The part about Rvalue References discourages from using std::forward in general and using rvalue references in other cases than defining the move assignment operator and constructor.

The only argument given for this is that these are complicated, diffcult to understand features.

Are there other arguments for avoiding these features?

答:
No. The Google style guide makes no sense for anybody except Google. And even for them it's highly questionable. The best approach to take is to forget the Google Style Guide and everything you've read in it, because it's junk.

Rvalue references are a great and wonderful thing that drastically improved C++. Not using them will consign your code to the pits of Hell. They are the number one most important feature in C++11.


问:
For asp.net mvc is this a three tiered solution?
I am a asp.net mvc programmer and if I want to start a project I do this:

I make a class library named Model for my models.

I make a class library named Infrastructure.Repository for database processes

I make a class library named Application for business logic layer

And finally I make a MVC project for the UI.

But now some things are confusing me.

Am I using 3-tier programming?
If yes so what is n-tier programming and which one is better?
If no so what is 3-tier programming?

Some where I see that the tiers namings are DAL and BIZ.

Which one is correct according to the naming convention?

答:
As an amendment to the above answer (and a bit of a history lesson), "3-tier" and "n-tier" are the same where n=3.  Back in the dark ages, application code and data were all in the same assembly (and "computing machines" were the size of rooms).  That quickly changed, and "data files" were invented, creating a two-layered (still single-tiered) architecture.  Some other things happened, and eventually the RDBMS came along, which was housed on its own computer, and the age of "client-server" computing was born.

Once the concept of separating the concerns of "program logic" (which included presentation-, business-, and application-logic in today's parlance) from "database logic" (persistence) was digested, business and application logic was moved to a "middle-tier", and suddenly we had "three-tier computing".  It spread in the early nineties, and coincided with the explosion of the Internet and the World Wide Web.

From three-tier, it was a short logical leap to spreading things across many layers, and separating those layers across many execution environments, sometimes for security, other times for maintenance, often for performance.  Tiring of the idea of having to describe things in quickly-increasing numerics, the phrase "n-tier" was born, and really describes any application architecture that spreads itself across multiple execution environments.

Note that today, with virtual machines, multi-core processors, and parallel computing, it's hard to say what code is running on what discreet processor, or how its separated from another "layer" on another "tier", but we like to put things in containers, whether or not the container has any real boundaries.


问:
OOP implementation doubts with databases
I was starting a project today and after designing the database structure and how the data would be stored etc, I started the implementation. I am doing this on php, but the language isn't really relevant here, since my doubts are more architectured related or I guess, since I'm struggling more than I thought by implenting stuff in OOP on PHP. (Recently jumped on php, I've been coding in c++ and java before).

So, I started by creating my "User" class, simple as that, few attributes, and __construct, insert, update and delete methods. Those last 3, queries to the db.

Then this doubt came to my head, and I probably know the answer myself but I just don't find out.

I can now create instances and create new Users: $user = new User("John", 34) but, what if I want to edit the user "Dave"? Or I want to show all users. That method, for example, getAllUsers() which would return all users where would be implemented? Because it doesn't really belong to the class User right? If it did, then how I would instance that method if I don't have any User instance?

I guess, I would need a class Users, or UserCollection which would be a collection of all the users, with the methods ´getCertainUser(id)´ and ´getAllUsers()´ which would return certain User or All of them, now then I would have a User I would be able to edit.
That is the way I've did in both Java and C++, since I didn't use a database to store the data, it was stored on a Set/Map or whatever the structure, and then saved on files.

That being said, my questions is, how this problem should be addressed as the way to go, Am I complicating things too much? How this should be solved 'the correct way' in OOP. The times I've handled similar problems I've never used a database, so having a collection of users was the only way to store them, but having the database which stores the users feels redundant to have that collection of users.

Thanks in advance.

答:
The problem should be addressed by separating concerns

Here is what I mean.

The reason why you have a bad feeling about adding the getAllUsers() to the User class is because it is too much responsibility for that class. This could convolute things down the line - especially when trying to test things.

My suggesting would be to rethink the way you are doing it.

Instead of making the User class know about all of those things such as inserting itself, updating itself and maybe returning all of the users - make it instead a DTO object that doesn't know about anything.

Then have a UserManager that takes in that DTO which can insert it into the database, update it, delete it and have a UserReader or UserRetriever (or some other name that gets the point across) that either returns back all users as a list of DTOs or a specific user based on the id.

This way it makes testing easier and makes sense conceptually which is key when - you want others to contribute to the project or just maintain it yourself.


答:
If you're looking for 'the correct way' to marry Object Oriented code with Relational Database persistence, you're going to be sorely disappointed. There is no single 'correct way', only a range of options.

Some would recommend separating your concerns (as AvetisG has suggested in his answer), by putting business logic in one class and persistence logic in another. An example of this, using the Repository pattern, is given in this SO question/answer.

Others feel perfectly fine combining all of the User-related stuff, including persistence, in the same object. An example of this is the Active Record pattern.

I would suggest you familiarize yourself with these alternatives, and then go with whatever makes the most sense to you. In the end, that'll be the most correct way.

Title: OOP implementation doubts with databases

Body:
I was starting a project today and after designing the database structure and how the data would be stored etc, I started the implementation. I am doing this on php, but the language isn't really relevant here, since my doubts are more architectured related or I guess, since I'm struggling more than I thought by implenting stuff in OOP on PHP. (Recently jumped on php, I've been coding in c++ and java before).

So, I started by creating my "User" class, simple as that, few attributes, and __construct, insert, update and delete methods. Those last 3, queries to the db.

Then this doubt came to my head, and I probably know the answer myself but I just don't find out.

I can now create instances and create new Users: $user = new User("John", 34) but, what if I want to edit the user "Dave"? Or I want to show all users. That method, for example, getAllUsers() which would return all users where would be implemented? Because it doesn't really belong to the class User right? If it did, then how I would instance that method if I don't have any User instance?

I guess, I would need a class Users, or UserCollection which would be a collection of all the users, with the methods ´getCertainUser(id)´ and ´getAllUsers()´ which would return certain User or All of them, now then I would have a User I would be able to edit.
That is the way I've did in both Java and C++, since I didn't use a database to store the data, it was stored on a Set/Map or whatever the structure, and then saved on files.

That being said, my questions is, how this problem should be addressed as the way to go, Am I complicating things too much? How this should be solved 'the correct way' in OOP. The times I've handled similar problems I've never used a database, so having a collection of users was the only way to store them, but having the database which stores the users feels redundant to have that collection of users.

Thanks in advance.


问:
Advice on new git / deployment workflow
I work with a small team that until recently didn't use source control. I'm working on the layout of our development/deployment workflow with git. I would appreciate and advice or insight you might have.

I'll spare you the details but we are basically using the git flow branching model and deploying with a remote pointed to a bare repo on the production server with a post-recieve hook. My question is with a larger project we have been developing. This is an application that will have many instances that will need to be able to update from the master branch of the applications repo but also have it's own set of unique files (front end project specific files).

I'm a little lost and I think it may be because I have the deployment scheme a little off. I've heard many people say "git isn't for deployment" and an equal number saying the opposite. The system works great for us currently pushing to the remote that deploys it based on that server's post-receive hook.

One deployment idea we have is to have a list of branches from the App's master that will have it's own 'projectA-master' and 'projectA-develop' branches that will follow our current git workflow. This leads us to having MANY branches on the original App repo and that feels wrong. Not to mention it doesn't scale well. We only have four servers slated for deployment but this method is awful when it gets to be 20 or more. That's a deal breaker.

```<code>master---A---B---C
   \\ \
    \\ develop--A--B--C
     \\
      \projectA-master--C--D--E
       projectA-develop--C--D--E
</code>```

Yuck.

Another idea was to have the App repo for development and updates and another repo (maybe App-frontend) that would be specific to each project and have a similar branching model above only not in the original App repo preserving it's code and branches to only core app specific development. Then having both deploy into the remote server.

```<code>master(App)---A---B---C---E---F----G
    \                            /  \___
     develop---A---B---C---E----F    ___ Live Instance
                                    /
master(App-frontend)---A---B---C---E
    \                             /
     develop---A---B---C----E----F
</code>```

This too feels wrong.

I used .gitignore to ignore all of the directories that are project specific but the problem I had there was that my FE files were not being source controlled on the remote server, they remained un-tracked.

I don't know how to push updates from the app master repo and not override the custom files on the project specific (remote server repo) level.

So how do you manage a situation like this? You've a product that will have many instances but each instance has client specific front end files. And how is this managed on a large scale of hundreds to thousands of instances and you still need to push out updates/fixes?

I've been all over these and other forums and I've gotten pretty far from not really utilizing git at all. If you have the time I would appreciate some input from those of you more experienced that can tell me what I'm doing wrong and what I'm doing right.

Thank you very much.

答:
Those unique files, are they installation specific? This is usually solved by putting properties in local config files (or in the registry for Windows), making sure these are not overwritten after each update of the application.

If you need central management of these files, you need some kind of datastore to host a config file per instance. You could use git for that, a branch per installation, or just one branch with a folder per installation, but it could also be a simple FTP server or a database. This should be kept separate from the main deployment artifact, since they should not be tagged or branched with the main application.

Title: Advice on new git / deployment workflow


答:
Even though it is right that you should not start testing your tests the ability of a test to fail is crucial. A test which cannot fail is not only useless - it also indicates that you ...

made logical mistakes

just wanted to do some quick testing without thinking it through or

are testing the language (e.g. unsigned >= 0) or general logic (true || false)

If you already have the code implemented please don't make the test fail by crashing the program. The following test will allways fail, even though it is a tautology.

```<code>#include <gtest/gtest.h>

TEST(test,testcase) {
    throw 1;
    EXPECT_TRUE(true);
}

int main(int argc, char ** argv) {
    ::testing::InitGoogleTest(&argc,argv);
    return RUN_ALL_TESTS();
}
</code>```

(Maybe there are test frameworks in which this test would still pass, but there is at least one in which it gives you false security.)

Instead just write a quick "empty implementation" which has the same interface and simply does nothing. You then - when all tests failed - switch out the dummy with the real implementation.

Title: How to ensure a new Unit Test is for the correct Test Case?

Body:
When writing a unit test for a scenario believed to be already covered, ie, the first run of the test would be green, what is a good guideline to ensure that it is in fact testing the proper test case, and not a test that 'always' passes, or passes for reasons that have nothing to do with the test case being considered ?

I believe the best practice is to change your class under test, so that it fails first, and then remove the intentional bug to see if it turns green, however that explanation is too vague. At an extreme, I could simply make my constructor throw an exception to get a red test, then remove the throw to make it green. I know the breaking change should be something 'close' to the scenario under test, but am not sure how to word it as a proper guideline that my juniors could follow.

Body:
Even though it is right that you should not start testing your tests the ability of a test to fail is crucial. A test which cannot fail is not only useless - it also indicates that you ...

made logical mistakes

just wanted to do some quick testing without thinking it through or

are testing the language (e.g. unsigned >= 0) or general logic (true || false)

If you already have the code implemented please don't make the test fail by crashing the program. The following test will allways fail, even though it is a tautology.

#include <gtest/gtest.h>

TEST(test,testcase) {
    throw 1;
    EXPECT_TRUE(true);
}

int main(int argc, char ** argv) {
    ::testing::InitGoogleTest(&argc,argv);
    return RUN_ALL_TESTS();
}

(Maybe there are test frameworks in which this test would still pass, but there is at least one in which it gives you false security.)

Instead just write a quick "empty implementation" which has the same interface and simply does nothing. You then - when all tests failed - switch out the dummy with the real implementation.


答:
While using null or using an Optional are reasonable choices, one more option would be to add an explicit second field, boolean _hasBeenRead.  Your code would look like

```<code>private boolean getValue() {
    if (_hasBeenRead)
       return _valueCache;

    else {
       // read the value and, if successful, set both _hasBeenRead and _valueCache.
    }
}
</code>```

Some would consider this more explicit and therefore clearer.  Especially if you are using older style Java without new fangled goodies like Optional.

p.s. Whatever you do, consider whether this method need be synchronized, if the variables need to be volatile, etc...

Title: Should a Java Boolean be used for ternary (3-state) logic?

Body:
I'm trying to make a basic cache of a boolean value, and I did it like such:

private Boolean _valueCache = null;
private boolean getValue() {
    try {
        if (_valueCache == null) { // if cache was never filled
            return _valueCache = getReader().getMyBooleanProperty(); // fill it and return the new value
        }
        return _valueCache; // else, return the cache
    } catch (NullPointerException ex) { // getReader() returned null
        return false; // that return may not be null in the future, so set nothing
    }
}
```

Does this go against best practices? (letting a Boolean have 3 values: true, false, and null) I only want to cache this value, so I don't want to make an entire custom HashMap that mimics this behavior with a get-or-default method. That said, I've never done a cache this small so I don't know the downsides to it.

To clarify, I meant "ternary" as in "3-state", as opposed to "binary" as in "2-state". Sorry for any confusion.

Body:
While using null or using an Optional are reasonable choices, one more option would be to add an explicit second field, boolean _hasBeenRead.  Your code would look like

private boolean getValue() {
    if (_hasBeenRead)
       return _valueCache;

    else {
       // read the value and, if successful, set both _hasBeenRead and _valueCache.
    }
}

Some would consider this more explicit and therefore clearer.  Especially if you are using older style Java without new fangled goodies like Optional.

p.s. Whatever you do, consider whether this method need be synchronized, if the variables need to be volatile, etc...


问:
Possible way to make java class builder more abstract by using interface required keys
I'm looking for a more abstract pattern for builders that handles required
fields without the need of writing a validator that checks if all requried fields are set.

I like this builder. But is there a way to make the interfaces more abstract
so that I don't need to create a new interface for each required field?

```<code>public class Example {

    private String first;
    private String second;
    private String third;
    private String fourth;
    private String fifth;

    public static RequiredSecond builder(String first) {
        return new ExampleBuilder(first);
    }

    public interface RequiredSecond {
        RequiredThird withSecond(String second);
    }

    public interface RequiredThird {
        RequiredFourth withThird(String third);
    }

    public interface RequiredFourth {
        Build withFourth(String fourth);
    }

    public interface Build {
        Build withFifth(String fifth);

        Example build();
    }

    private static class ExampleBuilder implements RequiredSecond, RequiredThird, RequiredFourth, Build {
        Example example = new Example();

        public ExampleBuilder(String first) {
            example.setFirst(first);
        }

        @Override
        public Build withFifth(String fifth) {
            example.setFifth(fifth);
            return this;
        }

        @Override
        public Example build() {
            return example;
        }

        @Override
        public Build withFourth(String fourth) {
            example.setFourth(fourth);
            return this;
        }

        @Override
        public RequiredFourth withThird(String third) {
            example.setThird(third);
            return this;
        }

        @Override
        public RequiredThird withSecond(String second) {
            example.setSecond(second);
            return this;
        }
    }

    public String getFirst() {
        return first;
    }

    public void setFirst(String first) {
        this.first = first;
    }

    public String getSecond() {
        return second;
    }

    public void setSecond(String second) {
        this.second = second;
    }

    public String getThird() {
        return third;
    }

    public void setThird(String third) {
        this.third = third;
    }

    public String getFourth() {
        return fourth;
    }

    public void setFourth(String fourth) {
        this.fourth = fourth;
    }

    public String getFifth() {
        return fifth;
    }

    public void setFifth(String fifth) {
        this.fifth = fifth;
    }

    @Override
    public String toString() {
        return "Example [first=" + first + ", second=" + second + ", third=" + third + ", fourth=" + fourth +
                ", fifth=" + fifth + "]";
    }

}
public class Labb {

    public static void main(String[] args) {
        // All required including optional
        Example ex1 = Example.builder("first").withSecond("second").withThird("third").withFourth("fourth").withFifth("optional fith").build();
        System.out.println(ex1);
        // Output: Example [first=first, second=second, third=third, fourth=fourth, fifth=optional fith]

        // All required excluding optional
        Example ex2 = Example.builder("first").withSecond("second").withThird("third").withFourth("fourth").build();
        System.out.println(ex2);
        // Output: Example [first=first, second=second, third=third, fourth=fourth, fifth=null]
    }
}
</code>```

答:
I wouldn't touch codes like that with a 10-foot pole.  I get that you are probably trying to solve some problem and this maybe an abstract of it.  But if any code get that convoluted then you're probably heading down the wrong path.  My feeling is that one builder ought to be enough, and you can check for required fields in the build function.  You can also try multiple build functions:</p>

```
...
class ExampleBuilder {
    private String first;
    ...
    public Example buildFirst() {
        if(first == null) throw new IllegalArgumentException("first can't be null");
        return new Example(this);
    }
    ...
}
```

Body:
I wouldn't touch codes like that with a 10-foot pole.  I get that you are probably trying to solve some problem and this maybe an abstract of it.  But if any code get that convoluted then you're probably heading down the wrong path.  My feeling is that one builder ought to be enough, and you can check for required fields in the build function.  You can also try multiple build functions:

...
class ExampleBuilder {
    private String first;
    ...
    public Example buildFirst() {
        if(first == null) throw new IllegalArgumentException("first can't be null");
        return new Example(this);
    }
    ...
}


问:
Efficient mixing of sync and async methods within a single method?
Okay, it sounds odd, but the code is very simple and explains the situation well.

```<code>public virtual async Task RemoveFromRoleAsync(AzureTableUser user, string role)
{
    AssertNotDisposed();
    var roles = await GetRolesForUser(user);
    roles.Roles = RemoveRoles(roles.Roles, role);
    await Run(TableOperation.Replace(roles));
}
</code>```

(I know I'm talking kind of in the abstract below, but the above is an actual method from what will be actual production code that is actually doing what I'm asking about here, and I'm actually interested in your actually reviewing it for correctness vis a vis the async/await pattern.)

I'm encountering this pattern more and more often now that I'm using async/await more.  The pattern consists of the following chain of events:

Await an initial call that gets me some information I need to work on

Work on that information synchronously

Await a final call that saves the updated work

The above code block is typically how I go about handling these methods.  I await the first call, which I have to because it is asynchronous.  Next, I do the work that I need to do which isn't IO or resource bound, and so isn't async.  Finally, I save my work which is also an async call, and out of cargo-cult I await it.

But is this the most efficient/correct way to handle this pattern?  It seems to me I could skip awaiting the last call, but what if it fails?  And should I use a Task method such as ContinueWith to chain my synchronous work with the original call?  I'm just at a point right now where I'm not sure if I'm handling this correctly.

Given the code in the example, is there a better way to handle this async/sync/async method call chain?

答:
The way to handle this pattern is to ensure that all I/O is asynchronous. Synchronous I/O methods cause the current thread to block while it waits for a response from the I/O destination (network, file-system, etc).

Another thing to consider is that await should be used when you need a return value or when you need the awaited code to finish before doing something else. If you don't need either of those things, you can "fire and forget" your async method with Task.Run.

So, for the most efficient use of computing resources, if RemoveRoles does any I/O, it should become await RemoveRolesAsync and the I/O methods called by RemoveRolesAsync should also be async (and possibly awaited).

If performance is not your utmost concern, then it's fine to do some synchronous I/O on an async thread. It is a technical debt though. (In this case, you might want to call the first async method with ConfigureAwait, depending on where the code is running.)

Here's a more in-depth look at the best practices - https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

Here are some notes about the behavior of ConfigureAwait in different environments like ASP.NET, WebAPI, etc - https://stackoverflow.com/questions/13489065/best-practice-to-call-configureawait-for-all-server-side-code

OwnerDisplayName: Will


问:
Design: How to handle user permissions across a system
My team is currently working on a massive refactor of a medium-sized application in PHP. We are doing our best to refactor our code on a module (Orders, Users, Products) basis. The issue that I am currently wondering about has to do with handling what a user is allowed to do on our system.

Currently, this hinges on mostly on the User's Access Level to our system. Sometimes, we may have to reference their owning group to see if the higher level group is allowed to do something (place an order) and pass that permission on transitively to the user.

What I have come up with so far is a class called "Guardian". Guardian takes a User in and then has functions like "canPlaceOrder" or "canViewOrderReport". One benefit to this approach is that we are able to then see all of the actions on our system that require permissions in one place. In addition, this will allow us to separate our permission logic from our front-end and domain models.

However, I could see this not being an entirely scalable solution. Following the OOP principle that a class should be open for extension, closed for modification, I can see that as we add more permissions to our system, our Guardian class will have to add more methods as well.

I do like the benefit of having all of our permissions well defined in a human-readable way using one class, so that we always know that we are checking the correct criteria. However, I'm worried about scalability. Are there other approaches to this problem?

My question is really: What is a good way to handle this? Is my solution okay?

答:
there are several good ways.

You could implement open-closed by always using a factory to get the Guardian and returning a subtype of guardian that inherits the previous version. New functionality could cast to the most recent subtype.

You could also implement open-closed by just ... Adding methods! And knowing not to touch others. While this is easier to screw up, yes you have to know what you are doing. Unfortunately a dev who doesn't know what they are doing will screw up the previously mentioned method (more commonly quoted as the way to implement open-closed).

You could also make a list of 'permission' basetype. Wireup/startup would populate the list with objects. Then you could just add inherited permissions. To query, the newest code could search the list for its subtype, and call it.

For example in .net you could even make a method  (weak on the php here but don't try to compile this either):
bool GetPermission()
{
 return (from p in _permissionList.OfType).First();
}

Usage:
 can_do_this=GetPermission().NeedManagerApproval();

And... there are many other ways.

Yes, this is an aspect/crosscutting concern. But...

I think a bad way would be one that involves adding an AOP framework to your project


答:
My concern with your solution would be the overhead of maintaining user permissions, depending on how many users you have and the turnover of users.

Evey time you get a new user you will need to add a whole stack of permissions "canViewProduct", "canViewOrders", "canPlaceOrder" etc. etc. etc.

In larger shops this is usually handle by splitting the problem in two.

You create "roles" e.g. "manager", "retailCustomer", "wholeSaleCustomer", "badCreditCustomer".

You then assign the atomic permisions to these roles.

When you get a new user you simply assign them one or two roles. When you decide you need to restrict "badCreditCustomers" to cash on delivery only you simply remove the "canOrderOnCredit" from that role.


问:
How to display an inward spiral matrix
Suppose I have the following matrix with values 1-25 as input to my program.

```<code> 1  2  3  4  5
 6  7  8  9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
</code>```

The inward spiral should give me the output 13 18 17 12 7 8 9 14 19 24 23 22 21 16 11 6 1 2 3 4 5 10 15 20 25. What could be the logic behind such a program? I tried to start off with the center of the matrix and then increasing the row and column to be traversed at every iteration, but I am kinda stuck here.

答:
The part that is being repeated is this "square loop" pattern (read this from a to p):

```<code>h i j k l
g       m
f       n
e       o
d c b a p
</code>```

(Here I've shown a square loop of width 5.)

The core of the solution lies in figuring out how to describe this pattern programmatically.  This itself is composed of 4 strips that differ in the starting point and increment: a to d, e to h, i to l, and m to p.  In this example, the a to d strip has starting point (4, 5) and increment (-1, 0).  The other strips are analogous.

The completely solution involves repeating this pattern with increasing size until the entire square is covered.  You start with the center piece, followed by a square loop of width 3, followed by another square loop of width 5, etc.

Depending on what coordinate system you use, you may have to deal with some offset that depends on the size of the full grid.

Title: How to display an inward spiral matrix

Body:
The part that is being repeated is this "square loop" pattern (read this from a to p):

h i j k l
g       m
f       n
e       o
d c b a p

(Here I've shown a square loop of width 5.)

The core of the solution lies in figuring out how to describe this pattern programmatically.  This itself is composed of 4 strips that differ in the starting point and increment: a to d, e to h, i to l, and m to p.  In this example, the a to d strip has starting point (4, 5) and increment (-1, 0).  The other strips are analogous.

The completely solution involves repeating this pattern with increasing size until the entire square is covered.  You start with the center piece, followed by a square loop of width 3, followed by another square loop of width 5, etc.

Depending on what coordinate system you use, you may have to deal with some offset that depends on the size of the full grid.


答:
Relational databases deal with Sets. If want a flexable and usable OO implementations you classes should also be sets ie. collections.

So you have a class "Users" which is a collection of "User" classes.

You need to support the following methods:--

```<code>   Users.loadById(id)   // get one user from db
   Users.loadAll()      // definately not scalable !
   Users.loadWithFilter("sql where clause")

   Users.first()       // first user in result set
   Users.next()        // next user in result set
   Users.byId(id)      // search for specific user id in current set

   Users.Update(id)    // make changes persistant in db for an indvidual entry
   Users.Delete(id)    // delete individual user from db
   Users.New(User)     // Insert new user into database.
</code>```

So all you SQL handling is in the Users class, the User class contains just the column values.

Body:
Relational databases deal with Sets. If want a flexable and usable OO implementations you classes should also be sets ie. collections.

So you have a class "Users" which is a collection of "User" classes.

You need to support the following methods:--

   Users.loadById(id)   // get one user from db
   Users.loadAll()      // definately not scalable !
   Users.loadWithFilter("sql where clause")

   Users.first()       // first user in result set
   Users.next()        // next user in result set
   Users.byId(id)      // search for specific user id in current set

   Users.Update(id)    // make changes persistant in db for an indvidual entry
   Users.Delete(id)    // delete individual user from db
   Users.New(User)     // Insert new user into database.

So all you SQL handling is in the Users class, the User class contains just the column values.


问:
How is MTU determined and can it be changed
I'm developing a multi-part solution that consists of an iOS application and OS X application which communicate over Bluetooth Low Energy. Everything works fine and I can send moderate amounts of text between the iPhone and my MacBook. I would like to be able to send larger amounts of data, such as an image, from the iPhone to the MacBook. I'm able to do this but it takes about 50 minutes for the transfer of 1 image, compressed as a JPEG with a 0.2 quality (on a scale of 0-1). Part of the problem is that in the iOS application when the central connects, it reports an maximum packet length of 20 bytes (plus 3 bytes for header). In iOS 7, the changed the MTU so it's not a hardcoded 23 bytes. I cannot find anywhere that would allow me to specify a higher MTU on my MacBook or in the IOBluetooth framework.

I found a constant value in one of the bluetooth header files in the framework that specifies the MTU as 23 (20 + 3 for header), which leads me to believe this is just something hard coded into the framework that should be able to be changed somehow.

An alternative would be to use BLE to negotiate some other form of transfer between the systems. Ultimately, the transfer shouldn't be required to go over the Internet (the way Bump does it) but if a direct WIFI or Bluetooth connection could be used without requiring any user configuration, that would work.

答: BLE max datarate limits you to your 23 packet size. you need to change to Standard bluetooth to get the 2Mbps datarates. </p>