答:
One option is to make it clear to the IDE and your users that there is a method, but you can't use the base class version:

```<code>class MyClass1(object):

    def func_2(self):
        raise NotImplementedError

    def func_1(self):
        return self.func_2() * 2
</code>```

You won't get warnings from intermediate classes that don't define func_2, but will get an error if you call it on a class that hasn't overridden it. The other option, pass, can hide these errors in some cases.

Title: Parent class using methods defined in child

Body:
I am working on a large program (more than 10k lines of code).

Below is a (hopefully not over-simplified) example of a problem I sometimes face:

```<code>class MyClass1(object):

    def func_1(self):
        return self.func_2() * 2

class MyClass6(MyClass1):

    def func_2(self):
        return 10

a = MyClass6().func_1()
print(a)  # Prints 20
</code>```

I need to use in MyClass1 a method that is defined later on in MyClass6.

Using this code as is, works fine. I get quite a visible warning:

and I can add a comment so that I know what is going on in the future in case I need to debug it. However, I can't use options in my IDE like Find usages, Rename etc.

Alternatively, I can use @abstractmethod to make it explicit that funct_2 is defined in a child class and my IDE options would work fine:

```<code>import abc

class MyClass1(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def func_2(self):
        return 'zzzz'

    def func_1(self):
        return self.func_2() * 2

class MyClass5(MyClass1):

    def func_2(self):
        return 10

a = MyClass5().func_1()
print(a)    # Prints 20
</code>```

... but I think this is not the way to go. For example I get weak warnings from my IDE for classes inbetween MyClass1 and MyClass5 (e.g. "MyClass4 has to implement abstract method...").

Question:

What is the right way to deal with a parent class using a method that is defined in a child class?

Edit:

Some extra details:
MyClass1 is never called on its own. Also func_2() has to be defined in MyClass6 because everything it needs is defined there as well.

Body:
One option is to make it clear to the IDE and your users that there is a method, but you can't use the base class version:

class MyClass1(object):

    def func_2(self):
        raise NotImplementedError

    def func_1(self):
        return self.func_2() * 2

You won't get warnings from intermediate classes that don't define func_2, but will get an error if you call it on a class that hasn't overridden it. The other option, pass, can hide these errors in some cases.


问:
What is the motivation behind the @ImplementedBy annotation in Guice?
I recently read about the @ImplementedBy annotation available in Google Guice. It allows the programmer to specify a binding between an interface and its implementation for future use in dependency injection. It is an example of a just-in-time binding.

I'm quite used to defining explicit bindings in my modules, using the following syntax:

```<code>bind(SomeInterface.class).to(SomeInterfaceImplementation.class);
</code>```

According to the documentation, this is equivalent to the following use of the @ImplementedBy annotation:

```<code>@ImplementedBy(SomeInterfaceImplementation.class)
public interface SomeInterface {
    //method declarations
}
</code>```

The only gain I can see here is that the code is marginally shorter. At the same time, this approach has a drawback rightly pointed out by the same docs:

Use @ImplementedBy carefully; it adds a compile-time dependency from the interface to its implementation.

Such dependency may not be a problem in many cases but I personally see it as a code smell.

What use cases make the @ImplementedBy annotation worth using?

One possible way seems to be to employ it in the code of a library or framework. As described in the docs, the annotation can provide a default binding easily overriden by an explicit one.

If a type is in both a bind() statement (as the first argument) and has the @ImplementedBy annotation, the bind() statement is used. The annotation suggests a default implementation that can be overridden with a binding.

This way, as the developer of a library, I can provide my users with an out of the box binding that can be customized somewhere in the client code.

Is this the only reason for the annotation to exist? Or is there something I'm missing? Can I gain anything by using it in code that is just an application taking care of some business logic and not a library/framework to be extended?

答:
I think the danger here is using only the @ImplementedBy annotation. Used appropriately, in conjunction with bind() statements in your module and so forth, it is okay.

Having a default implementation is great for testing; you don't necessarily want to have to explicitly define a mock injection every time you are testing a class that has lots of dependencies, or if you have a class that many things are dependent on (so you have to define a mock every single time).

For example, you might have a class:

```<code>@ImplementedBy(NoOpDataService.class)
interface DataService {
    Map<String, MyPOJO> getData();
}
</code>```

And then NoOpDataService is:

```<code>class NoOpDataService implements DataService {
    @Override
    public Map<String, MyPOJO> getData() {
        return Collections.emptyMap();
    }
}
</code>```

You'll never use this in your actual code, obviously; in your Guice module you would bind an implementation that actually does something. But all tests on classes that get an injected DataService don't need to have a mock binding anymore.

tl;dr I agree with you that having your interfaces depend on your implementation can be a code smell; but it can also remove boilerplate code make testing easier. It's not a difficult to implement feature; and while there is some small potential for abuse, ultimately the consequences cannot be too bad (a service starts up by surprise), and it would not be too hard to fix even if it does happen.

OwnerDisplayName: toniedzwiedz

ContentLicense: CC BY-SA 3.0

Body:
I think the danger here is using only the @ImplementedBy annotation. Used appropriately, in conjunction with bind() statements in your module and so forth, it is okay.

Having a default implementation is great for testing; you don't necessarily want to have to explicitly define a mock injection every time you are testing a class that has lots of dependencies, or if you have a class that many things are dependent on (so you have to define a mock every single time).

For example, you might have a class:

@ImplementedBy(NoOpDataService.class)
interface DataService {
    Map<String, MyPOJO> getData();
}

And then NoOpDataService is:

class NoOpDataService implements DataService {
    @Override
    public Map<String, MyPOJO> getData() {
        return Collections.emptyMap();
    }
}

You'll never use this in your actual code, obviously; in your Guice module you would bind an implementation that actually does something. But all tests on classes that get an injected DataService don't need to have a mock binding anymore.

tl;dr I agree with you that having your interfaces depend on your implementation can be a code smell; but it can also remove boilerplate code make testing easier. It's not a difficult to implement feature; and while there is some small potential for abuse, ultimately the consequences cannot be too bad (a service starts up by surprise), and it would not be too hard to fix even if it does happen.


问:
Database Normalization vs dependencies
I am developing 3-4 interdependent programs.  Call them foo bar baz and auth.  I want them to be independent of each other.  Imagine if I were to license out each program to other companies.  Some companies may want foo and bar, others may just want baz, etc.  It also seems like good practice to keep auth independent as well.

Context:
auth is taking care of authentication for all of the systems.  The main users table in auth has user_id, email, password, first, last

foo has a users table as well which has specific fields for the application:
user_id, role_id, etc.

Each system has its own database.  In the past I have created a foreign key from each application to the auth db.  I removed update permissions from the other dbs but granted select access to certain relevant fields.  This seems like a bad solution because it creates a tight dependency, but it allowed me to normalize the db so that I didn't have to store the users name and email in the foo, bar, or baz databases.

Would it be better to store the information in all of the databases?  Or would it be better to store the Auth Id in foo bar and baz and use an api to get the user info using the authId?

Similarly, I might have customers in all 3 systems.  Sure it seems bad to create a dependency into an auth db, but what about the customer dbs across all 3 of them?

Or is the best solution to have one central db.  One users table.

Other Suggestions?

答: I would recommend implementing Single Sign On (SSO), for example with LDAP. Your larger customers probably would have benefited from it as well, as they would be able to replace your built in auth app with their own existing user database. For your smaller customers that don't support SSO, you can simplify deployment by shipping your app with a default auth app.</p>

Title: Database Normalization vs dependencies


问:
I need a data structure for a card game
I am programming a card game in java, and unsure what data structure I should use for the player's hand.

I considered using an array, with one integer to traverse the array and another integer to increment and decrement the size of the player's hand. However, if a player removes a card from the middle of the array, then the array will have a hole in it.

I could shift the position of every subsequent card towards the 1 element of the array and decrement the integer that keeps track of the players hand -- but this seems insufficient. I also considered a linked list.

Does anyone have a better suggestion for a data structure or insight about the two ideas that I have?

答:
There are a couple things to think about here - the structure of a card and the structure of the collection of cards... and all the while keeping in mind that this is Java and should be written with proper attention to object oriented principles.

A card is a thing. Representing it entirely as a bit in a BitSet, or worse... doing your own bit manipulation and passing around a long really takes you away from those object oriented principles. You're instead dealing with "I've got bit 23 thats a jack of hearts" makes for some ugly coding.  Iterating over a bitset or bits set in a long isn't at all fun either. So, lets put that to rest - a bit isn't a card isn't a thing.

There are approaches based on this that aren't wrong for Java.  It is not unreasonable to stick all of the cards in an enum:

```<code>public enum Card {
  ACE_OF_HEARTS,
  TWO_OF_HEARTS,
  ...
  KING_OF_SPADES
}
</code>```

