问:
How to monitor code review efficiently?
I suspect major code review cover up in my team.
Too many code reviews are merged without any comment.

Seems to me like there's no such thing as a code review without a single comment.

How can I as a team lead properly monitor that my team is doing a proper code review process and how can I help them to maximize the process' benefits?

Update

Thought people might want to know about any update. I tried a lot of suggestions that were given here. most were already in use.
some helped a bit.
However, the problem remained - some people continuously got bad code in when I was not looking.

I found that code review monitoring is not as helpful as giving my team tools to make their code better to begin with.

So I added a library named "jscpd" to detect copy pastes.
The build failed on copy pastes.
That eliminated one problem immediately.

next we are going to try codeclimate.

I am also doing a manual review on old code reviews once a sprint for half a day.
I am converting todos into issues/tickets - as I found out people are writing them, but they are never handled at a later point.
I am also doing meetings with the entire teams to review code when it is appropriate.

in general it feels like we are moving in the right direction.

答: I think you should create a template and ask your team members to update it every time they do a code review. But even then, you should participate in the review process initially.</p>

Title: How to monitor code review efficiently?


问:
Points to Understand Architecture of an Application/System
We are working on a knowledge transition of multiple applications (around 700). To make the process easy, I am preparing a list of key points we need to consdier for understanding the architecture of each application like below.

Why the list is important is once the transition is over, we are
  trying to integrate/rewrite/refactor these applications.

Technology Stack (
a.  Programming languages
b.  Tools used
c.  Third party components)

Database (
a.  Data model
b.  Data flow
c.   Clustering)

Interfaces with other applications

Dependencies

NFR

Anyone has any exclusive check list for this or enrich the above list?

答:
In addition to Roman Reiner's answer, your checklist doesn't mention the requirements for each application.

You will need some combination of documents/diagrams/tests to say what the old applications are supposed to do before you start writing new applications to replace them.

ContentLicense: CC BY-SA 3.0


答:
A few things (to be honest, most of these are covered across the answers, but I wanted to put them in a single place)

You can put process and rules in place to make sure a code-review
happens, but it's pretty impossible to put them in so that
code-review is actually more than a box-ticking exercise. Ultimately
the team has to see the benefit of the process, if they are to approach it usefully

Lead by example. Take part in reviews. As a developer, I feel bad if
my manager (a non-developer now) spots stuff I don't. Highlight issues
that should have been caught in review (in a non-blaming way). If a production issue happens, if issues arise    during QA (if you
have a separate QA process), highlight where they could have been
caught in code-review. Discuss with the team how can we can ensure
future issues like that are caught

Discuss with the team what they want the process to do. If they don't
see any point to it (as may happen at the beginning) use the
production issues and necessary refixes as evidence of its benefit

Use automated code-checking software like Sonarqube so that
code-reviews can focus on issues like incomprehensible-code, logic
errors, lack of documentation, etc that can't be spotted
automatically.

Title: How to monitor code review efficiently?

Body:
I suspect major code review cover up in my team.
Too many code reviews are merged without any comment.

Seems to me like there's no such thing as a code review without a single comment.

How can I as a team lead properly monitor that my team is doing a proper code review process and how can I help them to maximize the process' benefits?

Update

Thought people might want to know about any update. I tried a lot of suggestions that were given here. most were already in use.
some helped a bit.
However, the problem remained - some people continuously got bad code in when I was not looking.

I found that code review monitoring is not as helpful as giving my team tools to make their code better to begin with.

So I added a library named "jscpd" to detect copy pastes.
The build failed on copy pastes.
That eliminated one problem immediately.

next we are going to try codeclimate.

I am also doing a manual review on old code reviews once a sprint for half a day.
I am converting todos into issues/tickets - as I found out people are writing them, but they are never handled at a later point.
I am also doing meetings with the entire teams to review code when it is appropriate.

in general it feels like we are moving in the right direction.


问:
Is logging next to an implementation a SRP violation?
When thinking of agile software development and all the principles (SRP, OCP, ...) I ask myself how to treat logging.

Is logging next to an implementation a SRP violation?

I would say yes because the implementation should be also able to run without logging. So how can I implement logging in a better way? I've checked some patterns and came to a conclusion that the best way not to violate the principles in a user-defined way, but to use any pattern which is known to violate a principle is to use a decorator pattern.

Let's say we have a bunch of components completely without SRP violation and then we want to add logging.

component A

component B uses A

We want logging for A, so we create another component D decorated with A both implementing an interface I.

interface I

component L (logging component of the system)

component A implements I

component D implements I, decorates/uses A, uses L for logging

component B uses an I

Advantages:
- I can use A without logging
- testing A means I don't need any logging mocks
- tests are simpler

Disadvantage:
- more components and more tests

I know this seem to be another open discussion question, but I actually want to know if someone uses better logging strategies than a decorator or SRP violation. What about static singleton logger which are as default NullLogger and if syslog-logging is wanted, one change the implementation object at runtime?

答:
As logging is often considered a cross-cutting concern I'd suggest using AOP for separating logging from implementation.

Depending on the language you'd use an interceptor or some AOP framework (e.g. AspectJ in Java) to perform this.

The question is if this is actually worth the hassle. Note that this separation will increase the complexity of your project while providing very little benefit.


问:
Handling epics that only provide a shippable product at the end
i am currently evaluating whether SCRUM would be right for our team.
One thing that i do not understand so far and have not found a satisfactory response to is how something like "complete refactoring" epics would be handled.

My specific example:
We need to migrate a very large piece of software that has been kept as is on Java 1.4/JBoss 3 to a more current setup.
While i can identify tasks in this epic that may be handled during a sprint of say 2 weeks, i could thing of tasks that may leave the product or at least this part of the product  not-shippableat least for one sprint.

How is something like that handled?
I can't wrap my head around it at the moment so any help to understand this is greatly appreciated.

Kind Regards
Christian

答:
Agile focuses on value (a.k.a. "solving problems for someone")

Does this refactoring bring value? If not, or if you can't point your finger on it, then you have two alternatives: go back to the drawing board and try to understand exactly what problem you are trying to solve with this, or simply do not use agile for something with such a fixed scope and undefinable value.

Assuming you have a clear idea of the value of this project, and exactly what problems it solves, then focus on those. Apply a "divide and conquer" approach to the problem and value, this allows you to get a series smaller problems to solve and values to be gained.

It is quite rare that, once large problems are well specified, they remain indivisible. If you get stuck with one, ask yourself if you are trying to find a problem to solve or a solution to a problem. In the former case: don't do anything; in the latter, maybe your solution is not the right approach.

For example "We need to migrate a very large piece of software that has been kept as is on Java 1.4/JBoss 3 to a more current setup" is not something you should do without a specific reason! You don't need to migrate anything, assuming you have a working piece of software... are there any actual problems you are trying to solve with this upgrade? Focus on those and consider the migration an optional solution.

I realize the above is quite generic, but your question is also generic :-)


问:
Laravel using models
I started working with Laravel about a month ago and I started by reading the documentation etc. Now I'm working on a project in Laravel 4.2 and I skipped some parts of the full documentation. In my current project I'm not using models and my fellow programmers tell me it's good to use models. I know it's pretty standard to just use models in a Laravel project and I've read parts of the documentation of models by now. I see it's a clear way of working with tables etc. Now that I'm like in the middle of my project, I dont know if switching to models now, would be a big advantage. Since I have no experience with models. (So I have to learn it from the start). I'm currently doing everything in the Controllers. I cant see the disadvantage in using the query builder from Laravel in my controller instead of using the models. I do plan to eventually start other projects with models, but switching to models right now doesn't seem like the best thing to do in the middle of my project.

This is a real project. I'm planning to get it online and people will actually use it.

Im still a student

So basically:

Is there a reason for me to switch to models in my current project?

Is there a difference in performance between my method and models?

答:
The real question you would have to ask is, "Why should I use an MVC pattern".
The reasons for using such a pattern can only be explained when one has an understanding of principles that programmers want to adhere to for a number of reasons, but maybe the most important one:

Seperation of concerns

The value of separation of concerns is simplifying development and maintenance of computer programs. When concerns are well-separated, individual sections can be reused, as well as developed and updated independently. Of special value is the ability to later improve or modify one section of code without having to know the details of other sections, and without having to make corresponding changes to those sections.

Source: Wikipedia

As described at the link I've posted, not implementing 'some' seperation of concern can, or will, lead to code being unreadable, unmanageable or worse - plain broken (examples? look for spaghetti-code or big-ball-of-mud)

Simple Example:

You've got a website in which books can be bought.

There are 26 different pages (controller methods) in which books are displayed, or in any way used (eg. Admins must add - edit - delete books, users must add-edit-delete comments on books, etc)

If you were to implement all your "book-logic" into each controller method then:

All your controller methods will become larger and larger as books get more and more complex

After a few weeks you want to change something about the way your books are displayed, you have to change all 26 different controller methods using them.

After a while, you will have no idea where to find that line of code that makes sure that if a book is not for sale for a small period of time, it won't be displayed by all your controllers that have anything to do with selling books

Etc.

After hacking in tons of small changes in all your controllers, you get the flue, or go on a long and (well-deserved) holiday just before a major bug  - and some other programmer has to quickly find and resolve it without your help. Credits to him if he solved it in a timely fashion.

Note: this is just a stupid, quickly made up example with certainly enough flaws, but it is about the general picture.
Now, let's think about our project when we've set all our book logic into 1 model that is reusable throughout all our pages. Simplified this means you'll have to implement a change once, and that fact should answer your first question.

