Juan-Carlos Gandhi (
juan_gandhi) wrote2007-09-12 07:42 am
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
conceptual problems with Java
First, as an illustration. Do you know what is the biggest problem with flowcharts? They are absolutely against any kind of functional or object-oriented development principles. Their impact on software development... it may have been more negative. If you think in the terms of flowcharts, your question is "what next" - which looks really ridiculous to any OOP- or FP-practicing developer.
Now Java.
Say, you have some kind of "base class" (e.g.
Fine. Does it help to communicate with other entities? We have several typical choices, "idioms":
What kind of mental model is this? Feodalism, I think. This is the world as represented in the minds of... yes, in the minds of Arrogant Engineers. I mean, Software Engineers.
Professional architects, I mean architects in building industry, see the world differently. First, nothing moves for them. Nobody owns nobody. Things consist of other things, and encapsulation happens on several levels. There is no communication between opposite walls or between the roof and the floor. If such a communication happens, it is called a leak, and should be eliminated.
What kind of a program would such an imaginary architect write?
It would be one enclosing class; everything that happens in the program, happens in the context of that class. Let's call it
I'm not saying it is an ideal model; it is just a slightly better model.
The problem with it in Java is that of course nobody wants to stuff all the code inside one huge file. And once you put it in another file, oops, you loose it: Java does not have mixins (yet), and so you cannot have an inner class, with a scope in an enclosing class, stored in a separate file. That's bummer.
P.S. (9/2011): Scala's cake pattern solve the problem more or less exactly this way. We have no traits in Java, so we are out of luck.
Now Java.
Say, you have some kind of "base class" (e.g.
Employee
), and some kind of "subclass" (e.g. ArrogantEngineer
). The subclass inherits some behavior from Employee, has some specific methods, and overrides some methods from its base class. Fine. Does it help to communicate with other entities? We have several typical choices, "idioms":
- singleton - base class contains a bunch of static references to external worlds; they are magically instantiated, using either
synchronized
keyword, or "double check locking" idiom, or a fashionable, since Java 5, holder class (see Bob Lee's blog for details) - factory - base class contains a static reference to a "factory" that produces references to other specific entities - this way we can decouple the other worlds from ours
- locator - like in CORBA or EJB, every time an
ArrogantEngineer
looks for a mouse, it has to start at "root context", ask for aMouseFactory
location, etc. Maybe you have to start withMouseMinistry
, and go down. Every time you need to move a mouse. Because the mouse you own may have expired. - double dispatch - okay, you find your mouse, and make it move, but how does the mouse know if it is on the verge of its carpet? You ask it every time? This ic called micromanagement. You are not supposed to do that. The mouse should tell you. "Don't call us, we'll call you". The mouse does not know you are an
ArrogantEngineer
- but you do, and act accordingly. - constructor - or setup, or configuration, whatever. Each
Employee
, on initialization, receives from an upper class representative all that they need for their future functioning. How does the "upper class" know that? That's their job; they are something likeEmployeeMinistry
, and know everything about everyone. Or they delegate toArrogantEngineerMinistry
which knows their subjects better.
What kind of mental model is this? Feodalism, I think. This is the world as represented in the minds of... yes, in the minds of Arrogant Engineers. I mean, Software Engineers.
Professional architects, I mean architects in building industry, see the world differently. First, nothing moves for them. Nobody owns nobody. Things consist of other things, and encapsulation happens on several levels. There is no communication between opposite walls or between the roof and the floor. If such a communication happens, it is called a leak, and should be eliminated.
What kind of a program would such an imaginary architect write?
It would be one enclosing class; everything that happens in the program, happens in the context of that class. Let's call it
Enterprise
. If there are some facilities that are directly available to everybody, so they are. We can introduce internal classes, like Department
- these classes contain a lot of data which they may or may not publish. But they do not have to name the outer scope, the scope of Enterprise
. And so on; employees access the data visible to them in Department
scope.I'm not saying it is an ideal model; it is just a slightly better model.
The problem with it in Java is that of course nobody wants to stuff all the code inside one huge file. And once you put it in another file, oops, you loose it: Java does not have mixins (yet), and so you cannot have an inner class, with a scope in an enclosing class, stored in a separate file. That's bummer.
P.S. (9/2011): Scala's cake pattern solve the problem more or less exactly this way. We have no traits in Java, so we are out of luck.
no subject
Note 1: If something is one huge building, do you need to lock it completely when you need to alter it slightly, e.g. to fix a leaking faucet?
Note 2 (a meta-note): There are no good and bad things; there are things used appropriately and not.
no subject
See, there are no mixins in Java. So you cannot have an inner class outside your file.
I guess this explains my position on your Note 1.
no subject
It was all good for enclosed systems with litle interaction between parts. Then distributed transactions, logging and reflection came along, people moved on to keep things in thread-local vars, intercept function calls, discover bean properties... all of a sudden, simple Java-interface like contracts turned into lawyerish descriptions with multiple clauses and couple of dimensions.
The point is - I love mixins; I don't know how to make people use them with my code so that they don't blow it. I will be thankful if you came across and would point me to such docs, like for Ruby or JavaScript.
no subject
no subject
no subject
Такого плана, при этом sum доступается к локальному контексту вызвавшей функции, а result - к вызываемой.
no subject
no subject
no subject
А mixins - это примеси (http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%81%D1%8C_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29).
no subject
в тройке есть. see 26.2 Extension methods (http://download.microsoft.com/download/5/8/6/5868081c-68aa-40de-9a45-a3803d8134b8/csharp_3.0_specification.doc)
no subject
Классические же примеси (и особенно Traits (http://en.wikipedia.org/wiki/Trait_(abstract_type))) это позволяют.
no subject
no subject
Хотел просто указать, что extension methods хотя и похожи на mixins, всё-таки полного набора их возможностей не предоставляют.
no subject
no subject
Анонимные делегаты - это closures (http://en.wikipedia.org/wiki/Closure), т.е. как замыкание функции с ее окружением. Замыкания в большинстве систем сводимы к классам (и наоборот).
Код типа
int sumUp()
{
int sum = 0;
mySqlClient.query("SELECT amount FROM things", delegate(QueryResult result){ sum += result.data[0] });
return sum;
}
будет скомпилирован в что-то вроде
class QueryResultHandler { // название другое, конечно
public int sum;
public void Handler(QueryResult result){ sum += result.data[0]; }
}
int sumUp(){
QueryResultHandler handler = new QueryResultHandler();
mySqlClient.Query("SELECT amount FROM things",handler.Handler);
return handler.sum;
}
Генераторам в C# соответствуют итераторы, т.е. реализации интерфейса IEnumerator (или IEnumerable). Они инкапсулируют конечный автомат, который возвращает значение в зависимости от своего состояния.
Т.е. если мы описываем метод вида
у нас будет сгенерирован inner class, реализующий IEnumerator с полями i, state и current (названия, ес-сно, другие), а в IEnumerator.MoveNext() будет осуществляться инкремент i, его запись в current для пользователя и переключение состояния. Короче, достаточно мудрёные действия, которые при ручном кодировании могли бы быть оптимальней =)
При наличии в языке first class continuations проще реализовать генераторы, чем при наличии генераторов реализовать continuations (хотя это to some extent возможно, и об этом была статья на RSDN).
Еще при помощи итераторов можно реализовать ленивые вычисления, но это уже другая песня...
no subject
Что я на считаю нужным - всего лишь возможность разбивать класс на много файлов. Скажем:
no subject
no subject
Звиняйте, с отпуска мы, расслабились. :)
no subject
no subject
no subject
no subject
no subject