You could then use an EnumSet as the collection. Yes, its backed by a BitSet when you dig into it, but it's a nice collection to deal with.  It's actually a Collection (a BitSet isn't) and so you get the iterators and contains and the like.  A BitSet, you're doing your iteration by hand calling nextSetBit(5) to find out what the index of the next set bit.

I won't say that the enum with all the cards in it is wrong, but it isn't right either.  If you read the tutorial on enums from Oracle, you even find...

```<code>import java.util.*;

public class Card {
    public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX,
        SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }

    public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }

    private final Rank rank;
    private final Suit suit;
    private Card(Rank rank, Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }

    public Rank rank() { return rank; }
    public Suit suit() { return suit; }
    public String toString() { return rank + " of " + suit; }

    private static final List<Card> protoDeck = new ArrayList<Card>();

    // Initialize prototype deck
    static {
        for (Suit suit : Suit.values())
            for (Rank rank : Rank.values())
                protoDeck.add(new Card(rank, suit));
    }

    public static ArrayList<Card> newDeck() {
        return new ArrayList<Card>(protoDeck); // Return copy of prototype deck
    }
}
</code>```

And you've got a deck backed by the ArrayList.

Here's a thing to think about though. You can't have two jack of hearts in your hand... well, some games you might, but most games you don't. This means a collection of cards is a Set. This gives you a few options for how to implement the hand in such a way that doesn't mean juggling arrays.

I'd start with a LinkedHashSet as that maintains dealt order, or you might prefer either the TreeSet or ConcurrentSkipListSet if you want the cards to be in sorted order.  Note that this isn't as useful for dealing the cards from a deck as you would want that to be in a List because Collections.shuffle takes a list as arguments.  You also don't have to worry about pulling cards out of the middle of the deck when dealing. So the LinkedList would work very nicely for the deck itself when dealing cards (see pollFirst if you want to do it that way).

Some games though, you may find that you need to keep it in a deque (such as a LinkedList - so you get the poll first and last).  Others you want to keep the cards in a sorted structure, or others you may want something else. It all depends on what you want to do and finding the correct Collection (or not) to do it.

However, the data structure for a card should be that of the card presented by Oracle in the enum tutorial.  And then you use the Collection that maps to how you want to hold the cards.

Title: I need a data structure for a card game

Body:
There are a couple things to think about here - the structure of a card and the structure of the collection of cards... and all the while keeping in mind that this is Java and should be written with proper attention to object oriented principles.

A card is a thing. Representing it entirely as a bit in a BitSet, or worse... doing your own bit manipulation and passing around a long really takes you away from those object oriented principles. You're instead dealing with "I've got bit 23 thats a jack of hearts" makes for some ugly coding.  Iterating over a bitset or bits set in a long isn't at all fun either. So, lets put that to rest - a bit isn't a card isn't a thing.

There are approaches based on this that aren't wrong for Java.  It is not unreasonable to stick all of the cards in an enum:

public enum Card {
  ACE_OF_HEARTS,
  TWO_OF_HEARTS,
  ...
  KING_OF_SPADES
}

You could then use an EnumSet as the collection. Yes, its backed by a BitSet when you dig into it, but it's a nice collection to deal with.  It's actually a Collection (a BitSet isn't) and so you get the iterators and contains and the like.  A BitSet, you're doing your iteration by hand calling nextSetBit(5) to find out what the index of the next set bit.

I won't say that the enum with all the cards in it is wrong, but it isn't right either.  If you read the tutorial on enums from Oracle, you even find...

import java.util.*;

public class Card {
    public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX,
        SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }

    public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }

    private final Rank rank;
    private final Suit suit;
    private Card(Rank rank, Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }

    public Rank rank() { return rank; }
    public Suit suit() { return suit; }
    public String toString() { return rank + " of " + suit; }

    private static final List<Card> protoDeck = new ArrayList<Card>();

    // Initialize prototype deck
    static {
        for (Suit suit : Suit.values())
            for (Rank rank : Rank.values())
                protoDeck.add(new Card(rank, suit));
    }

    public static ArrayList<Card> newDeck() {
        return new ArrayList<Card>(protoDeck); // Return copy of prototype deck
    }
}

And you've got a deck backed by the ArrayList.

Here's a thing to think about though. You can't have two jack of hearts in your hand... well, some games you might, but most games you don't. This means a collection of cards is a Set. This gives you a few options for how to implement the hand in such a way that doesn't mean juggling arrays.

I'd start with a LinkedHashSet as that maintains dealt order, or you might prefer either the TreeSet or ConcurrentSkipListSet if you want the cards to be in sorted order.  Note that this isn't as useful for dealing the cards from a deck as you would want that to be in a List because Collections.shuffle takes a list as arguments.  You also don't have to worry about pulling cards out of the middle of the deck when dealing. So the LinkedList would work very nicely for the deck itself when dealing cards (see pollFirst if you want to do it that way).

Some games though, you may find that you need to keep it in a deque (such as a LinkedList - so you get the poll first and last).  Others you want to keep the cards in a sorted structure, or others you may want something else. It all depends on what you want to do and finding the correct Collection (or not) to do it.

However, the data structure for a card should be that of the card presented by Oracle in the enum tutorial.  And then you use the Collection that maps to how you want to hold the cards.


问:
Rich object model in the context of a good REST API and of an existing rich object model on the server-side
First off, let's frame this question in the context of a good REST API and an existing rich object model on the server-side, as well as modern web architecture (MVC frameworks like angularjs).

I'm debating whether or not to use a rich object model with my next project. The alternative is just using very light-weight POJO objects (pretty much whatever the API gives me) and using these in a non-persistent (between views) manner, i.e. no "application state". Just load what you need for the current operations and then get rid of it when you don't.

The risks of a rich object model that are giving me pause are:

1. Testability - it could be harder to unit test a complex object model

2. Performance - with a large object graph, the performance of the app could suffer. Contrast that with lightweight POJO's that get created and destroyed as needed, the app stays nimble.

3. Complexity - a complex object model could be orders of magnitude more complex than a lightweight app that just loads what it needs at the moment. This could also make it harder to modify...

4. Harder to modify - a rich object model creates a multitude of dependencies. This makes it harder to change things down the road.

I'm leaning towards a lean, light-weight web app that just loads what it needs at the moment and destroys what it doesn't.

答:
I have done both of these approaches in the past and I tend towards the simplified POJOs. The main reason is, it allows and forces in that the business logic is actually performed on the server.

When we used to send the full rich model to the client our client code started accumulating little bits and pieces of business logic everywhere and got rather nasty. And that made code reuse completely impossible as it was tied to a particular screen.

So instead I prefer to just preprocess the data exactly for the need of the client and let it deal with the display only.

The other reason I have seen the small POJOs work better is speed. (Which is not true in all cases). But assuming that the user only wants to modify this small portion. With the rich model you tend to have to pull in the entire thing to the client modify the small bit and the save the whole thing back. Depending on the size of your model and type of user interaction this may or may not be a problem.

And last is interactivity and concurrency. (Which depending on your application may or may not be needed.) But custom simple POJOs and services allow you to save changes as your user goes, in small pieces and refresh often from the database. Which in turn cuts down possible concurrency issues, that come in when two users modify the same big chunk of data and then save back.

On the other hand, if you are dealing with a large form with multiple sub-screens that gets filled out once, it might be better to send the entire model to the client process it there and save it back. This has the problem of having the business logic on the client. The way we have worked around this in the past is to encode the business logic in the model (such as sending validation rules as part of the model).

OwnerDisplayName: Richard DesLonde


问:
Is it a good idea to install more libraries than you need?
I decided to try Anaconda, it seems that too many large companies are using it. I was amazed by the number of libraries included by default