Title: Laravel using models


答:
I would say you're taking SRP far too seriously. If your code is tidy enough that logging is the only "violation" of SRP then you are doing better than 99% of all other programmers, and you should pat yourself on the back.

The point of SRP is to avoid horrific spaghetti code where code that does different things is all mixed up together. Mixing logging with functional code doesn't ring any alarm bells for me.

Body:
When thinking of agile software development and all the principles (SRP, OCP, ...) I ask myself how to treat logging.

Is logging next to an implementation a SRP violation?

I would say yes because the implementation should be also able to run without logging. So how can I implement logging in a better way? I've checked some patterns and came to a conclusion that the best way not to violate the principles in a user-defined way, but to use any pattern which is known to violate a principle is to use a decorator pattern.

Let's say we have a bunch of components completely without SRP violation and then we want to add logging.

component A

component B uses A

We want logging for A, so we create another component D decorated with A both implementing an interface I.

interface I

component L (logging component of the system)

component A implements I

component D implements I, decorates/uses A, uses L for logging

component B uses an I

Advantages:
- I can use A without logging
- testing A means I don't need any logging mocks
- tests are simpler

Disadvantage:
- more components and more tests

I know this seem to be another open discussion question, but I actually want to know if someone uses better logging strategies than a decorator or SRP violation. What about static singleton logger which are as default NullLogger and if syslog-logging is wanted, one change the implementation object at runtime?


问:
What is the logic behind the use of different arrows (-> <-) in Haskell?
I've been thinking about language design lately, and reading over some of the new things in Haskell (always a nice source of inspiration).  I'm struck by the many odd uses of the left <- and right -> arrow operators.

I guess the many different usages comes from prior art in math and other languages regarding arrow syntax, but is there some other reason not to try and make the usage more consistent or clear?  Maybe I'm just not seeing the big picture?

The right arrow gets used as a type constructor for functions, the separator between argument and body of lambda expressions, separator for case statements, and it's used in pattern views, which have the form (e -> p).