```<code>installing: python-2.7.9-2 ...
installing: conda-3.10.0-py27_0 ...
installing: conda-build-1.11.0-py27_0 ...
installing: conda-env-2.1.3-py27_0 ...
installing: _license-1.1-py27_0 ...
installing: abstract-rendering-0.5.1-np19py27_0 ...
installing: argcomplete-0.8.4-py27_0 ...
installing: astropy-1.0.1-np19py27_0 ...
installing: bcolz-0.8.1-np19py27_0 ...
installing: beautiful-soup-4.3.2-py27_0 ...
installing: binstar-0.10.1-py27_3 ...
installing: bitarray-0.8.1-py27_0 ...
installing: blaze-core-0.7.3-np19py27_0 ...
installing: blz-0.6.2-np19py27_0 ...
installing: bokeh-0.8.1-np19py27_1 ...
installing: boto-2.36.0-py27_0 ...
installing: cairo-1.12.18-1 ...
installing: cdecimal-2.3-py27_0 ...
installing: certifi-14.05.14-py27_0 ...
installing: cffi-0.9.2-py27_0 ...
installing: clyent-0.3.4-py27_0 ...
installing: colorama-0.3.3-py27_0 ...
installing: configobj-5.0.6-py27_0 ...
installing: cryptography-0.8-py27_0 ...
installing: curl-7.38.0-0 ...
installing: cython-0.22-py27_0 ...
installing: cytoolz-0.7.2-py27_0 ...
installing: datashape-0.4.4-np19py27_1 ...
installing: decorator-3.4.0-py27_0 ...
installing: docutils-0.12-py27_0 ...
installing: dynd-python-0.6.5-np19py27_0 ...
installing: enum34-1.0.4-py27_0 ...
installing: fastcache-1.0.2-py27_0 ...
installing: flask-0.10.1-py27_1 ...
installing: fontconfig-2.11.1-2 ...
installing: freetype-2.5.2-0 ...
installing: funcsigs-0.4-py27_0 ...
installing: futures-2.2.0-py27_0 ...
installing: gevent-1.0.1-py27_0 ...
installing: gevent-websocket-0.9.3-py27_0 ...
installing: greenlet-0.4.5-py27_0 ...
installing: grin-1.2.1-py27_1 ...
installing: h5py-2.4.0-np19py27_0 ...
installing: hdf5-1.8.14-0 ...
installing: ipython-3.0.0-py27_0 ...
installing: ipython-notebook-3.0.0-py27_1 ...
installing: ipython-qtconsole-3.0.0-py27_0 ...
installing: itsdangerous-0.24-py27_0 ...
installing: jdcal-1.0-py27_0 ...
installing: jedi-0.8.1-py27_0 ...
installing: jinja2-2.7.3-py27_1 ...
installing: jpeg-8d-0 ...
installing: jsonschema-2.4.0-py27_0 ...
installing: libdynd-0.6.5-0 ...
installing: libffi-3.0.13-0 ...
installing: libpng-1.5.13-1 ...
installing: libsodium-0.4.5-0 ...
installing: libtiff-4.0.2-1 ...
installing: libxml2-2.9.0-0 ...
installing: libxslt-1.1.28-0 ...
installing: llvmlite-0.2.2-py27_1 ...
installing: lxml-3.4.2-py27_0 ...
installing: markupsafe-0.23-py27_0 ...
installing: matplotlib-1.4.3-np19py27_1 ...
installing: mistune-0.5.1-py27_0 ...
installing: mock-1.0.1-py27_0 ...
installing: multipledispatch-0.4.7-py27_0 ...
installing: networkx-1.9.1-py27_0 ...
installing: nltk-3.0.2-np19py27_0 ...
installing: nose-1.3.4-py27_1 ...
installing: numba-0.17.0-np19py27_0 ...
installing: numexpr-2.3.1-np19py27_0 ...
installing: numpy-1.9.2-py27_0 ...
installing: odo-0.3.1-np19py27_0 ...
installing: openpyxl-1.8.5-py27_0 ...
installing: openssl-1.0.1k-1 ...
installing: pandas-0.15.2-np19py27_1 ...
installing: patsy-0.3.0-np19py27_0 ...
installing: pep8-1.6.2-py27_0 ...
installing: pillow-2.7.0-py27_1 ...
installing: pip-6.0.8-py27_0 ...
installing: pixman-0.26.2-0 ...
installing: ply-3.4-py27_0 ...
installing: psutil-2.2.1-py27_0 ...
installing: ptyprocess-0.4-py27_0 ...
installing: py-1.4.26-py27_0 ...
installing: py2cairo-1.10.0-py27_2 ...
installing: pyasn1-0.1.7-py27_0 ...
installing: pycosat-0.6.1-py27_0 ...
installing: pycparser-2.10-py27_0 ...
installing: pycrypto-2.6.1-py27_0 ...
installing: pycurl-7.19.5.1-py27_0 ...
installing: pyflakes-0.8.1-py27_0 ...
installing: pygments-2.0.2-py27_0 ...
installing: pyopenssl-0.14-py27_0 ...
installing: pyparsing-2.0.3-py27_0 ...
installing: pyqt-4.11.3-py27_0 ...
installing: pytables-3.1.1-np19py27_2 ...
installing: pytest-2.6.4-py27_0 ...
installing: python-dateutil-2.4.1-py27_0 ...
installing: pytz-2015.2-py27_0 ...
installing: pyyaml-3.11-py27_0 ...
installing: pyzmq-14.5.0-py27_0 ...
installing: qt-4.8.6-0 ...
installing: readline-6.2-2 ...
installing: redis-2.6.9-0 ...
installing: redis-py-2.10.3-py27_0 ...
installing: requests-2.6.0-py27_0 ...
installing: rope-0.9.4-py27_1 ...
installing: runipy-0.1.3-py27_0 ...
installing: scikit-image-0.11.2-np19py27_0 ...
installing: scikit-learn-0.15.2-np19py27_0 ...
installing: scipy-0.15.1-np19py27_0 ...
installing: setuptools-14.3-py27_0 ...
installing: sip-4.16.5-py27_0 ...
installing: six-1.9.0-py27_0 ...
installing: sockjs-tornado-1.0.1-py27_0 ...
installing: sphinx-1.2.3-py27_0 ...
installing: spyder-2.3.4-py27_1 ...
installing: spyder-app-2.3.4-py27_0 ...
installing: sqlalchemy-0.9.9-py27_0 ...
installing: sqlite-3.8.4.1-1 ...
installing: ssl_match_hostname-3.4.0.2-py27_0 ...
installing: statsmodels-0.6.1-np19py27_0 ...
installing: sympy-0.7.6-py27_0 ...
installing: system-5.8-2 ...
installing: terminado-0.5-py27_0 ...
installing: theano-0.6.0-np19py27_0 ...
installing: tk-8.5.18-0 ...
installing: toolz-0.7.1-py27_0 ...
installing: tornado-4.1-py27_0 ...
installing: ujson-1.33-py27_0 ...
installing: unicodecsv-0.9.4-py27_0 ...
installing: util-linux-2.21-0 ...
installing: werkzeug-0.10.1-py27_0 ...
installing: xlrd-0.9.3-py27_0 ...
installing: xlsxwriter-0.6.7-py27_0 ...
installing: xlwt-0.7.5-py27_0 ...
installing: yaml-0.1.4-0 ...
installing: zeromq-4.0.4-0 ...
installing: zlib-1.2.8-0 ...
installing: anaconda-2.2.0-np19py27_0 ...
installing: _cache-0.0-x0 ...
</code>```

I need many of them, it makes deployment so I easy, it has a cloning option, too many good options, but there are libraries I don't need, like PyQt and others.

So when it comes to deployment, is it a good idea to buy time and make your job easier by bloating the servers?

答:
Anaconda minimal install is about 30MB, while full install is about 300MB. so your customized libraries can range in that interval.

The main question is if servers disk space is so critical that 200MB make big difference.

In that case, you can always do a script to install 'minimal version' and your choosen libraries.

If you are thinking on deploy on dozens, hundreds or thousands of servers, its worth to create a script anyway (using fabric, maybe)


问:
Parent class using methods defined in child
I am working on a large program (more than 10k lines of code).

Below is a (hopefully not over-simplified) example of a problem I sometimes face:

```<code>class MyClass1(object):

    def func_1(self):
        return self.func_2() * 2

class MyClass6(MyClass1):

    def func_2(self):
        return 10

a = MyClass6().func_1()
print(a)  # Prints 20
</code>```

I need to use in MyClass1 a method that is defined later on in MyClass6.

Using this code as is, works fine. I get quite a visible warning:

and I can add a comment so that I know what is going on in the future in case I need to debug it. However, I can't use options in my IDE like Find usages, Rename etc.

Alternatively, I can use @abstractmethod to make it explicit that funct_2 is defined in a child class and my IDE options would work fine:

```<code>import abc

class MyClass1(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def func_2(self):
        return 'zzzz'

    def func_1(self):
        return self.func_2() * 2

class MyClass5(MyClass1):

    def func_2(self):
        return 10

a = MyClass5().func_1()
print(a)    # Prints 20
</code>```

... but I think this is not the way to go. For example I get weak warnings from my IDE for classes inbetween MyClass1 and MyClass5 (e.g. "MyClass4 has to implement abstract method...").

Question:

What is the right way to deal with a parent class using a method that is defined in a child class?

Edit:

Some extra details:
MyClass1 is never called on its own. Also func_2() has to be defined in MyClass6 because everything it needs is defined there as well.

答:
If your problem is only the warnings of IDE, you can avoid it using 2 solutions

solution 1, meta class

```<code>class ABCMeta():
    def func_2(self):
        return 1 #any valid value, just to your IDE dont complain

class MyClass1(ABCMeta):

    def func_1(self):
        return self.func_2() * 2

class MyClass5(MyClass1):

    def func_2(self):
        return 10 #the value you really want to use

a = MyClass5().func_1()
print(a)    # Prints 20
</code>```

solution 2, sintetic:

```<code>class MyClass1(ABCMeta):

    def func_2(self):
        return 1 #any valid value, just to your IDE dont complain

    def func_1(self):
        return self.func_2() * 2

class MyClass5(MyClass1):

    def func_2(self):
        return 10 #the value you really want to use
</code>```

Body:
If your problem is only the warnings of IDE, you can avoid it using 2 solutions

solution 1, meta class

class ABCMeta():
    def func_2(self):
        return 1 #any valid value, just to your IDE dont complain

class MyClass1(ABCMeta):

    def func_1(self):
        return self.func_2() * 2

class MyClass5(MyClass1):

    def func_2(self):
        return 10 #the value you really want to use

a = MyClass5().func_1()
print(a)    # Prints 20

solution 2, sintetic:

class MyClass1(ABCMeta):

    def func_2(self):
        return 1 #any valid value, just to your IDE dont complain

    def func_1(self):
        return self.func_2() * 2

class MyClass5(MyClass1):

    def func_2(self):
        return 10 #the value you really want to use


问:
How to measure the potential value of refactoring
On an old,  large project with technical debt how can you reliably estimate or measure the benefit of refactoring code?

For example, say you have some components within a software stack solution written in an older language, and some later components written in a newer language. New features and bug fixes are constantly being added to this solution by a development team.

The developers suggest that replacing the existing old language components with the new version would be 'a good thing' However, no extra features would be added by this work and it will cost x dev-days.

A sales person suggests adding 'a great new feature'. the company measures the value of his suggestion by using a formula. ie. It will earn the company F million pounds, over t years at a cost of x dev-days work

How can the company cost up the refactoring proposal in a meaningful way? and under what circumstances is it likely to be the most profitable option for the company?

答:
The value of refactoring can be measured like so: currently new feature x will cost 5 devs 2 weeks. If we refactor y old component, the cost of new features will be reduced by an estimated 20%.
So new feature x will only cost 4 devs over 2 weeks.

Refactoring is an investment in reducing the cost of future developments. If you can't make that argument for your refactoring, there probably isn't a business case for it.


问:
Does a Completely Full-Featured Intermediate Language Exist?
Often when translating between languages (whether with program translation or compiling) it's a one-way, destructive translation.  The functionality of the "port" isn't lost, but some of the intent and expression is.

For instance, porting a program from Java to C is possible, but you lose the notion of classes and methods.  If that program were to be ported back to Java you'd need to infer the intent of what would be considered an object to get back to the original state.  And that's something that a computer isn't good at doing.  As such you'd end up with a Java program that looked more like a C program with data structures and a big collection of static functions.

Also consider a compiler.  Once a language has been compiled down to assembler or even to say CIL or JVM, concepts such as if statements are lost as they are turned into branches.