The left arrow gets used in do notation as something similar to variable binding, in list comprehensions for the same (I'm assuming they are the same, as list comprehensions look like condensed do blocks), and in pattern guards, which have the form (p <- e).

Now the last examples for each arrow are just silly!  I understand that guards and views serve different purposes, but they have almost identical form except that one is the mirror of the other!  I've also always found it kind of odd that regular functions are defined with = but lambdas with ->.  Why not use the arrow for both?  Or the equals for both?

It also gets pretty odd when you consider that for comparing some calculated value against a constant, there's nearly a half-dozen ways to do it:

```<code>test x = x == 4

f     x = if test x then g x else h x

f'    4 = g 4
f'    x = h x

f''   x@(test -> true) = g x
f''   _ = h x

f'''  x | true <- test x = g x
        | otherwise = h x

f'''' x = case (x) of
          4 -> g x
          _ -> h x
</code>```

Variety is the spice of source code though, right?

答:
The operator <- is used in two ways as described in Haskell operators:

List comprehension generator;

Single assignment operator in do-constr.

List comprehensions are syntactic sugar like the expression

import Data.Char (toUpper)

[toUpper c | c <- s]

where s :: String is a string such as "Hello". Strings in Haskell are lists of characters; the generator c <- sfeeds each character of s in turn to the left-hand expression toUpper c, building a new list. The result of this list comprehension is
"HELLO". (Of course, in this simple example you would just write map toUpper s.)

In the first versions of Haskell, the comprehension syntax was available for all monads.  Later the comprehension syntax was restricted to lists.
Since lists are an instance of monads, you can get list comprehension in terms of the
do-notation.

Because of this, several Haskell programmers consider the list comprehension unnecessary now.

The example from above can be translated to list monad as follows:

do c <- s
   return (toUpper c)

For more info, see List comprehension.


问:
Client-Server Application Object with child Objects
Actually I'm going to build an Client Server Application, at the Login I recive the User Object from the Server.
An user has a List of tasks, but I don't want to load them at the Login.
So what would be an good style to recive the Tasks of an user.
Should my user have an "GetTasks()" function which will access the server and will return the Tasks, which would be an strongly object orientated method.
Or should I Use an Service, which has a function that takes the user as parameter and returns the task.</p>

答:
Should my user have an "GetTasks()" function which will access the
  server and will return the Tasks, which would be an strongly object
  orientated method.

I am not sure it's something strongly object-oriented.

Or should I Use an Service, which has a function that takes the user
  as parameter and returns the task.

Of course it would be better to use Service for that. Follow SoC here.


问:
How can I avoid these nested repetitive ifs?
I'm trying to implement a web interface for a user database. Hosts can create guests for their courses, the guests can get deleted after the course has ended but have to remain in the database for a given amount of time. If a host tries to create a guest that already exists in the database, the following things can happen:

The guest is already active and was created by the same host,

The guest is already active and was created by a different host,

The guest is in deleted state and was created by the same host,

The guest is in deleted state and was created by a different host.

Currently, I'm trying to represent the user state in this enum:

```<code>public enum GuestUserStatus
{
    Unknown = 0,
    NewGuest = 1,

    ActiveSameHost = 10,
    ActiveDifferentHost = 11,

    DeletedSameHost = 20,
    DeletedDifferentHost = 21
}
</code>```

This allows me to switch() on the set user state.

However, to set the user state, I'm currently using repetetive if clauses like these:

```<code>if (queriedUser.GuestDetails.Creator == creator)
{
    if (queriedUser.GuestDetails.State == GuestState.Deleted)
    {
        currentStatus = GuestUserStatus.DeletedSameHost;
    }
    else
    {
        currentStatus = GuestUserStatus.ActiveSameHost;
    }
}
else
{
    if (queriedUser.GuestDetails.State == GuestState.Deleted)
    {
        currentStatus = GuestUserStatus.DeletedDifferentHost;
    }
    else
    {
        currentStatus = GuestUserStatus.ActiveDifferentHost;
    }
}
</code>```

The nested if clauses act on the same condition but with a different outcome.

Is there a way to avoid this? I looked into marking the enum with [Flags] and using powers of 2 as underlying values, but then I couldn't use the switch() anymore.

UPDATE: Please note that I have the same conditions twice and different outcomes to them.

UPDATE2: Trying to address the linked question How to tackle a 'branched' arrow head anti-pattern?: Let's say I implement the accepted answer of that question. That would give me something like this:

```<code> bool activeSameHost = (queriedUser.Guest.Creator == creator && queriedUser.GuestDetails.State != GuestState.Deleted);
 bool activeDifferentHost = (queriedUser.Guest.Creator == creator && queriedUser.GuestDetails.State == GuestState.Deleted);
 bool inactiveSameHost = (queriedUser.Guest.Creator != creator && queriedUser.GuestDetails.State == GuestState.Deleted);
 bool inativeDifferentHost = (queriedUser.Guest.Creator != creator && queriedUser.GuestDetails.State == GuestState.Deleted);

if(activeSameHost) currentStatus = GuestUserStatus.ActiveSameHost;
if(inactiveSameHost) currentStatus = GuestUserStatus.InactiveSameHost;
if(activeDifferentHost) currentStatus = GuestUserStatus.ActiveDifferentHost;
if(inactiveDifferentHost) currentStatus = GuestUserStatus.InactiveDifferentHost;
</code>```

I fail to see the improvement. Sure, the ifs are no longer nested, but the only thing that changed is the complexity moving from the nested ifs to the assignment of intermediate variables.

答:
Using lamdba actions is another option.

Here is a basic method that checks for conditional and runs appropriate code —
but notice that in state and creator parameters I took a long shot at their type:
they are not necessary good. Just illustrating the concept.

```<code>private void SetConditionalValue(Enum state, string guestCreator, string creator, Action activeSameHost, Action inactiveSameHost, Action activeDifferentHost, Action inactiveDifferentHost)
{
    if (guestCreator == creator)
    {
        if (state == GuestState.Deleted)
        {
           inactiveSameHost.Invoke();
        }
        else
        {
            activeSameHost.Invoke();
        }
    }
    else
    {
        if (state == GuestState.Deleted)
        {
            inactiveDifferentHost.Invoke();
        }
        else
        {
            activeDifferentHost.Invoke();
        }
    }
}
</code>```

Now the calls look like this :

```<code>SetConditionalValue(queriedUser.GuestDetails.State,
                    queriedUser.Guest.Creator,
                    creator,
                    () => currentStatus = GuestUserStatus.ActiveSameHost,
                    () => currentStatus = GuestUserStatus.InactiveSameHost,
                    () => currentStatus = GuestUserStatus.ActiveDifferentHost,
                    () => currentStatus = GuestUserStatus.InactiveDifferentHost);
</code>```

You can then reuse the same method for different actions with the same condition:

```<code>SetConditionalValue(queriedUser.GuestDetails.State,
                    queriedUser.Guest.Creator,
                    creator,
                    () => subscriptionCost = 130d,
                    () => subscriptionCost = 215d,
                    () => subscriptionCost = 125d,
                    () => subscriptionCost = 100d);
</code>```

Condition will be re-evaluated but still you don't have to worry about re writing it every single time. If the condition changes slightly later on, you change in one place and the rest is automatically affected. Of course you can switch to delegates for more control and reference parameters, but if everything is local you don't need to. You can mix that with pre evaluation of conditions in your update but I think the full if conditional is more readable and sustainable.

Body:
Using lamdba actions is another option.

Here is a basic method that checks for conditional and runs appropriate code —
but notice that in state and creator parameters I took a long shot at their type:
they are not necessary good. Just illustrating the concept.

private void SetConditionalValue(Enum state, string guestCreator, string creator, Action activeSameHost, Action inactiveSameHost, Action activeDifferentHost, Action inactiveDifferentHost)
{
    if (guestCreator == creator)
    {
        if (state == GuestState.Deleted)
        {
           inactiveSameHost.Invoke();
        }
        else
        {
            activeSameHost.Invoke();
        }
    }
    else
    {
        if (state == GuestState.Deleted)
        {
            inactiveDifferentHost.Invoke();
        }
        else
        {
            activeDifferentHost.Invoke();
        }
    }
}

Now the calls look like this :

SetConditionalValue(queriedUser.GuestDetails.State,
                    queriedUser.Guest.Creator,
                    creator,
                    () => currentStatus = GuestUserStatus.ActiveSameHost,
                    () => currentStatus = GuestUserStatus.InactiveSameHost,
                    () => currentStatus = GuestUserStatus.ActiveDifferentHost,
                    () => currentStatus = GuestUserStatus.InactiveDifferentHost);

You can then reuse the same method for different actions with the same condition:

SetConditionalValue(queriedUser.GuestDetails.State,
                    queriedUser.Guest.Creator,
                    creator,
                    () => subscriptionCost = 130d,
                    () => subscriptionCost = 215d,
                    () => subscriptionCost = 125d,
                    () => subscriptionCost = 100d);

Condition will be re-evaluated but still you don't have to worry about re writing it every single time. If the condition changes slightly later on, you change in one place and the rest is automatically affected. Of course you can switch to delegates for more control and reference parameters, but if everything is local you don't need to. You can mix that with pre evaluation of conditions in your update but I think the full if conditional is more readable and sustainable.


问:
Why do schools teach arrays over List?
Most of the assignments in my school for the initial programming classes required me to use arrays. I work full time now, and I never used an array for any project that I have worked on. Even in the exisiting projects I never saw the use of arrays anywhere. In my opinion, List is easier to use and is a standard. Why do professors tell students to use arrays in their assignments? Is it just so that students understand the basics? </p>

<p>Since most of the universities teach Java, this question is specific to Java. </p>

答:
I think it makes sense to teach how to use arrays first due to the fact that ArrayList uses an array internally. The ArrayList class has a member variable called elementData which is an Object array.

From the JDK ArrayList source code:

```<code>/**
 * The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer.
 */
private transient Object[] elementData;
</code>```

When you add, update, retrieve or remove elements from an ArrayList it uses this internal array to do those operations. As user Ixrec has already pointed out - ArrayList is just a higher-level abstraction which is typically easier to work with.

Title: Why do schools teach arrays over List?

Body:
I think it makes sense to teach how to use arrays first due to the fact that ArrayList uses an array internally. The ArrayList class has a member variable called elementData which is an Object array.

From the JDK ArrayList source code:

/**
 * The array buffer into which the elements of the ArrayList are stored.
 * The capacity of the ArrayList is the length of this array buffer.
 */
private transient Object[] elementData;

When you add, update, retrieve or remove elements from an ArrayList it uses this internal array to do those operations. As user Ixrec has already pointed out - ArrayList is just a higher-level abstraction which is typically easier to work with.


问:
Is Functional Programming a viable alternative to dependency injection patterns?
I have recently been reading a book entitled Functional Programming in C# and it occurs to me that the immutable and stateless nature of functional programming accomplishes similar outcomes to dependency injection patterns and is possibly even a better approach, especially in regards to unit testing.

I would be appreciative if anyone who has experience with both approaches could share their thoughts and experiences in order to answer the primary question: is Functional Programming a viable alternative to dependency injection patterns?

答:
Dependency management is a big problem in OOP for the following two reasons:

The tight coupling of data and code.

Ubiquitous use of side effects.

Most OO programmers consider the tight coupling of data and code to be wholly beneficial, but it comes with a cost.  Managing the flow of data through the layers is an unavoidable part of programming in any paradigm.  Coupling your data and code adds the additional problem that if you want to use a function at a certain point, you have to find a way get its object to that point.

Use of side effects creates similar difficulties.  If you use a side effect for some functionality, but want to be able to swap out its implementation, you pretty much have no other choice but to inject that dependency.

Consider as an example a spammer program that scrapes web pages for email addresses then emails them.  If you have a DI mindset, right now you're thinking of the services you will encapsulate behind interfaces, and which services will get injected where.  I'll leave that design as an exercise for the reader.  If you have an FP mindset, right now you're thinking of the inputs and outputs for the lowest layer of functions, like:

Input a web page address, output the text of that page.

Input a page's text, output a list of links from that page.

Input a page's text, output a list of email addresses on that page.

Input a list of email addresses, output a list of email addresses with duplicates removed.

Input an email address, output a spam email for that address.

Input a spam email, output the SMTP commands to send that email.

When you think in terms of inputs and outputs, there are no function dependencies, only data dependencies.  That's what makes them so easy to unit test.  Your next layer up arranges for the output of one function to be fed into the input of the next, and can easily swap out the various implementations as needed.

In a very real sense, functional programming naturally prods you to always invert your function dependencies, and therefore you usually don't have to take any special measures to do so after the fact.  When you do, tools like higher-order functions, closures, and partial application make it easier to accomplish with less boilerplate.

Note that it's not dependencies themselves that are problematic.  It's dependencies that point the wrong way. The next layer up may have a function like:

```<code>processText = spamToSMTP . emailAddressToSpam . removeEmailDups . textToEmailAddresses
</code>```

It's perfectly okay for this layer to have dependencies hard-coded like this, because its sole purpose is to glue the lower-layer functions together.  Swapping an implementation is as simple as creating a different composition:

```<code>processTextFancy = spamToSMTP . emailAddressToFancySpam . removeEmailDups . textToEmailAddresses
</code>```

This easy recomposition is made possible by a lack of side effects.  The lower-layer functions are completely independent of each other.  The next layer up may choose which processText is actually used based on some user config:

```<code>actuallyUsedProcessText = if (config == "Fancy") then processTextFancy else processText
</code>```

Again, not an issue because all the dependencies point one way.  We don't need to invert some dependencies in order to get them all pointing the same way, because pure functions already forced us to do so.

Note that you could make this a lot more coupled by passing config down through to the lowest layer instead of checking it at the top.  FP doesn't prevent you from doing this, but it does tend to make it a lot more annoying if you try.

Body:
Dependency management is a big problem in OOP for the following two reasons:

The tight coupling of data and code.

Ubiquitous use of side effects.

Most OO programmers consider the tight coupling of data and code to be wholly beneficial, but it comes with a cost.  Managing the flow of data through the layers is an unavoidable part of programming in any paradigm.  Coupling your data and code adds the additional problem that if you want to use a function at a certain point, you have to find a way get its object to that point.

Use of side effects creates similar difficulties.  If you use a side effect for some functionality, but want to be able to swap out its implementation, you pretty much have no other choice but to inject that dependency.

Consider as an example a spammer program that scrapes web pages for email addresses then emails them.  If you have a DI mindset, right now you're thinking of the services you will encapsulate behind interfaces, and which services will get injected where.  I'll leave that design as an exercise for the reader.  If you have an FP mindset, right now you're thinking of the inputs and outputs for the lowest layer of functions, like:

Input a web page address, output the text of that page.

Input a page's text, output a list of links from that page.

Input a page's text, output a list of email addresses on that page.

Input a list of email addresses, output a list of email addresses with duplicates removed.

Input an email address, output a spam email for that address.

Input a spam email, output the SMTP commands to send that email.

When you think in terms of inputs and outputs, there are no function dependencies, only data dependencies.  That's what makes them so easy to unit test.  Your next layer up arranges for the output of one function to be fed into the input of the next, and can easily swap out the various implementations as needed.

In a very real sense, functional programming naturally prods you to always invert your function dependencies, and therefore you usually don't have to take any special measures to do so after the fact.  When you do, tools like higher-order functions, closures, and partial application make it easier to accomplish with less boilerplate.

Note that it's not dependencies themselves that are problematic.  It's dependencies that point the wrong way. The next layer up may have a function like:

processText = spamToSMTP . emailAddressToSpam . removeEmailDups . textToEmailAddresses

It's perfectly okay for this layer to have dependencies hard-coded like this, because its sole purpose is to glue the lower-layer functions together.  Swapping an implementation is as simple as creating a different composition:

processTextFancy = spamToSMTP . emailAddressToFancySpam . removeEmailDups . textToEmailAddresses

This easy recomposition is made possible by a lack of side effects.  The lower-layer functions are completely independent of each other.  The next layer up may choose which processText is actually used based on some user config:

actuallyUsedProcessText = if (config == "Fancy") then processTextFancy else processText

Again, not an issue because all the dependencies point one way.  We don't need to invert some dependencies in order to get them all pointing the same way, because pure functions already forced us to do so.

Note that you could make this a lot more coupled by passing config down through to the lowest layer instead of checking it at the top.  FP doesn't prevent you from doing this, but it does tend to make it a lot more annoying if you try.


答:
is Functional Programming a viable alternative to dependency injection patterns?

This strikes me as an odd question. Functional Programming approaches are largely tangential to dependency injection.

Sure, having immutable state can push you to not "cheat" by having side effects or using the class state as an implicit contract between functions. It makes passing of data more explicit, which I suppose is the most basic form of dependency injection. And the functional programming concept of passing functions around makes that a lot easier.

But it doesn't remove dependencies. Your operations still need all of the data/operations they needed when your state was mutable. And you still need to get those dependencies there somehow. So I wouldn't say that functional programming approaches replace DI at all, so are no sort of alternative.

If anything, they've just shown you how bad OO code can create implicit dependencies than programmers rarely think about.

Title: Is Functional Programming a viable alternative to dependency injection patterns?

Body:
I have recently been reading a book entitled Functional Programming in C# and it occurs to me that the immutable and stateless nature of functional programming accomplishes similar outcomes to dependency injection patterns and is possibly even a better approach, especially in regards to unit testing.

I would be appreciative if anyone who has experience with both approaches could share their thoughts and experiences in order to answer the primary question: is Functional Programming a viable alternative to dependency injection patterns?


答:
I've also always found it kind of odd that regular functions are defined with = but lambdas with ->. Why not use the arrow for both? Or the equals for both?

The equality symbol makes sense for named function definitions because it states that applying the named function to its arguments is equivalent to evaluating the right hand side of the equation. Defining lambdas that way makes no sense notationally: x = x + 1 implies x is equal to its successor, which can't be true.

The left arrow gets used in do notation as something similar to variable binding, in list comprehensions for the same (I'm assuming they are the same, as list comprehensions look like condensed do blocks), and in pattern guards, which have the form (p <- e).

All of those constructs bind a new variable. Using = here would not make much sense either, because a statement such as x = x + 1 implies that x refers to the same thing on both sides. A variable binding introduces a new x that's distinct from any x that may occur in the right hand side.

One alternative would've been to just use -> and place the variable on the right, but I believe placing it on the left is objectively more readable in cultures that read left to right. You scan text by moving your eyes along the left margin and thus placing all the variables on the left makes them easier to find. And although having two different symbols for variable bindings may not seem consistent, there's consistency in the position of the variable that gets bound; it's always on the left.

So that just leaves the question of why <- as opposed to some other symbol like :=. I don't know, but I can guess. Look at what desugared monadic code looks like:

```<code>[1, 2, 3] >>= \xs -> map (*2) xs
</code>```

Considering that >>= with its arguments swapped is called =<<, it probably seemed natural to use a left-facing arrow.

Title: What is the logic behind the use of different arrows (-> <-) in Haskell?

Body:
I've been thinking about language design lately, and reading over some of the new things in Haskell (always a nice source of inspiration).  I'm struck by the many odd uses of the left <- and right -> arrow operators.

I guess the many different usages comes from prior art in math and other languages regarding arrow syntax, but is there some other reason not to try and make the usage more consistent or clear?  Maybe I'm just not seeing the big picture?

The right arrow gets used as a type constructor for functions, the separator between argument and body of lambda expressions, separator for case statements, and it's used in pattern views, which have the form (e -> p).

The left arrow gets used in do notation as something similar to variable binding, in list comprehensions for the same (I'm assuming they are the same, as list comprehensions look like condensed do blocks), and in pattern guards, which have the form (p <- e).

Now the last examples for each arrow are just silly!  I understand that guards and views serve different purposes, but they have almost identical form except that one is the mirror of the other!  I've also always found it kind of odd that regular functions are defined with = but lambdas with ->.  Why not use the arrow for both?  Or the equals for both?

It also gets pretty odd when you consider that for comparing some calculated value against a constant, there's nearly a half-dozen ways to do it:

```<code>test x = x == 4

f     x = if test x then g x else h x

f'    4 = g 4
f'    x = h x

f''   x@(test -> true) = g x
f''   _ = h x

f'''  x | true <- test x = g x
        | otherwise = h x

f'''' x = case (x) of
          4 -> g x
          _ -> h x
</code>```

Variety is the spice of source code though, right?

Body:
I've also always found it kind of odd that regular functions are defined with = but lambdas with ->. Why not use the arrow for both? Or the equals for both?

The equality symbol makes sense for named function definitions because it states that applying the named function to its arguments is equivalent to evaluating the right hand side of the equation. Defining lambdas that way makes no sense notationally: x = x + 1 implies x is equal to its successor, which can't be true.

The left arrow gets used in do notation as something similar to variable binding, in list comprehensions for the same (I'm assuming they are the same, as list comprehensions look like condensed do blocks), and in pattern guards, which have the form (p <- e).

All of those constructs bind a new variable. Using = here would not make much sense either, because a statement such as x = x + 1 implies that x refers to the same thing on both sides. A variable binding introduces a new x that's distinct from any x that may occur in the right hand side.

One alternative would've been to just use -> and place the variable on the right, but I believe placing it on the left is objectively more readable in cultures that read left to right. You scan text by moving your eyes along the left margin and thus placing all the variables on the left makes them easier to find. And although having two different symbols for variable bindings may not seem consistent, there's consistency in the position of the variable that gets bound; it's always on the left.

So that just leaves the question of why <- as opposed to some other symbol like :=. I don't know, but I can guess. Look at what desugared monadic code looks like:

[1, 2, 3] >>= \xs -> map (*2) xs

Considering that >>= with its arguments swapped is called =<<, it probably seemed natural to use a left-facing arrow.


答:
"shippable" doesn't necessarily mean "usable by the end user", and it doesn't necessarily mean you actually ship it. All it means is that you're done writing and testing the code, and that it has an appropriate level of quality.

With that in mind, you need to break down your epics into stories that can be completed in the context of a single sprint. Perhaps one story is to port a single program or function to a new version of java. That story will then be broken down into tasks to do the port, write the tests, and so on. At the end of that story, the code should be ported and proven correct with automated tests. Even if that single program can't be used because it has dependencies on other programs, the port of that particular program can be considered done.

More stories would be for porting other programs or functions. Another story might be to switch to something other than jboss, or to a new version of jboss. Again, that work should fit into a sprint. Keep writing stories like this to accomplish all the things that need to happen before the epic is complete. It may be that the very last story is something along the lines of "flip the switch and start using the new code".

With each story you need to identify who the story is for (and it doesn't necessarily have to be an end user), and what the business value of the story is.

Scrum is really nothing more than a mechanism for breaking large projects into smaller projects, with the idea being we can better plan and execute on small stuff better than we can large stuff. And, by completing smaller stories sooner rather than later, we can get feedback that can help us make better decisions going forward.

The other central benefit of scrum is that you don't consider a story done until it is "shippable", but again, that doesn't necessarily mean it's being used by the product, or is visible to the end user. It simply means you're absolutely, completely done with the work for that story.

Title: Handling epics that only provide a shippable product at the end

Body:
i am currently evaluating whether SCRUM would be right for our team.
One thing that i do not understand so far and have not found a satisfactory response to is how something like "complete refactoring" epics would be handled.

My specific example:
We need to migrate a very large piece of software that has been kept as is on Java 1.4/JBoss 3 to a more current setup.
While i can identify tasks in this epic that may be handled during a sprint of say 2 weeks, i could thing of tasks that may leave the product or at least this part of the product  not-shippableat least for one sprint.

How is something like that handled?
I can't wrap my head around it at the moment so any help to understand this is greatly appreciated.

Kind Regards
Christian


答: Assuming that list are indeed easier to work with, as you say — that doesn't really matter.  Learning is more about "basic to complex" than "easy to hard".  If fundamentals weren't important, then computer science wouldn't be an academic field.  You could just learn how to click together apps using existing frameworks/libraries from online tutorials.  (Of course, someone has to write those libraries ... and someone has to implement ArrayList in the first place....)

Title: Why do schools teach arrays over List?

Body:
Most of the assignments in my school for the initial programming classes required me to use arrays. I work full time now, and I never used an array for any project that I have worked on. Even in the exisiting projects I never saw the use of arrays anywhere. In my opinion, List is easier to use and is a standard. Why do professors tell students to use arrays in their assignments? Is it just so that students understand the basics? </p>

<p>Since most of the universities teach Java, this question is specific to Java. </p>


答:
No, it is not a violation of SRP.

The messages you send to the log should change for the same reasons as the surrounding code.

What IS a violation of SRP is using a specific library for logging directly in the code. If you decide to change the way of logging, SRP states that it should not impact your business code.

Some kind of abstract Logger should be accessible to your implementation code, and the only thing your implementation should say is "Send this message to the log", with no concerns wrt how it's done. Deciding about the exact way of logging (even timestamping) is not your implementation's responsibility.

Your implementation then should also not know whether the logger it is sending messages to is a NullLogger.

That said.

I would not brush logging away as a cross-cutting concern too fast. Emitting logs to trace specific events occurring in your implementation code belongs to the implementation code.

What is a cross-cutting concern, OTOH, is execution tracing: logging enters and exits in each and every method. AOP is best placed to do this.

Title: Is logging next to an implementation a SRP violation?


答:
Scrum is only a start point for your process, look at it, keep the bits you like, ditch the bits you don't. It is NOT a religion, (despite many people's insistence on adhering to its holy scriptures).

So, bearing in mind this, the point of Agile as a whole is to remove impediments (like management processes) to enable you to perform your work as easily as possible, however, it realizes that without any management process you may go 'off track', so it introduces a few different processes designed to help you keep yourself organised and working in the fright direction. The main processes that do this is regular updates and team communication.

So this means your epic is "do some work" but you can't realistically do all in one long go without involving a lot of risk (ie when you finished you'll show it, and only then will you know if you did it correctly). So, you break that epic task into smaller pieces that you can show to others to prove that you're still working on the right thing, and that it still fits the desired result.

It can be difficult to understand how to split an epic of 'do an upgrade' into smaller, bit-sized pieces, but I think if you started work you'd quickly be splitting it up anyway. The problem is one of perception, a mental block that stops you thinking about it (like seeing a blank page and not being able to start writing). You can imagine yourself performing the upgrade, and you'll naturally split the tasks up - write them down and you're pretty much done splitting the epic into stories. For example, to do such an upgrade you might have sub-tasks such as provide a new environment, upgrade to latest JBoss, upgrade the DB, document the configuration, test the system, upgrade the code (which in turn gets turned into upgrade each component or layer depending on your system).

Personally I think 2 week sprints are duff, I worked best with 6 week sprints once upon a time, so do not be afraid to change the timing, but do not increase the sprint times to remove the value of them - you need to show progress after each one, or its pointless having sprints at all. And if you don't show progress, there's no point doing Agile. So keep it to reasonable times and release often. If that means pulling a double-sprint now and then, so what - do it. (many people will say "but this will affect your velocity", and I say "sod velocity, its about real progress not management reporting").


答:
Java allows variables of any type to be stored into arrays.  By contrast, ArrayList only allows storage of references.  One may thus not usefully discuss ArrayList without first covering how auto-boxing will convert primitives to reference types, and how auto-unboxing will sometimes convert reference types to primitives:

```<code>for (int i=10; i<=10000; i*=10)
{
    ArrayList<Integer> l = new ArrayList<Integer>();
    l.add(i);
    l.add(i);
    l.add(l.get(0));
    System.out.print("i=" + i);
    System.out.print(" #0==i:" + (l.get(0)==i));
    System.out.print(" #1==i:" + (l.get(1)==i));
    System.out.print(" #2==i:" + (l.get(2)==i));
    System.out.print(" #0=#1:" + (l.get(0)==l.get(1)));
    System.out.print(" #1=#2:" + (l.get(1)==l.get(2)));
    System.out.println(" #0=#2:" + (l.get(0)==l.get(2)));
}
</code>```

If the code had used an int[3] rather than an ArrayList, there would be no surprises.  All three elements would compare equal to i and to each other.  Using ArrayList, however, even though all three elements of the list will always compare equal to i, and the first and third will always compare equal to each other, the first two elements will only equal each other when i is 1, 10, or 100, but (on most implementations) not when i is 1000 or 10000.

Title: Why do schools teach arrays over List?

Body:
Java allows variables of any type to be stored into arrays.  By contrast, ArrayList only allows storage of references.  One may thus not usefully discuss ArrayList without first covering how auto-boxing will convert primitives to reference types, and how auto-unboxing will sometimes convert reference types to primitives:

for (int i=10; i<=10000; i*=10)
{
    ArrayList<Integer> l = new ArrayList<Integer>();
    l.add(i);
    l.add(i);
    l.add(l.get(0));
    System.out.print("i=" + i);
    System.out.print(" #0==i:" + (l.get(0)==i));
    System.out.print(" #1==i:" + (l.get(1)==i));
    System.out.print(" #2==i:" + (l.get(2)==i));
    System.out.print(" #0=#1:" + (l.get(0)==l.get(1)));
    System.out.print(" #1=#2:" + (l.get(1)==l.get(2)));
    System.out.println(" #0=#2:" + (l.get(0)==l.get(2)));
}

If the code had used an int[3] rather than an ArrayList, there would be no surprises.  All three elements would compare equal to i and to each other.  Using ArrayList, however, even though all three elements of the list will always compare equal to i, and the first and third will always compare equal to each other, the first two elements will only equal each other when i is 1, 10, or 100, but (on most implementations) not when i is 1000 or 10000.


问:
How would you design a user database with custom fields
This question is around how should I design a database, it can be relational / nosql databases, depending on what will be the better solution

Given a requirement where you'll need to create a system that will involve a database to track "Company" and "User". A single user always only belong to one company

A user can only belong to one company

A company can have many users

The design for "Company" table is quite straightforward.
Company will have the following attributes / columns: (let's keep it simple)

```<code>ID, COMPANY_NAME, CREATED_ON
</code>```

First scenario

Simple & straight forward, users all have the same attribute, so this can be easily done in relational style, user table:

```<code>ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON
</code>```

Second scenario

What happen if different companies want to store different profile attribute for their user. Each company will have a defined set of attributes that would apply to all users of that company.

For example:

Company A wants to store: LIKE_MOVIE (boolean), LIKE_MUSIC (boolean)

Company B wants to store: FAV_CUISINE (String)

Company C wants to store: OWN_DOG (boolean), DOG_COUNT (int)

Approach 1

the brute force way is to have a single schema for the user and let them have nulls when they dont belong to the company:

```<code>ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, LIKE_MOVIE, LIKE_MUSIC, FAV_CUISINE, OWN_DOG, DOG_COUNT, CREATED_ON
</code>```

Which is kinda nasty because you will end up with a lot of NULLS and user rows that have columns that are irrelevant to them (ie. all users belonging to Company A has NULL values for FAV_CUISINE, OWN_DOG, DOG_COUNT)

Approach 2

a second approach, is to have "free form field":

```<code>ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_1, CUSTOM_2, CUSTOM_3, CREATED_ON
</code>```

Which would be nasty on its own since you have no idea what custom fields are, the data type will not be reflective of the values stored (eg. we'll store int value as VARCHAR).

Approach 3

I have looked into PostgreSQL JSON field, in which case you will have:

```<code>ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_PROFILE_JSON, CREATED_ON
</code>```

In this case, how would you be able to apply different schemas to a user?
A user with Company A will have schema that looks like

```<code> {"LIKE_MOVIE":"boolean", "LIKE_MUSIC": "boolean"}
</code>```

While a user with Company C will have a different schema:

```<code> {"OWN_DOG ":"boolean", "DOG_COUNT": "int"}
</code>```

How should I solve this issue? How can I design database properly to allow for this flexible schema for a single "object" (User) based on the relationship they have (Company)?

relational solution? nosql solution?

Edit: I've also thought about a "CUSTOM_PROFILE" table which will essentially store user attributes in rows rather than columns.

There are 2 problems with this approach:

1) The data grows per user grow as rows rather than columns - and this mean to get a full picture of the user, a lot of joins need to be done, multiple joins to the "custom profile" table on the different custom attributes

2) The data value is always stored as VARCHAR to be generic, even if we know the data is supposed to be integer or boolean etc

答:
You should normalize your database such that you have 3 different tables for each different type of company profile. Using your example, you would have tables with columns:

```<code>USER_ID, LIKE_MOVIE, LIKE_MUSIC

USER_ID, FAVORITE_CUISINE

USER_ID, OWN_DOG, DOG_COUNT
</code>```

This approach assumes that you will know the shape of information a company wants to store before hand and that it will not change often. If the shape of the data is unknown at design time, it would probably be better to go with that JSON field or a nosql database.

Body:
You should normalize your database such that you have 3 different tables for each different type of company profile. Using your example, you would have tables with columns:

USER_ID, LIKE_MOVIE, LIKE_MUSIC

USER_ID, FAVORITE_CUISINE

USER_ID, OWN_DOG, DOG_COUNT

This approach assumes that you will know the shape of information a company wants to store before hand and that it will not change often. If the shape of the data is unknown at design time, it would probably be better to go with that JSON field or a nosql database.


答:
Yes it is a violation of SRP as logging is a cross cutting concern.

The correct way is to delegate logging to a logger class (Interception) which sole purpose is to log - abiding by the SRP.

See this link for a good example:
https://msdn.microsoft.com/en-us/library/dn178467%28v=pandp.30%29.aspx

Here is a short example:

```<code>public interface ITenantStore
{
    Tenant GetTenant(string tenant);
    void SaveTenant(Tenant tenant);
}

public class TenantStore : ITenantStore
{
    public Tenant GetTenant(string tenant)
    {....}

    public void SaveTenant(Tenant tenant)
    {....}
}

public class TenantStoreLogger : ITenantStore
{
    private readonly ILogger _logger; //dep inj
    private readonly ITenantStore _tenantStore;

    public TenantStoreLogger(ITenantStore tenantStore)
    {
        _tenantStore = tenantStore;
    }

    public Tenant GetTenant(string tenant)
    {
        _logger.Log("reading tenant " + tenant.id);
        return _tenantStore.GetTenant(tenant);
    }

    public void SaveTenant(Tenant tenant)
    {
        _tenantStore.SaveTenant(tenant);
        _logger.Log("saving tenant " + tenant.id);
    }
}
</code>```

Benefits include

You can test this without logging - true unit testing

you can easily toggle logging on / off - even at runtime

you can substitute logging for other forms of logging, without ever having to change the TenantStore file.

Body:
Yes it is a violation of SRP as logging is a cross cutting concern.

The correct way is to delegate logging to a logger class (Interception) which sole purpose is to log - abiding by the SRP.

See this link for a good example:
https://msdn.microsoft.com/en-us/library/dn178467%28v=pandp.30%29.aspx

Here is a short example:

public interface ITenantStore
{
    Tenant GetTenant(string tenant);
    void SaveTenant(Tenant tenant);
}

public class TenantStore : ITenantStore
{
    public Tenant GetTenant(string tenant)
    {....}

    public void SaveTenant(Tenant tenant)
    {....}
}

public class TenantStoreLogger : ITenantStore
{
    private readonly ILogger _logger; //dep inj
    private readonly ITenantStore _tenantStore;

    public TenantStoreLogger(ITenantStore tenantStore)
    {
        _tenantStore = tenantStore;
    }

    public Tenant GetTenant(string tenant)
    {
        _logger.Log("reading tenant " + tenant.id);
        return _tenantStore.GetTenant(tenant);
    }

    public void SaveTenant(Tenant tenant)
    {
        _tenantStore.SaveTenant(tenant);
        _logger.Log("saving tenant " + tenant.id);
    }
}

Benefits include

You can test this without logging - true unit testing

you can easily toggle logging on / off - even at runtime

you can substitute logging for other forms of logging, without ever having to change the TenantStore file.


答:
If you're frequently going to run into custom field requests, I'd actually model it pretty similarly to the database.  Create a table that holds the metadata about each custom field, CompanyCustomField (who it belongs to, the data type, etc.) and another table CompanyCustomFieldValues which contains the CustomerId, FieldId and the value.  If you're using something like Microsoft Sql Server, I'd have the value column be a sql_variant datatype.

Of course this is not easy as you'll need an interface that lets admins define custom fields for each customer, and another interface that actually uses this metadata to build a UI to collect the field values.  And if you have other requirements, such as grouping of fields together or the need to do a pick list kind of field you'll need to accomdate that with more metadata / other tables (e.g., CompanyCustomFieldPickListOptions).

This is non trivial, but it has the advantage of not requiring database changes / code changes for every new custom field.  Any other features of custom fields will need to be coded as well (for example, if you want to regex validate a string value, or only allow dates between certain ranges, or if you need to enable one custom field based on another custom field value).

Title: How would you design a user database with custom fields

Body:
This question is around how should I design a database, it can be relational / nosql databases, depending on what will be the better solution

Given a requirement where you'll need to create a system that will involve a database to track "Company" and "User". A single user always only belong to one company

A user can only belong to one company

A company can have many users

The design for "Company" table is quite straightforward.
Company will have the following attributes / columns: (let's keep it simple)

```<code>ID, COMPANY_NAME, CREATED_ON
</code>```

First scenario

Simple & straight forward, users all have the same attribute, so this can be easily done in relational style, user table:

```<code>ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON
</code>```

Second scenario

What happen if different companies want to store different profile attribute for their user. Each company will have a defined set of attributes that would apply to all users of that company.

For example:

Company A wants to store: LIKE_MOVIE (boolean), LIKE_MUSIC (boolean)

Company B wants to store: FAV_CUISINE (String)

Company C wants to store: OWN_DOG (boolean), DOG_COUNT (int)

Approach 1

the brute force way is to have a single schema for the user and let them have nulls when they dont belong to the company:

```<code>ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, LIKE_MOVIE, LIKE_MUSIC, FAV_CUISINE, OWN_DOG, DOG_COUNT, CREATED_ON
</code>```

Which is kinda nasty because you will end up with a lot of NULLS and user rows that have columns that are irrelevant to them (ie. all users belonging to Company A has NULL values for FAV_CUISINE, OWN_DOG, DOG_COUNT)

Approach 2

a second approach, is to have "free form field":

```<code>ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_1, CUSTOM_2, CUSTOM_3, CREATED_ON
</code>```

Which would be nasty on its own since you have no idea what custom fields are, the data type will not be reflective of the values stored (eg. we'll store int value as VARCHAR).

Approach 3

I have looked into PostgreSQL JSON field, in which case you will have:

```<code>ID, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CUSTOM_PROFILE_JSON, CREATED_ON
</code>```

In this case, how would you be able to apply different schemas to a user?
A user with Company A will have schema that looks like

```<code> {"LIKE_MOVIE":"boolean", "LIKE_MUSIC": "boolean"}
</code>```

While a user with Company C will have a different schema:

```<code> {"OWN_DOG ":"boolean", "DOG_COUNT": "int"}
</code>```

How should I solve this issue? How can I design database properly to allow for this flexible schema for a single "object" (User) based on the relationship they have (Company)?

relational solution? nosql solution?

Edit: I've also thought about a "CUSTOM_PROFILE" table which will essentially store user attributes in rows rather than columns.

There are 2 problems with this approach:

1) The data grows per user grow as rows rather than columns - and this mean to get a full picture of the user, a lot of joins need to be done, multiple joins to the "custom profile" table on the different custom attributes

2) The data value is always stored as VARCHAR to be generic, even if we know the data is supposed to be integer or boolean etc


答:
For one reason or another, databases are the one field in which the inner platform effect shows up most often. This is just another case of the anti-pattern popping up.

In this case, you're trying to fight the natural and correct solution. Company A's users are not company B's users, and they should have their own tables for their own fields.

Your database vendor does not charge you by the table, and you don't need twice the diskspace for twice the tables (in fact, having two tables is more efficient because you don't store A's attributes for B's users. Even storing just NULLs takes space).

Of course, if there are sufficient common fields, you can factor those out into a shared Users table, and have a foreign key in each of the company-specific user tables. This is so simple a structure that no database query optimizer struggles with it. Any necessary JOIN is trivial.


答:
Please consider this as an alternative. The previous two examples will both require that you make changes to the schema as the application's scope grows in addition the "custom_column" solution is difficult to extend and maintain. Eventually you'll end up with Custom_510 and then just imagine how awful this table will be to work with.

First let's use your Companies schema.

```<code>[Companies] ComnpanyId, COMPANY_NAME, CREATED_ON
</code>```

Next we'll also use your Users schema for top level required attributes that will be used/shared by all companies.

```<code>[Users] UserId, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON
</code>```

Next we build a table where we will define our dynamic attributes that are specific to each companies custom user attributes. So here an example value of the Attribute column would be "LikeMusic":

```<code>[UserAttributeDefinition] UserAttributeDefinitionId, CompanyId, Attribute
</code>```

Next we define a UserAttributes table that will hold user attribute values

```<code>[UserAttributes] UserAttributeDefinitionId, UserId, Value
</code>```

This can be modified in many ways to be better for performance. You can use multiple tables for UserAttributes making each one specific to the data type being stored in Value or just leave it as a VarChar and work with it as a keyvalue store.

You also may want to move CompanyId off of the UserAttributeDefiniton table and into a cross reference table for future proofing.

Body:
Please consider this as an alternative. The previous two examples will both require that you make changes to the schema as the application's scope grows in addition the "custom_column" solution is difficult to extend and maintain. Eventually you'll end up with Custom_510 and then just imagine how awful this table will be to work with.

First let's use your Companies schema.

[Companies] ComnpanyId, COMPANY_NAME, CREATED_ON

Next we'll also use your Users schema for top level required attributes that will be used/shared by all companies.

[Users] UserId, COMPANY_ID, FIRST_NAME, LAST_NAME, EMAIL, CREATED_ON

Next we build a table where we will define our dynamic attributes that are specific to each companies custom user attributes. So here an example value of the Attribute column would be "LikeMusic":

[UserAttributeDefinition] UserAttributeDefinitionId, CompanyId, Attribute

Next we define a UserAttributes table that will hold user attribute values

[UserAttributes] UserAttributeDefinitionId, UserId, Value

This can be modified in many ways to be better for performance. You can use multiple tables for UserAttributes making each one specific to the data type being stored in Value or just leave it as a VarChar and work with it as a keyvalue store.

You also may want to move CompanyId off of the UserAttributeDefiniton table and into a cross reference table for future proofing.


答:
Your question has many potential solutions.  One solution is to store the additional attribrutes as XML.  The XML can be stored as text or if your using a database that supports XML types as XML (SQL Server).  Storing as text limits your querying ability (like searching on a custom attribute), but if storing and retrieval is all your need then its a good solution.  If one needs to query, then storing the XML as an XML type would be a better option (although this is more vendor specific).

This will give one the ability to store any number of attributes to a customer with just adding an addition column on the customer table.   One could store the attributes as a hashset or dictionary, one will lose type safety since everything will be a string to start with, but if one enforces standard format string for dates, numbers, booleans it will work out OK.

For more information:

https://msdn.microsoft.com/en-us/library/hh403385.aspx

@WalterMitty's answer is valid as well, although if one has a lot of customers with different attributes one could end up with many tables if following the inheritance model.  It depends on how many custom attributes are shared amongst customers.


答:
This sounds fine. You're describing a fairly standard logging decorator. You have:

component L (logging component of the system)

This has one responsibility: logging information that is passed to it.

component A implements I

This has one responsibility: providing an implementation of interface I (assuming I is properly SRP-compliant, that is).

This is the crucial part:

component D implements I, decorates/uses A, uses L for logging

When stated that way, it sounds complex, but look at it this way: Component D does one thing: bringing A and L together.

Component D does not log; it delegates that to L

Component D does not implement I itself; it delegates that to A

The only responsibility that component D has is to make sure that L is notified when A is used. The implementations of A and L are both elsewhere. This is completely SRP-compliant, as well as being a neat example of OCP and a pretty commonplace use of decorators.

An important caveat: when D uses your logging component L, it should do so in a way that lets you change how you're logging. The simplest way to do this is to have an interface IL that is implemented by L. Then:

Component D uses an IL to log; an instance of L is provided

Component D uses an I to provide functionality; an instance of A is provided

Component B uses an I; an instance of D is provided

That way, nothing depends directly on anything else, making it easy to swap them out. This makes it easy to adapt to change, and easy to mock parts of the system so you can unit test.


问:
How do you debug a complex application?
I have an application that is returning the wrong output, when it is run with a particular input choice.  I haven't been able to get anywhere near a diagnosis of the fault, despite spending about a day and a half on it. If it is run with Input A then it gets the correct output, if it has Input B then the output should be the same but is incorrect.  Input B goes through some slightly different processes to Input A, in an attempt to optimise it, although most of the steps are in common.

I am trying to compare side-by-side an invocation of the program with the two inputs.  Its a difficult way to debug as you have two application windows, two visual studio windows, and its easy to get mixed up.

The software is about 1 million lines of code, and some of the code is fiendishly complicated.  It has many nested loops and loops that run for a lot of iterations, with very complex variables.  It caches a lot of data, so when you find that values in one mode are different from the other you have to work out if the differences are significant, and then its hard to trap where the programs diverge since the values have already been calculated and you have to keep restarting the programs and going back.

I understand there is no silver bullet here but I just wondered if anyone had any tips?

答:
The answer is simple, the execution is complex.

Basically what you're trying to do is identify the point at which the variance occurs i.e. the point at which the actual result starts to move away from the expected result (and if this sounds like something that might show up through coded tests ("unit" and up) then that's not entirely surprising). Similarly you need to identify the point at which the variance stops i.e. where do the paths join such that you've got a result that changes consistently again. Having identified those points you can work to further narrow down the possible locations for the "errors".

The brute force way is adding debug/trace statements, breakpoints and inspection and then running the code.

You improve on this in two ways:

First by reducing the amount of code you have to run - there are diverse means. (As suggested, this means isolating/separating out the problematic code.)

Second by wrapping the stuff in tests (which is probably the best of the diverse means
if feasible).

Sadly none of this is straightforward or necessarily quick.

Title: How do you debug a complex application?


问:
Redistributing vendor libraries license exemption
I have a library that is MIT licensed. All of the vendor files (located in a vendor/ folder) are MIT licensed as well, so I'm not too worried about my current situation. I am curious what the legality is when I'm including other licenses (e.g. GPL).

Provided that the vendor allows redistribution, do I need to do anything to specifically let people know that the vendor files aren't included under my license. What would that look like?

答:
It's not quite that simple.

The purpose of the GPL is to provide what the Free Software Foundation sees as the "freedoms" that they believe are essential in all open source software.  A program is "free software" if the program's users have the four essential freedoms:

The freedom to run the program as you wish, for any purpose.

The freedom to study how the program works, and change it so it does your computing as you wish. Access to the source code is a
  precondition for this.

The freedom to redistribute copies so you can help your neighbor.

The freedom to distribute copies of your modified versions to others. By doing this you can give the whole community a chance to
  benefit from your changes. Access to the source code is a precondition
  for this.

When the FSF says that "access to the source code is a precondition," that means access to all of the source code.  More specifically, it means access to your source code.

So the GPL includes a Copyleft provision that states that, if you use a GPL library in your application and distribute it, then your entire application must be GPL.  In practice, that means that you must provide the source code for your entire application.

Simply telling folks that you can get the GPL components elsewhere is not a satisfactory workaround, especially if the GPL components are a required part of your software; in other words, your software won't work without the GPL libraries or code.  This is what the FSF calls a combined work.  Linking a GPL'd library statically or dynamically with other modules is making a combined work based on that library. Thus, the terms and conditions of the GNU General Public License cover the whole combination.

Assuming that your MIT licensed library contains no GPL'd components or links to any such components, the responsibility of license compliance rests with the user of your library, not you.


问:
Which (programming) specialities are needed in a good web development team?
At first glance, I'd say a good programming team needs to understand the following matters:

The details of the core language / framework

HTML, (asynchronous) javascript

SQL / data model

Usability / UI design

Security

Project management.

If this team is not complete: what is needed?

答:
Developers that know Regular Expressions properly.

For example: data validation, mod_rewrite rules, analysing logs, and so on.

There's many situations where regex knowledge can be a great help. And probably even more where knowing not to use (or ask for) a regex, because it isn't the best tool, will save time.

ContentLicense: CC BY-SA 2.5


问:
Value of unit testing property setters to check events
When coding in WPF with the MVVM pattern, it's common to see a lot of property get/set statements that raise an event, which can then be picked up by the UI layer.

```<code>    public string Address
    {
        get
        {
            return _address;
        }
        set
        {
            _address = value;
            OnPropertyChanged("Address");
        }
    }
</code>```

Many classes contain tens of these. The level of boilerplate code required is seen as a necessary evil by MVVM advocates.

However, one of the key advantages of MVVM over traditional code-behind models is that it's much easier to unit test. This is fine for functions and such, but there's a lot of uncovered code due to the getting and setting of these properties which is often done from the UI layer.

It made me wonder about the value of unit testing them. There's a valuable thing to check here: if a property doesn't raise the expected event, it can have severe repercussions for the functionality of the application. But on the other hand, changes to these properties are rare, and unit testing them would result in even more boilerplate code which would need to be maintained.

Are trivial functions like this worth the additional overhead of writing and maintaining tests?

EDIT: A commenter asked about how you'd unit test this. Here's an example from another property that I tested because the setter does more than just raise an event:

```<code>        Mock<IReciprocateRepository> repMock = GetMockRepository();
        CampaignViewModel cVm = new CampaignViewModel(repMock.Object);
        List<string> receivedEvents = new List<string>();

        cVm.PropertyChanged += (sender, e) => receivedEvents.Add(e.PropertyName);
        cVm.LoadHistory();

        Assert.IsTrue(receivedEvents.Contains("MemberItems"));
</code>```

答: In general, don't test trivial methods containing no logic. Once your getter or setter contains logic, then you can apply a unit test. Logic can be anything from an input validation  to a full blown implementation of something.</p>


答: In this case I would say DEFINITELY.  You are taking an action in a property that is above and beyond a simple value set. Unit tests will not only validate your design they will declare this as intent to future developers that come along and think about removing your additional code.</p>

Title: Value of unit testing property setters to check events

Body:
When coding in WPF with the MVVM pattern, it's common to see a lot of property get/set statements that raise an event, which can then be picked up by the UI layer.

```<code>    public string Address
    {
        get
        {
            return _address;
        }
        set
        {
            _address = value;
            OnPropertyChanged("Address");
        }
    }
</code>```

Many classes contain tens of these. The level of boilerplate code required is seen as a necessary evil by MVVM advocates.

However, one of the key advantages of MVVM over traditional code-behind models is that it's much easier to unit test. This is fine for functions and such, but there's a lot of uncovered code due to the getting and setting of these properties which is often done from the UI layer.

It made me wonder about the value of unit testing them. There's a valuable thing to check here: if a property doesn't raise the expected event, it can have severe repercussions for the functionality of the application. But on the other hand, changes to these properties are rare, and unit testing them would result in even more boilerplate code which would need to be maintained.

Are trivial functions like this worth the additional overhead of writing and maintaining tests?

EDIT: A commenter asked about how you'd unit test this. Here's an example from another property that I tested because the setter does more than just raise an event:

```<code>        Mock<IReciprocateRepository> repMock = GetMockRepository();
        CampaignViewModel cVm = new CampaignViewModel(repMock.Object);
        List<string> receivedEvents = new List<string>();

        cVm.PropertyChanged += (sender, e) => receivedEvents.Add(e.PropertyName);
        cVm.LoadHistory();

        Assert.IsTrue(receivedEvents.Contains("MemberItems"));
</code>```


答:
From the OOP point of view functions can be considered to be single-method interfaces.

Interface is a stronger contract than a function.

If you are using a functional approach and do a lot of DI then in comparison to using an OOP approach you will get more candidates for each dependency.

```<code>void DoStuff(Func<DateTime> getDateTime) {}; //Anything that satisfies the signature can be injected.
</code>```

vs

```<code>void DoStuff(IDateTimeProvider dateTimeProvider) {}; //Only types implementing the interface can be injected.
</code>```

Body:
From the OOP point of view functions can be considered to be single-method interfaces.

Interface is a stronger contract than a function.

If you are using a functional approach and do a lot of DI then in comparison to using an OOP approach you will get more candidates for each dependency.

void DoStuff(Func<DateTime> getDateTime) {}; //Anything that satisfies the signature can be injected.

vs

void DoStuff(IDateTimeProvider dateTimeProvider) {}; //Only types implementing the interface can be injected.


问:
Are there any good use-cases for variable variables?
Today I encountered this little PHP gem called variable variables.

```<code>$literal = "Hello";
$vv = "literal";
echo $$vv; // => prints "Hello"
</code>```

Are there actually any real use-cases for this language feature?

答:
Are there any good use-cases for variable variables?

It depends on your definition of "good".

My personal answer is simply no.

I tried to come up with one just to answer this question, I raked help questions on SO where people are using them, and read a guides and blog posts.

I just cannot find a scenario where it can be argued using a variable variable is more useful or worthwhile than another approach.

All I could think of and found where reasons against their usage.

I even read one article, with grateful and positive comments, which argued how it can make switch statements easier.

Switch statements, "simpler"?

I'd argue that even to someone very new to PHP, an array might arguably be a little trickier to wrap their head around at first, but the learning curve would drop way past that of learning variable variables once they begin trying to use them within code.

It would soon become confusing trying to follow and control the flow of variable variables.

Whereas once learned, an array is quite simple to look at and use.

As I see them, they:

Never resolve any problem which another option is not at least
equally suited, usually better

Make managing the codebase harder, because rather than a separate
variable with separate data, you now have "linked" variables tightly
coupled together, which is a mess waiting to happen

Are very rarely used, so readability is arguably lowered due to
unfamiliarity. Especially in classes/methods where missing that extra
$ ($var->*$*rogueVar) will be a temporary pain

The information for the child variable is not available without the
parent. $var = "james"; var name and value are right there.

Even the summary sounds icky - "a variable named based on a value
from another variable"

Even the PHP manual has information which, while unintentional, shows variable variables are complicated and potentially "troublesome":

PHP.net wrote:

In order to use variable variables with arrays, you have to resolve an
  ambiguity problem. That is, if you write $$a[1] then the parser needs
  to know if you meant to use $a[1] as a variable, or if you wanted $$a
  as the variable and then the [1] index from that variable. The syntax
  for resolving this ambiguity is: ${$a[1]} for the first case and
  ${$a}[1] for the second.

As their usage is very uncommon, I would argue that even seasoned developers would suddenly have some learning curve if another dev used this in their code.

Variable variables cannot be used with PHP's Superglobal arrays within functions or class methods.

This is more learning, and careful consideration to work around problems which using variable variables introduce.

For no benefit.

I think they may have been quite useful in older times, when "dinosaurs" roamed the datacentres. and PHP had not been refactored greatly and so much faster with things such as arrays etc.

If variable variables gave us some profound functionality, or even just highly useful, then perhaps using them would be worth the learning.

However, given what they offer, I just do not see the point in ever using them, even if an array is overkill and used some microseconds more, for the sake of code maintainability, readability, sanity preservation, and no difference in functionality, just use an alternative method - every time.


问:
have we come full circle with microservices, back to very old school approaches?
In terms of software architecture and design, how do microservices "stack up" (pun intended) against middleware?  I'm coming from Java, and it seems like as you move away from straight REST as an API, and abstract away different layers and connection parameters, at least in Java, you've almost come full circle back to some very old school ideas.  We've come back to virtualization...wheras the JVM is already virtual.

In an agnostic way, you can, and I would argue the advantages to, abstracting a RESTful API to CORBA.  Or, in a more java-centric way, JMS or MDB.

At one time EJB was a big deal in Java, then it was recognized to a bit of a cluster eff, but, now, are we back to the beginning?

Or, do microservices offer something which CORBA, or even better, MDB, lacks?  When I read (TLDR) Martin Fowler explaining microservices, it strikes me as a good solution to a bad problem, if you will.  Or rather, a closed minded approach which introduces a level of complexity only pushing the problem around.  If the services truly are micro, and are numerous, then each has a dollar cost to run and maintain it.

Furthermore, if one microservice amongst many changes its API, then everything depending on that service breaks.  It doesn't seem loosely coupled, it seems the opposite of agile.  Or am I misusing those words?

Of course, there are an indeterminate amount of choices between these extremes.

Shark versus Gorilla...go!  (For the pedantic, that's meant to be ironic, and isn't my intention at all.  The question is meant to be taken at face value.  If the question can be improved, please do so, or comment and I'll fix.)

Envision a multitude of microservices running in docker, all on one machine, talking to each other...madness.  Difficult to maintain or admin, and next to impossible to ever change anything because any change will cascade and cause unforeseeable errors.  How is it somehow better that these services are scattered across different machines?  And, if they're distributed, then surely some very, very old school techniques have solved, at least to a degree, distributed computing.

Why is horizontal scaling so prevalent, or at least desirable?

答:
TL;DR. I have had the pleasure of drinking a lot of Microserver flavored Kool-Aid, so I can speak a bit to the reasons behind them.

Pros:

Services know that their dependencies are stable and have had time to bake in

Allow rolling deployments of new versions

Allow components to be reverted without affecting higher layers.

Cons:

You cannot use the new and shiny features of your dependencies.

You can never break API backwards compatibility (or at least not for a many development cycles).

I think that you fundamentally misunderstand how a microservice architecture is supposed to work. The way it is supposed to be run is that every microservice (referred to from here on in as MS) has a rigid API that all of its clients agree upon. The MS is allowed to make any changes that it wants as long as the API is preserved. The MS can be thrown out and rewritten from scratch, as long as the API is preserved.

To aid in loose coupling, every MS depends on version n-1 of its dependencies. This allows for the current version of the service to be less stable and a bit more risky. It also allows versions to come out in waves. First 1 server is upgraded, then half, and finally the rest. If the current version ever develops any serious issues, the MS can be rolled back to a previous version with no loss of functionality in other layers.

If the API needs to be changed, it must be changed in a way that is backwards compatible.


答:
How is it somehow better that these services are scattered across different machines?

Because of the cloud.

Done laughing yet? Seriously though - for many businesses, the biggest cost for software isn't the software anymore. It's the bandwidth, hardware, CDN costs, etc. Now that everyone has a mobile device, there's just that much more traffic. And that will only get worse as your toaster gets its own internet connectivity.

So businesses are looking to manage those costs. Specifically, they're trying to handle the business problem of "if this thing blows up, how can I serve millions of people getting/using my software - without paying ahead of time for the servers to serve millions of people getting/using my software?".

Why is horizontal scaling so prevalent, or at least desirable?

Because it answers this (huge and increasing) business problem.

When you have a dozen users, you can toss all of the services on one box. This is good, since you only want to pay for one box. And you also don't want to pay for changes to the app to split up the various services when your business scales. These days, you don't have time to do that before the mob of customers lights your servers on fire anyways.

It's also good because it allows you to juggle server allocations so that you can:

use the most of the servers you have, leaving little to "waste".

measure the performance individual elements of your software.

reduce deployment/down time caused by releases.

Having very granular deployments makes those two things easier/better (in addition to helping to enforce better separation of concerns).

Title: have we come full circle with microservices, back to very old school approaches?

Body:
In terms of software architecture and design, how do microservices "stack up" (pun intended) against middleware?  I'm coming from Java, and it seems like as you move away from straight REST as an API, and abstract away different layers and connection parameters, at least in Java, you've almost come full circle back to some very old school ideas.  We've come back to virtualization...wheras the JVM is already virtual.

In an agnostic way, you can, and I would argue the advantages to, abstracting a RESTful API to CORBA.  Or, in a more java-centric way, JMS or MDB.

At one time EJB was a big deal in Java, then it was recognized to a bit of a cluster eff, but, now, are we back to the beginning?

Or, do microservices offer something which CORBA, or even better, MDB, lacks?  When I read (TLDR) Martin Fowler explaining microservices, it strikes me as a good solution to a bad problem, if you will.  Or rather, a closed minded approach which introduces a level of complexity only pushing the problem around.  If the services truly are micro, and are numerous, then each has a dollar cost to run and maintain it.

Furthermore, if one microservice amongst many changes its API, then everything depending on that service breaks.  It doesn't seem loosely coupled, it seems the opposite of agile.  Or am I misusing those words?

Of course, there are an indeterminate amount of choices between these extremes.

Shark versus Gorilla...go!  (For the pedantic, that's meant to be ironic, and isn't my intention at all.  The question is meant to be taken at face value.  If the question can be improved, please do so, or comment and I'll fix.)

Envision a multitude of microservices running in docker, all on one machine, talking to each other...madness.  Difficult to maintain or admin, and next to impossible to ever change anything because any change will cascade and cause unforeseeable errors.  How is it somehow better that these services are scattered across different machines?  And, if they're distributed, then surely some very, very old school techniques have solved, at least to a degree, distributed computing.

Why is horizontal scaling so prevalent, or at least desirable?


问:
Repository matrix pattern?
I'm trying really hard to refactor some of my legacy code in the project using best practices and design patterns + DDD so I'd love some feedback on an issue I'm currently having.

Let's assume that I have two entity classes:

class Dog
{
    protected $name;

    function __construct($name)
    {
        $this->name = $name;
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    function bark()
    {
        echo 'Rawr';
    }
}

class Husky extends Dog
{
    /**
     * @var Sledge
     */
    protected $sledge;

    function __construct($name, Sledge $slegde)
    {
        parent::__construct($name);
        $this->sledge = $slegde;
    }

    function pull()
    {
        echo $this->sledge->pull();
    }
}
```

Dog is my regular entity and his only responsibility is to map database fields.
Husky on the other hand has same responsibilities as dog but also delegates Sledge pulling.

Normally, both entities would have different repositories (should they? Since one inherits from one another) to call for, however business requirement implies that client does not have to specify dog's type (so it can either be a "basic" Dog or special Husky), just its name http://localhost/animal/fluffy.

What is more, currently they both reside in the same database table (recognized by type field) and right now there are no technical plans to change that (performance and time reasons).

What is the best way to do it?

Should I create some AnimalRepository, pull the data and treat it as DTO, detect it's type and then create appropriate class?

Should I create some kind of higher abstraction level mapper? How should it look like?

答:
We can solve any problem by introducing an extra level of indirection. I doubt that adding another level of abstraction would solve your problem.

I think the question you should be asking is 'do I need two repositories for this or just one' and the answer to this depends on a lot more than can be found here... No harm in starting off with the one Dog repository and moving off into separate repositories when it becomes clear that the Dog repository needs to have methods that are only valid for Huskies and your program structure would benefit from the separation.

Title: Repository matrix pattern?