On a higher level, source to source translators exist, but some languages have features (i.e. delegates in C#) which don't exist in other languages (like Java not having delegates).  The translation can happen, but is mildly destructive (i.e. Java would need a wrapper class to simulate delegates).

So, having said all that, is there a language who's goal is to be structurally compatible with all other languages by supporting all language features of all languages?

I'm not so concerned with being able to fully translate between languages as I am with being able to express each language's code in the common language.  So the goal would be translating to the common language and back again to the source language without losing anything.  Like: Java->Common->Java or LISP->Common->LISP

答:
Some intermediate languages have been successfully used as target for a lot of various languages, e.g. LLVM (or Ramsey & Jones' C--, which might be a dead project in 2015).

Notice that an intermediate language does not carry all the information provided in the source language (e.g. you are losing information when compiling from C to LLVM).

However, I am not sure that your wish makes sense. There are some programming language features which are not compositional, or are a whole program thing. Eg continuations (you can't implement call/cc without some support from your intermediate language), exceptions, or even garbage collection or parallelism or homoiconicity or persistence or threads (or concurrency).

Notice that for your question programming language semantics matter much more than syntax. Of course, all these intermediate representations are theoretically Turing-equivalent e.g. to a RAM machine.

BTW, some people might believe that x86-64 machine code or JavaScript is actually what you want....

In 2020  consider also libgccjit or Gimple or even generating C code. See of course this answer and Bismon. In RefPerSys we want to generate C++ code

ContentLicense: CC BY-SA 4.0


问:
How to explain why design choices are good?
As I've become a better developer, I find that much of my design skill comes more from intuition than mechanical analysis. This is great. It lets me read code and get a feel for it quicker. It lets me translate designs between languages and abstractions much easier. And it lets me get stuff done faster.

The downside is that I find it harder to explain to teammates (and worse, management) why a particular design is advantageous; especially teammates that are behind the times on best practices. "This design is more testable!" or "You should favor composition over inheritance." go right over their heads, and lead into the rabbit hole of me trying to clue everyone in to the last decade of software engineering advances.

I'll get better at it with practice of course, but in the mean time it involves a lot of wasted time and/or bad design (that will lead to wasted time fixing it later). How can I better explain why a certain design is superior, when the benefits aren't completely obvious to the audience?

答:
Depends on the audience! As developers we developed an intuition for good and bad code, and use vague emotional terms like "code smell", "ugly code", "beautiful solution". This only works when communicating with other developers with the same mindset. Try to explain your non-technical CEO that you should invest x man-hours into making some code "more beautiful" you will most likely fail spectacularly.

You need to be able to make the case that any given design improvement will either

save money for the company

make money for the company

For example, what is the case for adhering to the single-responsibility principle? If each class have a single responsibility it makes it much easier to locate and fix bugs, and it makes it easier to add features and improvements. Less time fixing bugs and adding features = money saved.


问:
Ternary operator considered harmful?
For example, would you prefer this one-liner

```<code>int median(int a, int b, int c) {
    return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
</code>```

or an if/else solution involving multiple return statements?

When is ?: appropriate, and when is it not? Should it be taught to or hidden from beginners?

答:
This can be reformatted to be as nice-looking as the if/else combination:

```<code>int median(int a, int b, int c)
{
    return
        (a<b)
        ?
            (b<c)
            ? b
            :
                (a<c)
                ? c
                : a
        :
            (a<c)
            ? a
            :
                (b<c)
                ? c
                : b;
}
</code>```

But the problem is that I am not really sure if I got the indentation right to represent what will actually happen. :-)

Title: Ternary operator considered harmful?

Body:
This can be reformatted to be as nice-looking as the if/else combination:

int median(int a, int b, int c)
{
    return
        (a<b)
        ?
            (b<c)
            ? b
            :
                (a<c)
                ? c
                : a
        :
            (a<c)
            ? a
            :
                (b<c)
                ? c
                : b;
}

But the problem is that I am not really sure if I got the indentation right to represent what will actually happen. :-)

ContentLicense: CC BY-SA 2.5


答:
Sending data over the wire to an API Is, I think, one of the key drivers of an ADM/POCO style approach to programming (see my question : https://softwareengineering.stackexchange.com/questions/283725/ where i touch on some of the same points)

If you take the OOP route, you are faced with the problems of serializing a model which jealously guards its data and then creating a similar model on the server side from that data which may need maybe of the same basic functions, but all the best practice guides (for good reason) warn against using the same model on both sides of the service.

The ADM route makes the whole thing simpler, but there is a danger here that as the functionality of the service becomes complex, your simple procedural approach will result in 'bad' code, futhermore, there is a temptation for this style to spread to the application side of the interface.

However, I do think you can have the best of two worlds here. With the service you cant get around the fact that you are programming a function which takes a data struct as a parameter and making your program match this fact is the best thing to do.

As you can see in my example though, there's no reason not to make the service itself follow OOP within the restraint of 'you must receive and return a struct'

On the app side the restriction of 'some methods are not run on this machine' are harder to deal with. You can inject the service into the model and then have model.method() calling the service, but this will lead to some very contrived code in my opinion.

Or you can use the ADM approach of calling the methods on the serviceclient objects passing in your struct like models. Again this non OOP approach matches the reality of the situation, whilst enabling you to keep the rest of your code sensible

Title: Rich object model in the context of a good REST API and of an existing rich object model on the server-side

Body:
First off, let's frame this question in the context of a good REST API and an existing rich object model on the server-side, as well as modern web architecture (MVC frameworks like angularjs).

I'm debating whether or not to use a rich object model with my next project. The alternative is just using very light-weight POJO objects (pretty much whatever the API gives me) and using these in a non-persistent (between views) manner, i.e. no "application state". Just load what you need for the current operations and then get rid of it when you don't.

The risks of a rich object model that are giving me pause are:

1. Testability - it could be harder to unit test a complex object model

2. Performance - with a large object graph, the performance of the app could suffer. Contrast that with lightweight POJO's that get created and destroyed as needed, the app stays nimble.

3. Complexity - a complex object model could be orders of magnitude more complex than a lightweight app that just loads what it needs at the moment. This could also make it harder to modify...

4. Harder to modify - a rich object model creates a multitude of dependencies. This makes it harder to change things down the road.

I'm leaning towards a lean, light-weight web app that just loads what it needs at the moment and destroys what it doesn't.


问:
Detecting and Dealing with obscene language in user input
I've seen some pretty darned restrictive 'chat-systems' in kids games, that make it nigh-on-impossible to get much of a message across whilst typing.

So, I looked at some ideas, and there where two main ones, the whitelist and the blacklist:

Whitelisted words are the only words you can use.

Certainly safe language without a doubt.

Very, very restricted conversation.

Large data needed for freer conversation.

Blacklisted words are the only words you can't use.

Easy detection of specific words.

May not be a comprehensive list.

Doesn't deal with 5tr4n9e w4y5 0f typ1n9.

Clearly, the whitelist is not the way to go for easy, free conversation, but the blacklist could easily be bypassed.

Furthermore, how should disallowed words be dealt with? For instance, If I were to send the string "You're truly elucidating!" through the whitelist, which probably wouldn't have a benign but very complex word such as elucidate in it's database, and it instead broadcast "You're truly ***********!, I doubt many people would take it as a compliment. The blacklist has a similar problem - should I blank out curse words, or just entirely prevent such a message fro  being sent?

So: What method should I use to detect and handle obcene language in user input without restricting conversation, but keeping things 100% safe?

As a sidenote, an API for a dictionary that marks out obscene language would be useful for both a whitelist and a blacklist.

答:
There is no technical solution to this problem.

From Jeff Atwood's article:

I'm doubtful it will ever be possible to solve this particular problem through code alone.

If a user really wants to use bad words in messages, he will still achieve it if the only filter is a program.

Is “fuck” a forbidden word? OK, we'll try “f*uck”: still understandable, but more difficult to catch for an application.

Still caught? What about “uck (the first letter is not an “f”, but the mathematical sans-serif small “f” 0x1d5bf).

What? Your app understands that 0x1d5bf character is visually similar to the character “f”? It's OK, there are plenty of other characters in Unicode which will appear visually similar.

Even a more basic problem—determining what constitutes a word—is not that easy. In a perfect ASCII world, a word would be some characters in [A-Za-z] range separated by a space. In a real world, you have punctuation, diacritics, characters which are not displayed, and dozens of other Unicode things which can make a simple task of separating text into words in the same way a human will do very, very challenging.

Of course, all those problems are solved with a dictionary of whitelisted words. You're back to ASCII, space character and basic punctuation. In such restricted context, it becomes easy to parse text programmatically and reject text which contains something your app doesn't understand. This, in turn, has two major problems:

Nobody sane will enjoy a conversation in a such controlled environment.

Obscenity will take other routes. It's always possible to tell obscene things without using obscene words.

Instead, why not using a system similar to Stack Exchange's one with the ability for the community to edit messages, to close ones for which the site is not the right place, and flag ones which are particularly problematic or harmful?


问:
The principle of least knowledge
I understand the motive behind the principle of least knowledge, but I find some disadvantages if I try to apply it in my design.

One of the examples of this principle (actually how not to use it), which I found in the book Head First Design Patterns specify that it is wrong to call a method on objects that were returned from calling other methods, in terms of this principle.

But it seems that sometimes it is very needed to use such capability.

For example:
I have several classes: video-capture class, encoder class, streamer class, and they all use some basic other class, VideoFrame, and since they interact with each other, they can do for example something like this:

streamer class code

```<code>...
frame = encoder->WaitEncoderFrame()
frame->DoOrGetSomething();
....
</code>```

As you can see, this principle is not applied here. Can this principle be applied here, or is it that this principle cannot always be applied in a design like this?

答:
Is functional design better than object-oriented design?  It depends.

Is MVVM better than MVC?  It depends.

Amos & Andy or Martin and Lewis?  It depends.

What does it depend on?  The choices you make depend on how well each technique or technology meets your software's functional and non-functional requirements, while adequately satisfying your design, performance and maintainability goals.

[Some book] says that [some thing] is wrong.

When you read this in a book or blog, evaluate the claim based on its merit; that is, ask why.  There is no right or wrong technique in software development, there is only "how well does this technique meet my goals?  Is it effective or ineffective?  Does it solve one problem but create a new one?  Can it be well-understood by the entire development team, or is it too obscure?"

In this particular case -- the act of calling a method on an object returned by another method -- since there is an actual design pattern that codifies this practice (Factory), it's difficult to imagine how one could make the assertion that it is categorically wrong.

The reason it's called the "Principle of Least Knowledge" is that "Low Coupling" is a desirable quality of a system.  Objects that are not tightly-bound to each other work more independently, and are therefore easier to maintain and modify individually.  But as your example shows, there are times when high-coupling is more desirable, so that objects can more effectively coordinate their efforts.

Title: The principle of least knowledge


答:
The principle you are talking of (better known as Law of Demeter) for functions can be applied by adding another helper method to your streamer class like

```<code>  {
    frame = encoder->WaitEncoderFrame()
    DoOrGetSomethingForFrame(frame);
    ...
  }

  void DoOrGetSomethingForFrame(Frame *frame)
  {
     frame->DoOrGetSomething();
  }
</code>```

Now, each function only "talks to friends", not to "friends of friends".

IMHO it is a rough guideline which can help to create methods which follow more strictly the single responsibility principle. In a simple case like the one above it is probably very opinionated if this is really worth the hassle and if the resulting code is really "cleaner", or if it will just expand your code formally without any noteable gain.

Title: The principle of least knowledge

Body:
I understand the motive behind the principle of least knowledge, but I find some disadvantages if I try to apply it in my design.

One of the examples of this principle (actually how not to use it), which I found in the book Head First Design Patterns specify that it is wrong to call a method on objects that were returned from calling other methods, in terms of this principle.

But it seems that sometimes it is very needed to use such capability.

For example:
I have several classes: video-capture class, encoder class, streamer class, and they all use some basic other class, VideoFrame, and since they interact with each other, they can do for example something like this:

streamer class code

```<code>...
frame = encoder->WaitEncoderFrame()
frame->DoOrGetSomething();
....
</code>```

As you can see, this principle is not applied here. Can this principle be applied here, or is it that this principle cannot always be applied in a design like this?

Body:
The principle you are talking of (better known as Law of Demeter) for functions can be applied by adding another helper method to your streamer class like

  {
    frame = encoder->WaitEncoderFrame()
    DoOrGetSomethingForFrame(frame);
    ...
  }

  void DoOrGetSomethingForFrame(Frame *frame)
  {
     frame->DoOrGetSomething();
  }

Now, each function only "talks to friends", not to "friends of friends".

IMHO it is a rough guideline which can help to create methods which follow more strictly the single responsibility principle. In a simple case like the one above it is probably very opinionated if this is really worth the hassle and if the resulting code is really "cleaner", or if it will just expand your code formally without any noteable gain.


答:
The Principle of least knowledge or the Law of Demeter is a warning against entangling your class with details of other classes that traverse layer after layer.  It tells you that it is better to talk only with your "friends" and not with "friends of friends".

Imagine you've been asked to weld a shield onto a statue of a knight in shiny plate armor.  You carefully position the shield on the left arm so it looks natural.  You notice there are three small places on the forearm, the elbow, and the upper arm where the shield happens to touch the armor.  You weld all three places because you want to be sure the connection is strong. Now imagine your boss is mad because he can't move the elbow of his armor. You assumed the armor was never going to move and so created an immobile connection between forearm and upper arm. The shield should only connect to it's friend, forearm. Not to forearms friends. Even if you have to add a chunk of metal to make them touch.

Metaphors are nice but what do we actually mean by friend? Any thing an object knows how to create or find is a friend. Alternatively, an object can just ask to be handed other objects, of which it only knows the interface.  These don't count as friends because no expectation on how to get them is imposed. If the object doesn't know where they came from because something else passed/injected it then it's not a friend of a friend, it's not even a friend. It's something the object only knows how to use. That's a good thing.

When trying to apply principles like this it's important to understand that they are never forbidding you from accomplishing something.  They are a warning that you might be neglecting to do more work to achieve a better design that accomplishes the same thing.

No one wants to do work for no reason so it's important to understand what you're getting out of following this.  In this case it keeps your code flexible.  You can make changes and have fewer other classes impacted by the changes to worry about. That sounds good but doesn't help you decide what to do unless you take it as some kind of religious doctrine.

Instead of blindly following this principle take a simple version of this problem. Write a solution that doesn't follow the principle and one that does. Now that you have two solutions you can compare how receptive each is to changes by trying to make them in both.

If you CAN'T solve a problem while following this principle there is likely another skill you're missing.

One solution to your particular problem is to inject the frame into something (a class or method) that knows how to talk to frames so you don't have to spread all those frame chatting details in your class, which now only knows how and when to get a frame.

That actually follows another principle:  Separate use from construction.

```<code>frame = encoder->WaitEncoderFrame()
</code>```

By using this code you've taken responsibility for somehow acquiring a Frame.  You haven't yet assumed any responsibility for talking to a Frame.

```<code>frame->DoOrGetSomething();
</code>```

Now you have to know how to talk to a Frame, but replace that with:

```<code>new FrameHandler(frame)->DoOrGetSomething();
</code>```

And now you only have to know how to talk to your friend, FrameHandler.

There are many ways to achieve this and this is, perhaps, not the best one but it shows how following the principle doesn't make the problem unsolvable.  It's just demanding more work from you.

Every good rule has an exception.  Best examples I know are internal Domain Specific Languages.  A DSLs method chain seems to abuse the Law of Demeter all the time because you are constantly calling methods that return different types and using them directly.  Why is this OK?  Because in a DSL everything that is returned is a carefully designed friend that you are meant to talk to directly.  By design, you have been given the right to expect a DSL's method chain not to change.  You don't have that right if you just randomly delve into the code base chaining together whatever you find.  The best DSLs are very thin representations or interfaces to other objects that you likely shouldn't delve into either.  I only mention this because I found I understood the law of demeter much better once I learned why DSLs are  a good design.  Some go so far as to say DSL's don't even violate the real law of demeter.  They just seem to when you look at the law superficially.

Another solution is to let something else inject frame into you.  If frame came in from a setter or preferably a constructor then you're not taking any responsibility for constructing or acquiring a frame.  This means your role here is much more like FrameHandlers was going to be.  Instead now you're the one who's chatty with Frame and making something else figure out how to get a Frame  In a way this is the same solution with a simple change of perspective.

The SOLID principles are the big ones I try to follow.  Two being respected here are Single Responsibility and Dependency Inversion Principles. It's really hard to respect these two and still end up violating the Law of Demeter.

The mentality that goes into violating Demeter is like eating at a buffet restaurant where you just grab whatever you want.  With a little work upfront you can provide yourself with a menu and a server who'll bring you anything you like. Sit back, relax, and tip well.

Title: The principle of least knowledge

Body:
The Principle of least knowledge or the Law of Demeter is a warning against entangling your class with details of other classes that traverse layer after layer.  It tells you that it is better to talk only with your "friends" and not with "friends of friends".

Imagine you've been asked to weld a shield onto a statue of a knight in shiny plate armor.  You carefully position the shield on the left arm so it looks natural.  You notice there are three small places on the forearm, the elbow, and the upper arm where the shield happens to touch the armor.  You weld all three places because you want to be sure the connection is strong. Now imagine your boss is mad because he can't move the elbow of his armor. You assumed the armor was never going to move and so created an immobile connection between forearm and upper arm. The shield should only connect to it's friend, forearm. Not to forearms friends. Even if you have to add a chunk of metal to make them touch.

Metaphors are nice but what do we actually mean by friend? Any thing an object knows how to create or find is a friend. Alternatively, an object can just ask to be handed other objects, of which it only knows the interface.  These don't count as friends because no expectation on how to get them is imposed. If the object doesn't know where they came from because something else passed/injected it then it's not a friend of a friend, it's not even a friend. It's something the object only knows how to use. That's a good thing.

When trying to apply principles like this it's important to understand that they are never forbidding you from accomplishing something.  They are a warning that you might be neglecting to do more work to achieve a better design that accomplishes the same thing.

No one wants to do work for no reason so it's important to understand what you're getting out of following this.  In this case it keeps your code flexible.  You can make changes and have fewer other classes impacted by the changes to worry about. That sounds good but doesn't help you decide what to do unless you take it as some kind of religious doctrine.

Instead of blindly following this principle take a simple version of this problem. Write a solution that doesn't follow the principle and one that does. Now that you have two solutions you can compare how receptive each is to changes by trying to make them in both.

If you CAN'T solve a problem while following this principle there is likely another skill you're missing.

One solution to your particular problem is to inject the frame into something (a class or method) that knows how to talk to frames so you don't have to spread all those frame chatting details in your class, which now only knows how and when to get a frame.

That actually follows another principle:  Separate use from construction.

frame = encoder->WaitEncoderFrame()

By using this code you've taken responsibility for somehow acquiring a Frame.  You haven't yet assumed any responsibility for talking to a Frame.

frame->DoOrGetSomething();

Now you have to know how to talk to a Frame, but replace that with:

new FrameHandler(frame)->DoOrGetSomething();

And now you only have to know how to talk to your friend, FrameHandler.

There are many ways to achieve this and this is, perhaps, not the best one but it shows how following the principle doesn't make the problem unsolvable.  It's just demanding more work from you.

Every good rule has an exception.  Best examples I know are internal Domain Specific Languages.  A DSLs method chain seems to abuse the Law of Demeter all the time because you are constantly calling methods that return different types and using them directly.  Why is this OK?  Because in a DSL everything that is returned is a carefully designed friend that you are meant to talk to directly.  By design, you have been given the right to expect a DSL's method chain not to change.  You don't have that right if you just randomly delve into the code base chaining together whatever you find.  The best DSLs are very thin representations or interfaces to other objects that you likely shouldn't delve into either.  I only mention this because I found I understood the law of demeter much better once I learned why DSLs are  a good design.  Some go so far as to say DSL's don't even violate the real law of demeter.  They just seem to when you look at the law superficially.

Another solution is to let something else inject frame into you.  If frame came in from a setter or preferably a constructor then you're not taking any responsibility for constructing or acquiring a frame.  This means your role here is much more like FrameHandlers was going to be.  Instead now you're the one who's chatty with Frame and making something else figure out how to get a Frame  In a way this is the same solution with a simple change of perspective.

The SOLID principles are the big ones I try to follow.  Two being respected here are Single Responsibility and Dependency Inversion Principles. It's really hard to respect these two and still end up violating the Law of Demeter.

The mentality that goes into violating Demeter is like eating at a buffet restaurant where you just grab whatever you want.  With a little work upfront you can provide yourself with a menu and a server who'll bring you anything you like. Sit back, relax, and tip well.


问:
What are the practical implications of homotopy type theory in programming?
I am just beginning to learn Haskell, after coming from the JavaScript/Ruby worlds. I have come across https://github.com/HoTT and the Homotopy Type Theory book, which I am very eager to read.

However, I will be learning the math and type theory concepts as I go, so it seems like it will take a long time before I understand what homotopy type theory will mean to a practicing programmer.

Could you describe what impact homotopy type theory will have on programming in practice, for a layman? For example, will it make certain things easier to easier to write? If so, which things? Or will it allow for you to do new things in programming that weren't previously possible? If so, which things?

Thanks, very much looking forward to wrapping my head around it at a more basic level.

答:
One of the powerful things compilers are able to do during their optimization
phase is to swap out inefficient representations for equivalent ones. For
example, in Haskell you could use a lazy list to compute a sum of numbers, but
the GHC Haskell compiler will recognize that this is equivalent to using
iteration with a temporary variable. That way, you get to program against a
simple abstraction that's easy to reason about, while your executable takes
advantage of a representation better suited to the hardware platform (and that
happens to be much harder to reason about at scale).

However, equivalences known to the compiler are mostly restricted to well
known and researched data structures, such as stream fusion for lists. You could
define your own equivalences in source code (using a pair of conversion
functions that compose to identity in either direction), but you'd have to
apply them manually, and it can get tricky to choose the right type to use in
all places in order to avoid excessive conversions.

Now let's imagine a world where you get to define "higher inductive types",
say a canonical lookup map. This type has several constructors for the various
kinds of maps: binary search, AVL, red-black, Trie, Patricia, etc. Along with
the typical data constructors, you also define an equivalence type capturing
possibly multiple conversions between these representations, where different
conversions offer varying dimensions of efficiency (i.e., time vs. memory).

What if the compiler were able to use this notion to transparently rewrite map
representations, the same way it can do today with list fusion? Meanwhile, in
your code you get to work with the construction that is simplest to reason
about (and makes proof work easier, if you are in such an environment). This
may sound just like an abstract interfaces with multiple implementations, but
it includes the freedom to choose any implementation and have the compiler
transparently substitute another as needed, without affecting the meaning of
the program.

HoTT gives us a type theoretic foundation to justify this fancy rewriting
mechanism and these richly defined types, because it promotes the notion of
equivalence to being equivalent to equality. It remains to be seen how this
will actually play out in practice, but it gives us the theoretical framework
on which to base future work.


答:
I've heard great things about WebPurify's profanity APIs.  It's not free, but they have a thing on their website where you can type sample text in and see if it detects anything:

http://www.webpurify.com/features/

I just put in f-u-c-k and it detected profanity, so that's a good sign...

Title: Detecting and Dealing with obscene language in user input

Body:
I've seen some pretty darned restrictive 'chat-systems' in kids games, that make it nigh-on-impossible to get much of a message across whilst typing.

So, I looked at some ideas, and there where two main ones, the whitelist and the blacklist:

Whitelisted words are the only words you can use.

Certainly safe language without a doubt.

Very, very restricted conversation.

Large data needed for freer conversation.

Blacklisted words are the only words you can't use.

Easy detection of specific words.

May not be a comprehensive list.

Doesn't deal with 5tr4n9e w4y5 0f typ1n9.

Clearly, the whitelist is not the way to go for easy, free conversation, but the blacklist could easily be bypassed.

Furthermore, how should disallowed words be dealt with? For instance, If I were to send the string "You're truly elucidating!" through the whitelist, which probably wouldn't have a benign but very complex word such as elucidate in it's database, and it instead broadcast "You're truly ***********!, I doubt many people would take it as a compliment. The blacklist has a similar problem - should I blank out curse words, or just entirely prevent such a message fro  being sent?

So: What method should I use to detect and handle obcene language in user input without restricting conversation, but keeping things 100% safe?

As a sidenote, an API for a dictionary that marks out obscene language would be useful for both a whitelist and a blacklist.


问:
How do I safely write code in my own 'words' and not plagiarize?
I understand plagiarism and paraphrasing fairly well when it comes to writing a research paper, but those equivalent areas in programming seem foreign to me. I've looked up the topics online, and surprisingly there is not as much material on the subject as one would have expected.

When writing code and having to implement something I've never implemented before, I'll go online to look for an example. I try to read through the documentation beforehand, but sometimes I find it challenging to follow. So if that fails, I will search for the topic online and be presented with dozens of examples (whether they be on someone's personal blog or a Q&A site like SO). Now I'm usually presented with 5-10 lines of code. I have and will NEVER copy-and-paste that into my own code, but I still worry about copying it down verbatim. I find it hard to reword a certain piece of code, especially when there are only so many ways to do so. I make sure to rename variables, change formatting, etc. - but is this enough?

I've always wanted to understand this topic, but now that I'm working with a new language and in a corporate environment I think that it is especially pertinent. If anyone could explain or link to a good explanation elsewhere, I would greatly appreciate that!

tl;dr
I don't understand how much you have to change and reword 5-10 snippets of code found online to avoid plagiarism. What if there is very little that you can change?

答:
I'd suggest that you use whatever sources you can find to figure out how to solve a problem. And once you have figured it out, you remove all these sources from the screen and write your own solution.

Unless you have a photographic memory and copy one of the existing solutions, this solves the problem of plagiarism and/or copyright infringement. It also helps you by forcing you to actually understand the problem.

You can go a slight step further: Most solutions that you find on the internet have one fault or another. Just because it's on the internet doesn't mean it's perfect. Figure out what is not quite correct and fix it. That way you get a better understanding, have better code, and definitely avoid any accusation of copyright infringement or plagiarism.

OwnerDisplayName: Anonymous


问:
What are the implications of implementing a research idea published by a university?
Suppose a researcher publishes a paper about something that could potentially be of high revenue potential.
A software developer reads it then decides to pursue a business with it.

What are the implications?
Is the researcher entitled to royalties?
Do we need to ask for permission of some sort?

I think that it is done regularly but I do want to understand the implications.

Example where this has been done before from wikipedia:
"Apache Hadoop's MapReduce and HDFS components were inspired by Google papers on their MapReduce and Google File System."

答:
I am currently undertaking my PhD in Artificial Intelligence + publishing and thought I would share my thoughts and experiences.

Academic writing is generally a pursuit to contribute to the body of knowledge. Academics in general, publish to contribute to this public domain of knowledge. Universities tend to have their own Intellectual property offices which protect the interests of the research, but would never allow for a researcher to publish detail that could jepordise the universities intellectual property. This can take the form of patents and trade secrets.

If the knowledge is in the public domain and not protected in anyway, then people are free to do what they want. Think about this though. Research is never done, and these contributions tend to be very narrow contributions that are hard to protect. Most PhDs I know are carrying on the work from others around the world they have never met, basing their entire project from the public domain of knowledge.

Also, I had someone implement the algorithms I described in a paper and I was very flattered, not offended or angry. I find academics have different incentives to business people. If you email the first author, they might even give you all of their code. Many researchers in my field are happy to show off their work and see it in practice as it looks great on the CV.


答:
The only way for a conversion from language X to some intermediate language IL and back to be lossless is for IL to be a superset of X. If you want to have multiple languages as X, then IL has to be a superset of all of them.

Therefore, I would suggest that IL has the following structure:

```<code>delimiter: ---------SOMERANDOMSTRING----------
---------SOMERANDOMSTRING----------
language: C
#include <stdio.h>
int main() { printf("hello world\n"); return 0; }
---------SOMERANDOMSTRING----------
language: Java
public class Main { public static void main(String[] args) {
  System.stdout.println("hello world");
}}
---------SOMERANDOMSTRING----------
</code>```

In other words, MIME-like embedding of the actual source code into the language. The "compiler" then has to parse apart the pieces and pass them to a proper processor for that language.

This obviously isn't useful.

Title: Does a Completely Full-Featured Intermediate Language Exist?

Body:
Often when translating between languages (whether with program translation or compiling) it's a one-way, destructive translation.  The functionality of the "port" isn't lost, but some of the intent and expression is.

For instance, porting a program from Java to C is possible, but you lose the notion of classes and methods.  If that program were to be ported back to Java you'd need to infer the intent of what would be considered an object to get back to the original state.  And that's something that a computer isn't good at doing.  As such you'd end up with a Java program that looked more like a C program with data structures and a big collection of static functions.

Also consider a compiler.  Once a language has been compiled down to assembler or even to say CIL or JVM, concepts such as if statements are lost as they are turned into branches.

On a higher level, source to source translators exist, but some languages have features (i.e. delegates in C#) which don't exist in other languages (like Java not having delegates).  The translation can happen, but is mildly destructive (i.e. Java would need a wrapper class to simulate delegates).

So, having said all that, is there a language who's goal is to be structurally compatible with all other languages by supporting all language features of all languages?

I'm not so concerned with being able to fully translate between languages as I am with being able to express each language's code in the common language.  So the goal would be translating to the common language and back again to the source language without losing anything.  Like: Java->Common->Java or LISP->Common->LISP

Body:
The only way for a conversion from language X to some intermediate language IL and back to be lossless is for IL to be a superset of X. If you want to have multiple languages as X, then IL has to be a superset of all of them.

Therefore, I would suggest that IL has the following structure:

delimiter: ---------SOMERANDOMSTRING----------
---------SOMERANDOMSTRING----------
language: C
#include <stdio.h>
int main() { printf("hello world\n"); return 0; }
---------SOMERANDOMSTRING----------
language: Java
public class Main { public static void main(String[] args) {
  System.stdout.println("hello world");
}}
---------SOMERANDOMSTRING----------

In other words, MIME-like embedding of the actual source code into the language. The "compiler" then has to parse apart the pieces and pass them to a proper processor for that language.

This obviously isn't useful.


问:
Declaring a class final?
I like my code to be written well; however, I have run into not really an problem, but more of a question about conventions. Say I have this class.

```<code>public class Test {

    public void doStuff() {
        System.out.println("stuff");
    }
}
</code>```

This class is not going to be extended, so should it be final? I know that when you don't want a class to be extended you make it final; however, in this case the class isn't going to be extended. Sorry if that is confusing. I am basically wondering if you should make every class that isn't going to be extended final.

答:
One of the rules for checkstyle that I have a love/hate relationship with is in the Class Design section - Design For Extension.  I've often found myself turning it off because it is annoying to follow to a 'T' - especially on large legacy projects where it isn't followed (having a bajillion warnings from check style makes it harder to fix any of them).

That said, its a rather simple rule:

The exact rule is that nonprivate, nonstatic methods of classes that can be subclassed must

be abstract or

be final or

have an empty implementation.

If you can subclass a class, you should make it so that it can be extended in a meaningful way.

"Wait," you say, "This is rule is about public non-static methods that either must be abstract, final, or have an empty implementation. What does this have to do with a final class?"

The exact rule is that non private, non static methods of classes that can be subclassed must ...

If you leave a class non-final, you are saying that it can be subclassed in a meaningful way. If it can't, then it shouldn't be able to be subclassed.

By making a class final, you are making it just a little bit harder for your co-worker to tinker with its innards by making a subclass that exposes all the methods that are implementation specific.  There are few things as wonderful as tracking down a bug because an immutable you wrote was subclassed to become mutable - trust me on this.

Designing for inheritance is costly. It takes extra thought to make sure that you are doing it right. That someone else won't mess it up. By saying final class you are avoiding all of that and saying "no - this cannot be inherited" and making it that much easier to reason about.

If you are not spending the time to design the class for extensibility, the appropriate thing to do is make sure no one makes the mistake working from the belief that the class is extensible.

Related reading:

How can designing for inheritance cause extra cost?

Why should a class be anything other than "abstract" or "final/sealed"?

Should I seal all classes I know shouldn't ever be used as a base class?

Why seal a class?

Title: Declaring a class final?


答:
Eric Lippert has an  excellent blog post on why one would mark classes final.  Specifically, he refers to the Microsoft practice of declaring .NET Framework classes sealed, but the principles are the same.

To summarize, writing an extensible class is a whole different ball game than writing a final class.

Sealing classes means you don't have to think about the myriad ways that a consumer might break the class by extending it.

Writing extensible classes requires a more rigorous design process.  You have to design them to be easily, clearly and logically extensible, a design consideration that you don't have to think about at all if you simply seal the class.

You lose encapsulation when you allow a class to be inherited.

Supporting an extensible class is much more involved.  Yes, you have to support the many ways a consumer might extend it.  If you upgrade the class later, you have to worry about breaking consumers' extensions.

See Also

Why aren't classes sealed by default?

Title: Declaring a class final?

Body:
I like my code to be written well; however, I have run into not really an problem, but more of a question about conventions. Say I have this class.

```<code>public class Test {

    public void doStuff() {
        System.out.println("stuff");
    }
}
</code>```

This class is not going to be extended, so should it be final? I know that when you don't want a class to be extended you make it final; however, in this case the class isn't going to be extended. Sorry if that is confusing. I am basically wondering if you should make every class that isn't going to be extended final.


问:
How should I annotate, that a class is immutable in Java?
I recently stumbled upon how useful immutable objects are and that e.g. if you pass elements to a constructor and your class should be immutable, you have to copy these elements if they are not immutable themselves.

This requires a lot of checking or knowledge about my project, because if I have

```<code>public A(B foo)
</code>```

and B is not immutable, A I'd have to copy B. Now imagine B seems immutable, but itself has mutable classes in the constructor and so on.

Is there a standard or best-practice for documenting if a class is immutable in Java? It seems there is no @immutable keyword in Javadoc.

The @Immutable annotation seems to be something totally different for auto class generation and not part of standard Java.

答:
You can use annotations:

@javax.annotation.concurrent.Immutable from JSR-305

or @net.jcip.annotations.Immutable from Java Concurrency In Practice


问:
Is there any advantage to c-style bit manipulation over std::bitset?
I work almost exclusively in C++11/14, and usually cringe when I see code like this:

```<code>std::int64_t mArray;
mArray |= someMask << 1;
</code>```

This is just an example; I'm talking about bit-wise manipulation in general. In C++, is there really any point? The above is mind-warping and error-prone, while using an std::bitset allows you to:

more easily modify the size of the std::bitset as needed by adjusting a template parameter and letting the implementation take care of the rest, and

spend less time figuring out what's going on (and possibly making mistakes) and write std::bitset in a manner similar to std::array or other data containers.

My question is; is there any reason not to use std::bitset over primitive types, other than for backward-compatability?

答:
This certainly doesn't apply in all cases, but occasionally an algorithm might depend on the efficiency of C-style bit-twiddling to provide significant performance gains. The first example which comes to my mind is the use of bitboards, clever integer encodings of board game positions, to speed up chess engines and the like. Here, the fixed size of integer types is no problem, since chessboards are always 8*8 anyway.

For a simple example, consider the following function (taken from this answer by Ben Jackson) which tests a Connect Four position for victory:

```<code>// return whether newboard includes a win
bool haswon2(uint64_t newboard)
{
    uint64_t y = newboard & (newboard >> 6);
    uint64_t z = newboard & (newboard >> 7);
    uint64_t w = newboard & (newboard >> 8);
    uint64_t x = newboard & (newboard >> 1);
    return (y & (y >> 2 * 6)) | // check \ diagonal
           (z & (z >> 2 * 7)) | // check horizontal -
           (w & (w >> 2 * 8)) | // check / diagonal
           (x & (x >> 2));      // check vertical |
}
</code>```

Body:
This certainly doesn't apply in all cases, but occasionally an algorithm might depend on the efficiency of C-style bit-twiddling to provide significant performance gains. The first example which comes to my mind is the use of bitboards, clever integer encodings of board game positions, to speed up chess engines and the like. Here, the fixed size of integer types is no problem, since chessboards are always 8*8 anyway.

For a simple example, consider the following function (taken from this answer by Ben Jackson) which tests a Connect Four position for victory:

// return whether newboard includes a win
bool haswon2(uint64_t newboard)
{
    uint64_t y = newboard & (newboard >> 6);
    uint64_t z = newboard & (newboard >> 7);
    uint64_t w = newboard & (newboard >> 8);
    uint64_t x = newboard & (newboard >> 1);
    return (y & (y >> 2 * 6)) | // check \ diagonal
           (z & (z >> 2 * 7)) | // check horizontal -
           (w & (w >> 2 * 8)) | // check / diagonal
           (x & (x >> 2));      // check vertical |
}


答:
From a logical (non-technical) point of view, there is no advantage.

Any plain C / C++ code can be wrapped within suitable "library construct". After such wrapping, the matter of "whether this is more advantageous than that" becomes a moot question.

From a speed point-of-view, C / C++ should allow the library construct to generate code that is as efficient as the plain code that it wraps. This is however subject to:

Function inlining

Compile-time checking and elimination of unnecessary runtime checking

Dead code elimination

Many other code optimizations...

Using this kind of non-technical argument, any "missing functions" could be added by anyone, and therefore are not counted as disadvantage.

However, built-in requirements and limitations cannot be overcome with additional code. Below, I argue that the size of std::bitset is a compile-time constant, and therefore while not counted as disadvantage, it is still something that affects user's choice.

From an aesthetic point-of-view (readability, ease of maintenance etc), there is a difference.

However, it is not apparent that the std::bitset code immediately wins over the plain C code. One has to look at bigger pieces of code (and not some toy-sample) to say whether the use of std::bitset has improved the human quality of the source code.

The speed of bit manipulation depends on the coding style. Coding style affects both C/C++ bit manipulation, and is equally applicable to std::bitset as well, as explained follows.

If one writes code that uses the operator [] to read and write one bit at a time, one will have to do this multiple times if there are more than one bits to be manipulated. The same can be said of the C-style code.

However, bitset also has other operators, such as operator &=, operator <<=, etc., which operates on the full width of the bitset. Because the underlying machinery can often operate on 32-bit, 64-bit and sometimes 128-bit (with SIMD) at a time (in the same number of CPU cycles), code that is designed to take advantage of such multi-bit operations can be faster than "loopy" bit-manipulation code.

The general idea is called SWAR (SIMD within a register), and is a subtopic under bit manipulations.

Some C++ vendors might implement bitset between 64-bits and 128-bits with SIMD. Some vendors might not (but might eventually do). If there is a need to know what the C++ vendor's library is doing, the only way is to look at the disassembly.

As to whether std::bitset has limitations, I can give two examples.

The size of std::bitset must be known at compile time. To make an array of bits with dynamically chosen size, one will have to use std::vector<bool>.

The current C++ specification for std::bitset does not provide a way to extract a consecutive slice of N bits from a larger bitset of M bits.

The first one is fundamental, meaning that for people who need dynamically-sized bitsets, they must choose other options.

The second one can be overcome, because one can write some kind of adapters to perform the task, even if the standard bitset is not extensible.

There are certain types of advanced SWAR operations that are not provided out-of-the-box from std::bitset. One could read about these operations on this website about bit permutations. As usual, one can implement these on their own, operating on top of std::bitset.

Regarding the discussion on performance.

One admonition: a lot of people ask about why (something) from the standard library is much much slower than some simple C-style code. I would not repeat the prerequisite knowledge of microbenchmarking here, but I just have this advice: make sure to benchmark in "release mode" (with optimizations enabled), and make sure the code isn't being eliminated (dead code elimination) or being hoisted out of a loop (loop-invariant code motion).

Since in general we cannot tell whether someone (on the internet) were doing the microbenchmarks correctly, the only way we can get a reliable conclusion is to do our own microbenchmarks, and document the details, and submit to public review and critique. It doesn't hurt to re-do microbenchmarks that others have done before.

Title: Is there any advantage to c-style bit manipulation over std::bitset?

Body:
I work almost exclusively in C++11/14, and usually cringe when I see code like this:

```<code>std::int64_t mArray;
mArray |= someMask << 1;
</code>```

This is just an example; I'm talking about bit-wise manipulation in general. In C++, is there really any point? The above is mind-warping and error-prone, while using an std::bitset allows you to:

more easily modify the size of the std::bitset as needed by adjusting a template parameter and letting the implementation take care of the rest, and

spend less time figuring out what's going on (and possibly making mistakes) and write std::bitset in a manner similar to std::array or other data containers.

My question is; is there any reason not to use std::bitset over primitive types, other than for backward-compatability?


问:
number of square matrices in a non-square matrix
i was wondering if there is any formula to calculate the number of square matrices present in a square matrix.

e.g

a 3x2 matrix has 3 square matrices that are (2x2, 1x1, 1x1)

a 6x3 matrix has 2 square matrices that are (3x3, 3x3)

a 4x3 matrix has 4 square matrices that are (3x3, 1x1, 1x1, 1x1)

any idea how to get this ? Thanks in advance

答:
Well, at a glance it seems like you want the "greedy" solution that finds the largest possible squares (rather than using all 1x1s), so it seems like simply finding the largest possible square in the current matrix and then recursively looking at the remaining part of the matrix should work:</p>

```<code>int squaresInRectangle(int m, int n) {
   if(m <= 0 || n <= 0) { return 0; }
   int largestPossibleSquareSize = min(m, n);
   int remainingSquareCount;
   if(m < n) {
       remainingSquareCount = squaresInRectangle(m, n - largestPossibleSquareSize);
   } else {
       remainingSquareCount = squaresInRectangle(m - largestPossibleSquareSize, n);
   }
   return 1 + remainingSquareCount;
}
</code>```

Body:
Well, at a glance it seems like you want the "greedy" solution that finds the largest possible squares (rather than using all 1x1s), so it seems like simply finding the largest possible square in the current matrix and then recursively looking at the remaining part of the matrix should work:

int squaresInRectangle(int m, int n) {
   if(m <= 0 || n <= 0) { return 0; }
   int largestPossibleSquareSize = min(m, n);
   int remainingSquareCount;
   if(m < n) {
       remainingSquareCount = squaresInRectangle(m, n - largestPossibleSquareSize);
   } else {
       remainingSquareCount = squaresInRectangle(m - largestPossibleSquareSize, n);
   }
   return 1 + remainingSquareCount;
}


答:
Many problems can be solved with a recursive greedy algorithm.

Given a MxN matrix, you can always find a KxK matrix in the upper left corner, where K = Min(M,N). If you then remove that part out from your matrix, you get a remainder. Repeat the process on that matrix until you run out of elements.

An example execution of the naive algorithm:

```<code>|0 0 0 1 1| => |0 0 0| % |1 1|
|0 0 0 1 1|    |0 0 0|   |1 1|
|0 0 0 2 3|    |0 0 0|   |2 3|
</code>```

There's still a matrix remainder.

```<code>|1 1| => |1 1| %  |2 3|
|1 1|    |1 1|
|2 3|
</code>```

There's still a matrix remainder.

```<code>|2 3| => |2| % |3|
</code>```

There's still a matrix remainder.

```<code>|3| => |3| % ||
</code>```

It appears we're done, having run out of matrices. One 3x3, one 2x2, two 1x1.

And remember, if you lift homework solutions from somewhere without understanding them and without being able to motivate what you've said in your report, the person you're cheating most is yourself.

Title: number of square matrices in a non-square matrix

Body:
i was wondering if there is any formula to calculate the number of square matrices present in a square matrix.

e.g

a 3x2 matrix has 3 square matrices that are (2x2, 1x1, 1x1)

a 6x3 matrix has 2 square matrices that are (3x3, 3x3)

a 4x3 matrix has 4 square matrices that are (3x3, 1x1, 1x1, 1x1)

any idea how to get this ? Thanks in advance

Body:
Many problems can be solved with a recursive greedy algorithm.

Given a MxN matrix, you can always find a KxK matrix in the upper left corner, where K = Min(M,N). If you then remove that part out from your matrix, you get a remainder. Repeat the process on that matrix until you run out of elements.

An example execution of the naive algorithm:

|0 0 0 1 1| => |0 0 0| % |1 1|
|0 0 0 1 1|    |0 0 0|   |1 1|
|0 0 0 2 3|    |0 0 0|   |2 3|

There's still a matrix remainder.

|1 1| => |1 1| %  |2 3|
|1 1|    |1 1|
|2 3|

There's still a matrix remainder.

|2 3| => |2| % |3|

There's still a matrix remainder.

|3| => |3| % ||

It appears we're done, having run out of matrices. One 3x3, one 2x2, two 1x1.

And remember, if you lift homework solutions from somewhere without understanding them and without being able to motivate what you've said in your report, the person you're cheating most is yourself.


答:
Very similar to the Euclidean algorithm</p>

```<code>int squaresInRectangle(int m, int n) {
    if (n <= 0) { return 0; }
    return squaresInRectangle(n, m % n) + (m / n);
}
</code>```

Body:
Very similar to the Euclidean algorithm

int squaresInRectangle(int m, int n) {
    if (n <= 0) { return 0; }
    return squaresInRectangle(n, m % n) + (m / n);
}


问:
Advantage/Disadvantage of having all variables declared in a JUnit Test
I've been writing some unit tests for some new code at work, and sent it off for a code review. One of my co-workers made a comment about why I was putting variables that are used in a number of those tests outside of the scope for the test.

The code I posted was essentially

```<code>import org.junit.Test;

public class FooUnitTests {

    @Test
    public void testConstructorWithValidName() {
        new Foo(VALID_NAME);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithNullName() {
        new Foo(null);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithZeroLengthName() {
        new Foo("");
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithLeadingAndTrailingWhitespaceInName() {
        final String name = " " + VALID_NAME + " ";
        final Foo foo = new Foo(name);

        assertThat(foo.getName(), is(equalTo(VALID_NAME)));
    }

    private static final String VALID_NAME = "name";
}
</code>```

His proposed changes were essentially

```<code>import org.junit.Test;

public class FooUnitTests {

    @Test
    public void testConstructorWithValidName() {
        final String name = "name";
        final Foo foo = new Foo(name);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithNullName() {
        final String name = null;
        final Foo foo = new Foo(name);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithZeroLengthName() {
        final String name = "";
        final Foo foo = new Foo(name);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testConstructorWithLeadingAndTrailingWhitespaceInName() {
        final String name = " name ";
        final Foo foo = new Foo(name);

        final String actual = foo.getName();
        final String expected = "name";

        assertThat(actual, is(equalTo(expected)));
    }
}
</code>```

Where everything that is required within the scope of the test, is defined within the scope of the test.

Some of the advantages he argued were

Each test is self contained.

Each test can be executed in isolation, or in aggregation, with the same result.

Reviewer doesn't have to scroll to wherever these parameters are declared to look up what the value is.

Some of the disadvantages of his method that I argued were

Increases code duplication

Can add noise to the reviewers mind if there are several similar tests with different values defined (ie. test with doFoo(bar) results in one value, while the same call has a different result because bar is defined differently in that method).

Aside from convention, are there any other advantages/disadvantages of using either method over the other?

答:
You should keep doing what you're doing.

Repeating yourself is just as bad an idea in test code as in business code, and for the same reason. Your colleague has been misled by the idea that every test should be self-contained. That's quite true, but "self-contained" doesn't mean that it should contain everything it needs within its method body. It only means that it should give the same result whether it's executed in isolaton or as part of a suite, and regardless of the order of the tests in the suite. In other words, the test code should have the same semantics regardless what other code has executed before it; it doesn't have to have all required code bundled textually.

Reusing constants, set-up code and the like increases the quality of the test code and doesn't compromise its self-contained-ness, so it's good thing that you should keep doing.