powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Пятничный Best practices.
76 сообщений из 76, показаны все 4 страниц
Пятничный Best practices.
    #38554098
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, коллеги!

Вот такой вот пятничный говнокодец.

Очень часто нужно сортировать сущности в коллекциях по разным колонкам.
В настоящий момент это уродство выглядит вот так.

Entity.java

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;

public class FuckenEntity {

    private BigInteger account;
    private String clientName;
    private Date clientActivityDate;
    private String clientSubType;
    private BigDecimal clientBalance;

    public BigInteger getAccount() {
        return account;
    }

    public void setAccount(BigInteger account) {
        this.account = account;
    }

    public String getClientName() {
        return clientName;
    }

    public void setClientName(String clientName) {
        this.clientName = clientName;
    }

    public Date getClientActivityDate() {
        return clientActivityDate;
    }

    public void setClientActivityDate(Date clientActivityDate) {
        this.clientActivityDate = clientActivityDate;
    }

    public String getClientSubType() {
        return clientSubType;
    }

    public void setClientSubType(String clientSubType) {
        this.clientSubType = clientSubType;
    }

    public BigDecimal getClientBalance() {
        return clientBalance;
    }

    public void setClientBalance(BigDecimal clientBalance) {
        this.clientBalance = clientBalance;
    }
}



SortProcessor
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
import org.apache.log4j.Logger;
import org.springframework.beans.factory.BeanNameAware;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import static java.lang.String.format;
import static java.lang.String.format;

public class FuckenEntityProcessor implements BeanNameAware {

    private static Logger logger = Logger.getLogger(FuckenEntityProcessor.class);

    /**
     *
     * @param FuckenEntitys - fucken collection to sort (out)
     * @param nField - number of field (Just like SELECT .... FROM ... ORDER by nField )
     * @param direction - direction of sorting like { ASC | DESC }
     */
    public static void sort(List<FuckenEntity> FuckenEntitys, int nField, int direction) {
        if (direction == 0 || direction == 1) {
            if (FuckenEntitys != null && FuckenEntitys.size() > 0) {
                try {
                    if (nField == 0) {
                        Collections.sort(FuckenEntitys, new Comparator<FuckenEntity>() {
                            @Override
                            public int compare(FuckenEntity o1, FuckenEntity o2) {
                                if (o1.getAccount()==null && o2.getAccount()==null) return 0;
                                if (o1.getAccount()==null) return 1;
                                if (o2.getAccount()==null) return -1;
                                return o1.getAccount().compareTo(o2.getAccount());
                            }
                        });
                    } else if (nField == 1) {
                        Collections.sort(FuckenEntitys, new Comparator<FuckenEntity>() {
                            @Override
                            public int compare(FuckenEntity o1, FuckenEntity o2) {
                                if (o1.getClientName()==null && o2.getClientName()==null) return 0;
                                if (o1.getClientName()==null) return 1;
                                if (o2.getClientName()==null) return -1;
                                return o1.getClientName().compareTo(o2.getClientName());
                            }
                        });
                    } else if (nField == 2) {
                        Collections.sort(FuckenEntitys, new Comparator<FuckenEntity>() {
                            @Override
                            public int compare(FuckenEntity o1, FuckenEntity o2) {
                                if (o1.getClientActivityDate()==null && o2.getClientActivityDate()==null) return 0;
                                if (o1.getClientActivityDate()==null) return 1;
                                if (o2.getClientActivityDate()==null) return -1;
                                return o1.getClientActivityDate().compareTo(o2.getClientActivityDate());
                            }
                        });
                    } else if (nField == 3) {
                        Collections.sort(FuckenEntitys, new Comparator<FuckenEntity>() {
                            @Override
                            public int compare(FuckenEntity o1, FuckenEntity o2) {
                                if (o1.getClientSubType()==null && o2.getClientSubType()==null) return 0;
                                if (o1.getClientSubType()==null) return 1;
                                if (o2.getClientSubType()==null) return -1;
                                return o1.getClientSubType().compareTo(o2.getClientSubType());
                            }
                        });
                    } else if (nField == 4) {
                        Collections.sort(FuckenEntitys, new Comparator<FuckenEntity>() {
                            @Override
                            public int compare(FuckenEntity o1, FuckenEntity o2) {
                                if (o1.getClientBalance()==null && o2.getClientBalance()==null) return 0;
                                if (o1.getClientBalance()==null) return 1;
                                if (o2.getClientBalance()==null) return -1;
                                return o1.getClientBalance().compareTo(o2.getClientBalance());
                            }
                        });
                    }
                    if (direction==1) Collections.reverse(FuckenEntitys);
                } catch (Exception ex) {
                    logger.error(
                            format("Exception while sorting FuckenEntitys param = %d,dir = %d",
                                    nField, direction), ex
                    );
                }
            }
        }
    }

    ................
}



Обычно List<entity> связана 1:1 с GWT FlexTable и отображается на UI пользователя
как есть.

Сортировать на стороне источника данных не всегда возможно. Где БД - мы
как-то сортируем а вот из rest-сервисов приходится делать всё самим.

Встроенные DBMS (Derby, HyperSonic, H2) мы не используем.

Сами entities лежат в скоупе GWT компилляции и имеют поля только основных
примитивных типов (int, String, Date, BigDecimal). Сложные объекты
я пока не встречал.

Вопрос:

Как сортировать универсально?

Нужен какой-то компонент (SpringBean) которому на вход приходит
неизвестная коллекция List<Object> и номер колонки и direction (ASC|DESC)
по которой надо сортировать и на выходе мы имеет отсортированное.

Буду рад выслушать идеи, Best Practices и почитать исходники.

Спасибо!

P.S. Реверс тоже радует :)

P.P.S Фух. Написал таки. Пятница ... мать ее так.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554102
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А reflection не спасет отца русской демократии?
Если нужна производительность, то что-то типа CGLIB

AFAIK & IMHO. Я бы в этом направлении делал, но осторожно, думая о производительности.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554109
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Codegeneration меня точно спасёт. Не утонуть-бы...
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554125
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://tips4java.wordpress.com/2008/10/23/bean-comparator/
говнокод, говнокодом, но тут ещё какой-то тупак с индексом поля. Кто придумал свойства через int адресовать?
В остальном, всё достаточно примитивно. Надо тупо избавиться от копипаста и станет более менне адекватно. Попробую изобразить.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554141
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Processor {

    public static void sort(List<Entity> entities, final int nField, int direction) {
        Collections.sort(entities, new EntityComparator() {
            @Override
            Comparable get(Entity e) {
                switch (nField){
                    case 0: return e.getAccount();
                    case 1: return e.getClientName();
                    case 2: return e.getClientActivityDate();
                    case 3: return e.getClientSubType();
                    case 4: return e.getClientBalance();
                }
                throw new IllegalArgumentException("No field for index " + nField);
            }
        });
    }

    abstract static class EntityComparator implements Comparator<Entity> {
        @Override
        public int compare(Entity e1, Entity e2) {
            Comparable c1 = get(e1);
            Comparable c2 = get(e2);
            if (c1 == null && c2 == null) return 0;
            if (c1 == null) return 1;
            if (c2 == null) return -1;
            return c1.compareTo(c2);
        }

        abstract Comparable get(Entity e);
    }
}
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554144
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

блин, прогнал немного.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Processor {

    public static void sort(List<Entity> entities, final int nField, int direction) {
        Collections.sort(entities, new EntityComparator<Entity>() {
            @Override
            Comparable get(Entity e) {
                switch (nField){
                    case 0: return e.getAccount();
                    case 1: return e.getClientName();
                    case 2: return e.getClientActivityDate();
                    case 3: return e.getClientSubType();
                    case 4: return e.getClientBalance();
                }
                throw new IllegalArgumentException("No field for index " + nField);
            }
        });
    }

    abstract static class EntityComparator<T> implements Comparator<T> {
        @Override
        public int compare(T e1, T e2) {
            Comparable c1 = get(e1);
            Comparable c2 = get(e2);
            if (c1 == null && c2 == null) return 0;
            if (c1 == null) return 1;
            if (c2 == null) return -1;
            return c1.compareTo(c2);
        }

        abstract Comparable get(T e);
    }
}
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554157
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
switch..case можно смело в саму entity унести
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554179
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О. Спасибо попробую. С entities такой трабл что компилируются они плагином gwt-maven-plugin
а с этим есть различные language limitations. Не всё что есть в Java компилируется в GWT.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554652
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz
Код: java
1.
    abstract static class EntityComparator<T> implements Comparator<T> 


Рекомендую посмотреть Commons BeanUtils, там уже всё сделали (а именно BeanComparator)
http://commons.apache.org/proper/commons-beanutils/
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554682
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton ,
Если интересно сделать именно самому, то я бы смотрел банально в сторону рефлекшена и Unsafe:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
public class Sorter {
    private static Unsafe UNSAFE = unsafe();

    public static <T> List<T> sort(List<T> src, Class cls, String fieldName, final SortOrder sortOrder)
        throws Exception {
        Field field = cls.getDeclaredField(fieldName);

        final FieldType type = fieldType(field);

        final long offset = UNSAFE.objectFieldOffset(field);

        Collections.sort(src, new Comparator<T>() {
         @Override public int compare(T o1, T o2) {
             switch (type) {
                 case INT:
                     return compareInt(o1, o2, offset, sortOrder);

                 // Все остальные примитивы.

                 default:
                     assert type == FieldType.OBJECT;

                     return compareObject(o1, o2, offset, sortOrder);
             }
         }
        });

        return src;
    }

    private static int compareInt(Object o1, Object o2, long offset, SortOrder sortOrder) {
        int val1 = UNSAFE.getInt(o1, offset);
        int val2 = UNSAFE.getInt(o1, offset);

        int res = val1 < val2 ? -1 : val1 == val2 ? 0 : 1;

        if (sortOrder == SortOrder.DESC)
            res = res * -1;

        return res;
    }

    // Все остальные примитивы.

    private static int compareObject(Object o1, Object o2, long offset, SortOrder sortOrder) {
        Object val1 = UNSAFE.getObject(o1, offset);
        Object val2 = UNSAFE.getObject(o1, offset);

        return applySortOrder(((Comparable)val1).compareTo(val2), sortOrder);
    }

    private static int applySortOrder(int res, SortOrder sortOrder) {
        return sortOrder == SortOrder.ASC ? res : res * -1;
    }


    private static FieldType fieldType(Field field) {
        // Тут определите тип поля.
        // TODO.
    }

    private static Unsafe unsafe() {
        try {
            Field f = Unsafe.class.getDeclaredField("theUnsafe");

            f.setAccessible(true);

            return (Unsafe)f.get(null);
        }
        catch (Exception e) {
            throw new RuntimeException("Failed to get Unsafe instance.");
        }
    }

    private static enum FieldType {
        INT,

        // Все стальные примитивы.

        OBJECT
    }
}

Разумеется, это только концепт, для демонстрации идеи. Для пущей няшности можно заморочиться, например, с аннотациями и кэшем дескрипторов конкретного класса. Например, фигачите на полях, по которым можно сортировать аннотацию Sortable. Потом, каким-нибудь образом регистрируете этот класс в сортировщике. Он проверяет консистентность. Например, что все reference поля реализуют Comparable. А потом кэширует дескриптор этого класса у себя. И когда вы будете вызывать непосредственно сортировку, то он просто вытащит дескриптор из кэша, быстро поймет, как именно надо обработать это поле, и все буде круто.

Ну и прочих фишек и оптимизаций уже сами нафигачите. Например, проверять SortType можно один раз на весь процесс сортировки, а не на каждом сравнении, как у меня. Можно передавать опциональный Comparator. И т.д..

Но вообще, как сказали выше, такое наверняка уже давным давно есть в каких-нибудь утилитарных библиотеках.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554685
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Плюс можно, например, не создавать новый компаратор на каждый раз, а статически их создать и закэшировать. Например, по каждому типу и "направлению сортировки". Таким образом, у вас их будет штук эдак 18 (9 типов * 2 направления), зато GC Будет за вами меньше мусора собирать. Ну это уже совсем изврат, если прям все соки надо выжать
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554704
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шняга какая-то, зачем рефлекшн.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
    class Column<ENTITY, VALUE> {
        private final Getter<ENTITY, VALUE> getter;
        private final Comparator<VALUE>     comparator;

        public Getter<ENTITY, VALUE> getGetter() {
            return getter;
        }

        public Comparator<VALUE> getComparator() {
            return comparator;
        }

        Column(Getter<ENTITY, VALUE> getter, Comparator<VALUE> comparator) {
            this.getter = getter;
            this.comparator = comparator;
        }

        int compare(ENTITY e1, ENTITY e2) {
            return comparator.compare(getter.get(e1), getter.get(e2));
        }
                
    }

    static final Comparator<BigInteger> BIG_INT = new Comparator<BigInteger>() {
        @Override
        public int compare(BigInteger o1, BigInteger o2) {
            return o1.compareTo(o2);
        }
    };
    
    static final Comparator<String> STRING = new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }
    };

    interface Getter<ENTITY, T> {
        T get(ENTITY e);
    }

    class FuckenEntity {

        private BigInteger account;
        private String     clientName;

        public static final Getter<FuckenEntity, BigInteger> ACCOUNT = new Getter<FuckenEntity, BigInteger>() {
            @Override
            public BigInteger get(FuckenEntity e) {
                return e.account;
            }
        };

        public static final Getter<FuckenEntity, String> CLIENT_NAME = new Getter<FuckenEntity, String>() {
            @Override
            public String get(FuckenEntity e) {
                return e.clientName;
            }
        };
    }

    <E> void sort(final List<E> fuckenEntitys, final List<? extends Column> fuckenColumns) {

        Comparator<E> fuckenComparator = new Comparator<E>() {
            @Override
            public int compare(E o1, E o2) {
                for (Column column : fuckenColumns) {
                    int compare = column.compare(o1, o2);
                    if (compare != 0)
                        return compare;
                }
                return 0;
            }

            @Override
            public boolean equals(java.lang.Object obj) {
                return false;
            }
        };

        Collections.sort(fuckenEntitys, fuckenComparator);
    }

    
    void primer(List<FuckenEntity> list){
        Column<FuckenEntity, BigInteger> column1 = new Column<FuckenEntity, BigInteger>(FuckenEntity.ACCOUNT, BIG_INT);
        Column<FuckenEntity, String> column2 = new Column<FuckenEntity, String>(FuckenEntity.CLIENT_NAME, STRING);

        sort(list, Arrays.asList(column1, column2));
    }
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554745
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvПлюс можно, например, не создавать новый компаратор на каждый раз, а статически их создать и закэшировать. Например, по каждому типу и "направлению сортировки". Таким образом, у вас их будет штук эдак 18 (9 типов * 2 направления), зато GC Будет за вами меньше мусора собирать. Ну это уже совсем изврат, если прям все соки надо выжать
Это тема. +1
Я думаю что нам нужен пул компараторов. У нас в коде штук 200 интерфейсов и на каждый есть
1 FlexTable c 5-10 колонками сортировок. Тоесть грубо говоря нам надо 200 * 5 = 1000 компараторов.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554843
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ivanraРекомендую посмотреть Commons BeanUtils, там уже всё сделали (а именно BeanComparator)
http://commons.apache.org/proper/commons-beanutils/
Мне не нужно ничего рекомендовать, я вопросов не задавал. BeanComparator работает на рефлексии. Мой код - нет. Я просто отрефакторил то что привел mayton
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554844
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЭто тема. +1
Я думаю что нам нужен пул компараторов. У нас в коде штук 200 интерфейсов и на каждый есть
1 FlexTable c 5-10 колонками сортировок. Тоесть грубо говоря нам надо 200 * 5 = 1000 компараторов.
Сортировка клиентская или серверная? В любом случае зачем пул, если на сервере компаратор быстро издохнет в молодом поколении, а на клиенте никто не будет так часто и постоянно сортировать все возможные интерфейсы.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554845
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лагман,
А зачем столько новых бестолковых Comparator для типов, которы уже реализуют Comparable?
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554861
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лагман, y нас есть необходимость сортировать также null значения.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554882
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,
А так ли нужен вам List<FuckenEntity> ?
Не подойдет ли List<List<Comparable>>, т.е. матрица свойств обектов, вместо списка обектов.

Ну и можно класс отдельный создать Matrix<T extends Comparable>,
который будет еще и описания колонок внутри себя хранить.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554884
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDMatrix<T extends Comparable>
Не так, правильнее Matrix<? extends Comparable>
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554892
ivanra
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczBeanComparator работает на рефлексии. Мой код - нет. Я просто отрефакторил то что привел mayton
Все так, но доступ к геттерам в BeanComparator кешируется, так что расходы на рефлексию (в большой коллекции, либо при многократной сорировке) сводятся к вызову этих геттеров, что сравнимо по производительности с работой через интерфейсы. Поэтому BeanComparator не такой уж и медленный, как кажется на первый взгляд.
Конечно, хардкод будет самый быстрый, но можно ли это считать Best practices?
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554932
Monochromatique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В каком кошмаре живут явисты.

https://code.google.com/p/lambdaj/
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554955
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MonochromatiqueВ каком кошмаре живут явисты.

https://code.google.com/p/lambdaj/

Иди из нашего кошмара в свой- установки MS серверов и совместимости версия дотнета :)
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554960
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MonochromatiqueВ каком кошмаре живут явисты.

https://code.google.com/p/lambdaj/ Надежда на Java 8 .
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38554962
Monochromatique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey TominMonochromatiqueВ каком кошмаре живут явисты.

https://code.google.com/p/lambdaj/

Иди из нашего кошмара в свой- установки MS серверов и совместимости версия дотнета :)

Да как бы нет проблем. ))


Но как-то хотелось думать (не приведи Бог столкнуться), что в JAVA есть эквивалент - persons.OrderBy(p=>p.name)

На что я кстати и привел ссылку. Просто ты наверное не понял.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555003
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MonochromatiqueAlexey Tominпропущено...
Иди из нашего кошмара в свой- установки MS серверов и совместимости версия дотнета :)

Да как бы нет проблем. ))

Но как-то хотелось думать (не приведи Бог столкнуться), что в JAVA есть эквивалент - persons.OrderBy(p=>p.name)


Будет в JDK8

MonochromatiqueНа что я кстати и привел ссылку. Просто ты наверное не понял.

Я не понял, что ты этим хотел сказать, да :)
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555031
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczЛагман,
А зачем столько новых бестолковых Comparator для типов, которы уже реализуют Comparable?
У вас проблемы с восприятием примеров, и с ООП.
maytonЛагман, y нас есть необходимость сортировать также null значения.
У вас проблемы с восприятием примеров.
Алсо своим воторым вопросом вы отвечаете на свой первый.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555034
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а, думал это один человек, сорри. В общем итого mayton отвечает на вопрос Blazkowicza
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555039
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛагманУ вас проблемы с восприятием примеров, и с ООП.

У вас проблемы с кодированим и культурой общения. Меня каждый раз умиляет как джуниоры из года в год ваяют подобные страницы кода, которые не делают ничего полезного и заменяются парой методов и классом.

ЛагманmaytonЛагман, y нас есть необходимость сортировать также null значения.
У вас проблемы с восприятием примеров.
Алсо своим воторым вопросом вы отвечаете на свой первый.
Мой рефакторинг первоначального кода точно так же справляется с null значениями, как и оригинальный код. Без копараторов.

А вот подобный код в проекте
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 static final Comparator<BigInteger> BIG_INT = new Comparator<BigInteger>() {
        @Override
        public int compare(BigInteger o1, BigInteger o2) {
            return o1.compareTo(o2);
        }
    };
    
    static final Comparator<String> STRING = new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }
    };


это бесполезный шум. Не нужен компаратор, так где есть Comparable. Не нужно два разных компаратора для двух Comparable типов. Такой код не несет никакой пользы. Просто усложяет код, не более.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555050
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczswitch..case... +1000


mayton,

Вот еще одно оригинальное решение: http://stackoverflow.com/a/1421537
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555107
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDmayton,
А так ли нужен вам List<FuckenEntity> ?
Не подойдет ли List<List<Comparable>>, т.е. матрица свойств обектов, вместо списка обектов.

Ну и можно класс отдельный создать Matrix<T extends Comparable>,
который будет еще и описания колонок внутри себя хранить.
Мой вопрос слишком сложен для местной массы?
Настолько сложен, что даже непонятно о чем это?
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555116
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDМой вопрос слишком сложен для местной массы?

Конечно. Мы тут тупая масса идиотов. Куда нам до Вас.

HoBTIDНастолько сложен, что даже непонятно о чем это?
Тихо сам с собою я ведь беседу.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555174
Monochromatique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDHoBTIDmayton,
А так ли нужен вам List<FuckenEntity> ?
Не подойдет ли List<List<Comparable>>, т.е. матрица свойств обектов, вместо списка обектов.

Ну и можно класс отдельный создать Matrix<T extends Comparable>,
который будет еще и описания колонок внутри себя хранить.
Мой вопрос слишком сложен для местной массы?
Настолько сложен, что даже непонятно о чем это?

http://lurkmore.to/Неуловимый_Джо
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555191
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDHoBTIDmayton,
А так ли нужен вам List<FuckenEntity> ?
Не подойдет ли List<List<Comparable>>, т.е. матрица свойств обектов, вместо списка обектов.

Ну и можно класс отдельный создать Matrix<T extends Comparable>,
который будет еще и описания колонок внутри себя хранить.
Мой вопрос слишком сложен для местной массы?
Настолько сложен, что даже непонятно о чем это?
Он не сложен. Он - не нужен. У нас сопряжение GWT виджетов
с слоем процессоров идёт через списки Entities. Это в некотором
роде мета-описание самих сущностей. И оно несёт материальный
смысл. Как метаинформация о колонках в БД. Мы можем абстрагироваться
от колонок но мета-описание придётся сделать на другом Layer.
А это дополнительные расходы. Зачем описывать сущности еще
раз в другом месте.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555336
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonУ нас сопряжение GWT виджетов
с слоем процессоров идёт через списки Entities.Т.е. сопряжение нельзя сделать с матрицей вместо списка?

maytonЭто в некотором
роде мета-описание самих сущностей. И оно несёт материальный
смысл. Как метаинформация о колонках в БД.Это имеет какой-то смысл, только если у ваших сущностей есть поведение,
которое необходимо реализовать именно в этом сортируемом списке, а не где-то еще.
Если там просто геттеры и сеттеры, все можно сделать через матрицу.
Если, например пользователь выбирает из списка объект и с ним делает что-то сложное,
то сам объект можно создавать только когда пользователь начал с ним что-то делать.

mayton... Мы можем абстрагироваться
от колонок но мета-описание придётся сделать на другом Layer.
А это дополнительные расходы. ... Зачем описывать сущности еще
раз в другом месте.Вполне логично задать симметричный вопрос, зачем описывать сущности в этом месте?
Ведь по сути, сущности здесь не нужны, нужна просто таблица с их свойствами.
А эта таблица - другая, совершенно отдельная сущность.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555399
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эта Entity(DTO) описывается на уровне бизнеса. Поле такое-то... тип такой-то..
DSL в некотором роде.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555427
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЭта Entity(DTO) описывается на уровне бизнеса. Поле такое-то... тип такой-то..
DSL в некотором роде.
Как связан "уровень бизнеса" и таблица со строками и числами на экране пользователя?
Вы Excel пользовались когда-нибудь? Вот Экселю совершенно наплевать на любые уровни бизнеса,
данные - это просто таблица.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555432
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если же вам потом понадобится нечто "очень бизнесовое", добавьте в эту табличку колонку с id,
по которому потом можно создать сущность.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555435
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDЕсли же вам потом понадобится нечто "очень бизнесовое", добавьте в эту табличку колонку с id,
по которому потом можно создать сущность.
В чем преимущества? Вы предлагаете решение без очевидных достоинств и требуете доказательств что оно не самое оптимальное?
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555461
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczВ чем преимущества? Вы предлагаете решение без очевидных достоинств и требуете доказательств что оно не самое оптимальное?
Преимущества в простой сортировке и фильтрации такой таблицы, без рефлексии.
Функции работы с ней универсальны, все что им нужно, это чтобы значения в одной колонке были сравнимы между собой.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555470
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDПреимущества в простой сортировке и фильтрации такой таблицы, без рефлексии.

Моя версия решения проблемы не использует рефлексию.
Задача сортировка списка списков по элементу внутреннего списка слабо отличается от задачи сортировки списка бинов по свойству.

HoBTIDФункции работы с ней универсальны, все что им нужно, это чтобы значения в одной колонке были сравнимы между собой.
Забудьте слово "универсальный".
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555493
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczМоя версия решения проблемы не использует рефлексию.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
            Comparable get(Entity e) {
                switch (nField){
                    case 0: return e.getAccount();
                    case 1: return e.getClientName();
                    case 2: return e.getClientActivityDate();
                    case 3: return e.getClientSubType();
                    case 4: return e.getClientBalance();
                }
                throw new IllegalArgumentException("No field for index " + nField);


Вот эта версия???
Осознаете ли Вы значение слова "говнокод"???

BlazkowiczЗадача сортировка списка списков по элементу внутреннего списка слабо отличается от задачи сортировки списка бинов по свойству.Даже если предположить, что слабо отличается
(не хочу сейчас углубляться в случаи, когда она отличается очень сильно), как ее реализовать?
В случае бинов - только рефлексией или же забитыми гвоздями switch или if.

BlazkowiczЗабудьте слово "универсальный".
Мне жаль, что вы его забыли, уж я-то не забуду никогда.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555501
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDОсознаете ли Вы значение слова "говнокод"???

Многоуважаемое хамло. На данный момент это наиболее простой и компактный код приведенный в этой теме и соответствующий семантике оригинального метода. Вашего кода мы пока в теме не увидели.

HoBTIDДаже если предположить, что слабо отличается
(не хочу сейчас углубляться в случаи, когда она отличается очень сильно), как ее реализовать?
Правильно, углублятся не нужно. Пукнул в лужу и пошел. Код привести не можем. Обосновать его преимущество не можем. Хамить - всегда пожалуйста.

HoBTIDВ случае бинов - только рефлексией или же забитыми гвоздями switch или if.
Ну, у вас, вероятно, если более разумные и "универсальные" идеи как привязать свойства к индексам полей. Только вы нам их не расскажите, как я понял.

HoBTIDМне жаль, что вы его забыли, уж я-то не забуду никогда.
Слово "универсальный" это то как джуниоры описывают свой код. Они понятия не имееют о таких критериях, как связанность, сцепление, читаемость, ошибкоустойчивость к будущим изменениям и т.п. У них на всё один критерей "универсальный". Я из этого возраста давно вышел, поэтому данным словом код никогда не измеряю.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555544
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczКод привести не можем. Обосновать его преимущество не можем.
Кода будет довольно много, я его писал в одном из проектов.
Зато он не зависит от сущности, это я называю словом "универсальный".

Если у вас недопонимание этого слова в связи с психическими травмами получеными в джуниорском периоде,
это не значит, что и у других похожие травмы.

BlazkowiczНу, у вас, вероятно, если более разумные и "универсальные" идеи как привязать свойства к индексам полей. Только вы нам их не расскажите, как я понял.
Ну что ж, пожалуй напишу азы, вдруг кто-нибудь поймет?

Код: java
1.
2.
3.
4.
public class VisualTableModel {
    private final List<List<Comparable>> data = new ArrayList<>();
    private final List<ColumnDef> columns = new ArrayList<>();
}



Осталось написать класс ColumnDef - описание колонки, и различные методы класса VisualTableModel,
вот тут кода будет много, но за соответствующее вознаграждение, я готов его предоставить.

Blazkowicz ... о таких критериях, как связанность, сцепление, читаемость, ошибкоустойчивость к будущим изменениям и т.п. У них на всё один критерей "универсальный". Я из этого возраста давно вышел, поэтому данным словом код никогда не измеряю.
И Ваш код удовлетворяет критерию слабой связности, например?
Или, может быть, он ошибкоустойчивый к будущим изменениям?
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555572
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDКода будет довольно много, я его писал в одном из проектов.

Ну, вот и я о том же.

HoBTIDЗато он не зависит от сущности, это я называю словом "универсальный".

Ну, так бины тогда можно вообще выкинуть и писать всё на массивах и хэшмапах. На форумах каждые два года появляется нуб с такой "оригинальной" и "универсальной" идеей.

HoBTIDЕсли у вас недопонимание этого слова в связи с психическими травмами получеными в джуниорском периоде,
это не значит, что и у других похожие травмы.

Да, всё понятно уже. Можешь дальше не закатывать истерику.

HoBTIDНу что ж, пожалуй напишу азы, вдруг кто-нибудь поймет?
Код: java
1.
2.
3.
4.
public class VisualTableModel {
    private final List<List<Comparable>> data = new ArrayList<>();
    private final List<ColumnDef> columns = new ArrayList<>();
}



Круто ваще. Как я сразу об этом не подумал. Спасибо, сансэй.

HoBTIDОсталось написать класс ColumnDef - описание колонки, и различные методы класса VisualTableModel,
вот тут кода будет много,

Какая мелочь.

HoBTIDно за соответствующее вознаграждение, я готов его предоставить.
Куда переводить?

HoBTIDИ Ваш код удовлетворяет критерию слабой связности, например?
Или, может быть, он ошибкоустойчивый к будущим изменениям?
Это здесь при чем? Это же не я заявляю об "универсальности".
Мой код лаконичный - пока что не вижу чтобы кто-то более простое решение предложил. Полностью сохраняет семантику оригинального метода. Полностью сохраняет изначальный дизайн, класс, который отвечал за маппинг индекса на свойства, всё так же за это и отвечает. Это не значит что я с первоначальным дизайном согласен. Поэтому и порекомендовал унести маппинг индекса на свойства в саму сущность.

Вы же предлагаете автору решение,
- которое потребует перелопатить вагон существующего кода в том числе за пределами указаных методов.
- решение, которое не факт что натянется на существующие view
- решение, которое обладает непостижимо максимальной "универсальностью"

У меня на проекте имеется ArrayBeanTableModel, универсальный для всех сущностей. Без всяких матриц. Никак от детипизации я не страдаю. Ваше же решение сродни динамической типизации. Никакой возможности контролировать что там в матрице и как-то этим пользоваться. Единственное что можно делать, это выводить на View. Какая-от сомнительная универсальность выходит.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555599
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczУ меня на проекте имеется ArrayBeanTableModel, универсальный для всех сущностей. Без всяких матриц.
Т.е. у себя вы используете решение, не зависящее от типа сущности, а автору темы предлагаете зависящее. Оригинально.
И на каком же принципе оно основано? Дайте угадаю, рефлексия?

BlazkowiczНикак от детипизации я не страдаю. Ваше же решение сродни динамической типизации. Никакой возможности контролировать что там в матрице и как-то этим пользоваться. Единственное что можно делать, это выводить на View. Какая-от сомнительная универсальность выходит.
Действительно, контролировать ничего не нужно, т.к. данные через эту матрицу не редактируются, только выводятся для просмотра.
Редактирование строчки нужно делать уже через сущность в отдельной форме.

Преимущество в том, что матрица реализует все требования к списку для просмотра
(сортировка, фильтрация, может быть реализовано постраничная загрузка) и этим не нужно заморачиваться в сущностях.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555622
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDТ.е. у себя вы используете решение, не зависящее от типа сущности, а автору темы предлагаете зависящее. Оригинально.

Автору я предлагаю решение проблемы о которой он спросил. А не переписать половину проекта под "универсальное" решение.

HoBTIDИ на каком же принципе оно основано? Дайте угадаю, рефлексия?

С фига ли? Мапятся колонки на свойства схожим образом через switch case. У меня гриды на View слишком динамично меняются и довольно сильно отличаются от модели. Поэтому существует отдельный слой маппинга модели на гриды.
Зато через него всегда доступна строго типизированя модель, через которую я всегда могу запускать бизнес-логику, конкретного типа. В вашем же решении, отдельно матрица только для просмотра, отдельно список сущностей где-то ещё, либо списка вообще нет, и сущности каждый раз пересобираеются из матрицы без какого либо контроля типов. Действительно что может быть проще и универсальнее массива массивов.

HoBTIDДействительно, контролировать ничего не нужно, т.к. данные через эту матрицу не редактируются, только выводятся для просмотра.
Редактирование строчки нужно делать уже через сущность в отдельной форме.

Оу, но теперь понятно всё. Т.е. данные можно только редактировать и показывать. Теперь мы пришли к тому что матрица сразу делает грид не доступным для радактирования, а лишь только через отдельную форму. Очень "универсально".


HoBTIDПреимущество в том, что матрица реализует все требования к списку для просмотра
(сортировка, фильтрация, может быть реализовано постраничная загрузка) и этим не нужно заморачиваться в сущностях.
У меня есть сортировка, и постраничная загрузка. Фильтрация унесена на уровнеь работы с базой. Локально фильтровать сущности, как-то странно и не эффективно. И всё это на типизировном списке сущностей, без матрицы.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555680
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczС фига ли? Мапятся колонки на свойства схожим образом через switch case. Поэтому существует отдельный слой маппинга модели на гриды.
switch case независимо от типа сущности? Я поражен.
Или же для каждой сущности есть отдельный объект маппинга, куда спрятан этот switch, и это Вы называете "независимо"?

BlazkowiczЗато через него всегда доступна строго типизированя модель, через которую я всегда могу запускать бизнес-логику, конкретного типа. В вашем же решении, отдельно матрица только для просмотра, отдельно список сущностей где-то ещё, либо списка вообще нет, и сущности каждый раз пересобираеются из матрицы без какого либо контроля типов. Действительно что может быть проще и универсальнее массива массивов.
Действительно, у моего решения есть недостаток, если нужна бизнес логика непосредственно в списке, его использовать нельзя.
Но чаще всего, такая логика не нужна.
Отдельного списка сущностей нет, сущность загружается из БД или берется из кэша, при начале редактирования.
Из матрицы пересобирать не совсем корректно, т.к. она может не содержать всех колонок, и уж точно не содержит табличных частей.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555693
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDswitch case независимо от типа сущности? Я поражен.
Или же для каждой сущности есть отдельный объект маппинга, куда спрятан этот switch, и это Вы называете "независимо"?

Прикинь, да. Модель на View надо как-то маппить. Эка неожиданность для гуру дизайна. Правда?
В вашем решении возможны два варианта. Либо вы в матрицу вываливаете всё что только можно. Каким образом, например, гарантировать порядок колонок?
Либо у вас присутствует точно такой же маппинг, но в неявном виде. Что затрудняет его поддержку.

HoBTIDДействительно, у моего решения есть недостаток, если нужна бизнес логика непосредственно в списке, его использовать нельзя.
Но чаще всего, такая логика не нужна.

Добро пожалуйвать в чудесный мир Anemic Domain Model.

HoBTIDОтдельного списка сущностей нет, сущность загружается из БД или берется из кэша, при начале редактирования.

Мы уже поняли, что у вас кроме просмотра редактирования, другой логики быть не может. Можно не продолжать.

HoBTIDИз матрицы пересобирать не совсем корректно, т.к. она может не содержать всех колонок, и уж точно не содержит табличных частей.
Ну, понятно. Все прелести Anemic Domain Model. Если нужна логика для конктретного типа, она будет реализована прям там в таблице с матрицей этого типа. Это очень удобно, не нужно вообще париться о разделении модели и представлении.
До тех пор пока одна и та же логика вдруг не потребуется на нескольких разных слоях.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555698
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут цена вопроса - "сферический проект в вакууме" или уже имеющийся проект
который писали в определённом ключе.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555719
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonТут цена вопроса - "сферический проект в вакууме" или уже имеющийся проект
который писали в определённом ключе.
Как можно?! Саппорт это для джуниоров. Гуру дизайна всё пишет с нуля!
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555767
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczmaytonТут цена вопроса - "сферический проект в вакууме" или уже имеющийся проект
который писали в определённом ключе.
Как можно?! Саппорт это для джуниоров. Гуру дизайна всё пишет с нуля!
Гуру дизайна и совершенство архитектурной мысли постепенно переписывает плохие участки.
А не продолжает говнокодить в том же стиле, как изначально была написана система.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555773
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDГуру дизайна и совершенство архитектурной мысли постепенно переписывает плохие участки.
А не продолжает говнокодить в том же стиле, как изначально была написана система.
Ключевое слово "постепенно".
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555781
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczКлючевое слово "постепенно".
Конечно, параллельно с имеющимися, создаете класс матрицы,
создаете новую форму в дополнение к существующей форме списка одного из типов сущностей,
и ее уже делаете через матрицу.
Кстати, порядок колонок задается просто порядком их добавления в список колонок (List<ColumnDef> columns).
А пользователь естественно может переставлять колонки во View.

Поскольку матрица это всего лишь ViewModel, она ничего не затрагивает из бизнес-логики.
На нее легко можно перевести отдельные списки, не трогая "половину приложения".
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555832
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDПоскольку матрица это всего лишь ViewModel, она ничего не затрагивает из бизнес-логики.
На нее легко можно перевести отдельные списки, не трогая "половину приложения".
Да, понятно, что ViewModel. Только не понятно нафига оно. ViewModel в этом случае исключительно односторонняя. Хотя ViewModel по задумке обеспечивает связь в обе стороны. Кроме этого ViewModel концепия удобна в случае внятных инструментов биндинга. Для чего она нужна, если биндинга нет - не понятно.
Ну и вы нам так и не расказали свою сокровенную тайну как именно Model мапиться на ViewModel.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555883
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczНу и вы нам так и не расказали свою сокровенную тайну как именно Model мапиться на ViewModel.
Да вы оказывается кое-что понимаете.
Это действительно тайна.
В колонке ViewModel указывается путь по свойствам до нужного реквизита, например:
Код: java
1.
2.
columnProducerName.addPropertyToPath(Good.PRODUCER_PROP);
columnProducerName.addPropertyToPath(Producer.NAME_PROP);


Затем, по пути свойств определяются имена таблиц и колонок в БД.
Строится запрос с JOIN'ами и из результата его выполнения заполняется матрица.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38555904
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTIDДа вы оказывается кое-что понимаете.

Снова нарываетесь на грубость.

HoBTIDЭто действительно тайна.
В колонке ViewModel указывается путь по свойствам до нужного реквизита, например:
Код: java
1.
2.
columnProducerName.addPropertyToPath(Good.PRODUCER_PROP);
columnProducerName.addPropertyToPath(Producer.NAME_PROP);



Чем это принципиально лучше type safe switch case? В коротм не нужны константы на каждое свойство.

HoBTIDЗатем, по пути свойств определяются имена таблиц и колонок в БД. Строится запрос с JOIN'ами и из результата его выполнения заполняется матрица.

Ну, понятно. View слой самым прямым образом влияет на доступ к данным. И теперь вы полностью подтвердили мои догадки про джуниорство. Лет 7-8 назад я дизайнил решения именно таким же образом. "Универсально", но при этом то что называется термином Over Abstracted. "Универсальность" заключается в том что, действительно один и тот же код покрывает все сущности. Это с точки зрения молодого программиста мега опупенно. Но при этом на лицо все недостатки излишней абстрагированости:
- если появляются требования не задуманые изначально абстракцией, то нужно рефакторить саму абстракцию
- ООП идет лесом, так как нет никакой возможности заточить разное поведение, под разные сущности.
У меня, например, в проекте есть у бизнес сущностей сложное вычислимое свойство. Которое не только влияет на бизнес-процесс, но и требует специального отображения на view. И как же прикажете быть в таком Anemic View, где бизнес сущности принципиально отствутствуют? Выносить вычисления в БД? И подрезать таким образом переносимость?
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38556295
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MonochromatiqueНо как-то хотелось думать (не приведи Бог столкнуться), что в JAVA есть эквивалент - persons.OrderBy(p=>p.name)

Ещё пара месяцев и будет
personList.sort((p1, p2) -> p1.name.compareTo(p2.name));

OrderBy, тоже можно забабахать со ссылкой на getter.
http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

Только в данном случае в этом пользы особой нет.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38556298
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С++ возвращается?

Код: plaintext
1.
ContainingClass::staticMethodName
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38556303
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonС++ возвращается?
Код: plaintext
1.
ContainingClass::staticMethodName


Угу. Java и так не дружелюбна к нубам. А теперь со стрелочками и двоеточиями будет ещё головоломнее.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Пятничный Best practices.
    #38911058
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Жду сахара в "девятке". Вот такую конфету. Как в "шарпах"

Вместо:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
String location = "";
if (vendor != null)
{
    if (vendor.ContactPerson() != null)
    {
        if (vendor.ContactPerson.HomeAddress() != null)
        {
            location = vendor.ContactPerson.HomeAddress.LineOne();
        }
    }
}



вот так писать.
Код: java
1.
String location = vendor?.ContactPerson()?.HomeAddress()?.LineOne();

.

Сорц был нагло спизж взят мной из Хаба-хабра. И подпилен чтоб был похож на Java
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38911327
organism
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,

Берем Groovy и не ждем)
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38911334
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Круть.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38911690
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЖду сахара в "девятке". Вот такую конфету. Как в "шарпах"
Ужас. От null'ов надо избавляться, а не прятать их за синтаксическим сахаром.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38911743
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeonidvmaytonЖду сахара в "девятке". Вот такую конфету. Как в "шарпах"
Ужас. От null'ов надо избавляться, а не прятать их за синтаксическим сахаром.
+1. Мы может заменить null на NullObject в СВОЁМ коде. Но OVER9000 библиотек удалённого
вызова или persistence оставляют за собой право возвращать неинициализированные части
объекта (для SOAP) или null филды если это БД. Таковы реалии. Как с этим
бороться - неизвестно.

И вобщем-то даже не проблема с null как с "признаком" особого статуса return. А проблема
с семантикой операций которые с ним разрешены. В БД к примеру nulls можно суммировать,
ранжировать и сортировать и делать операции больше/меньше. Результат - будет детерминирован
и никакого исключения не будет. В Java подобная семантика - непозволительна.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38911749
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Код: java
1.
String location = vendor?.ContactPerson()?.HomeAddress()?.LineOne();


Сорц был нагло спизж взят мной из Хаба-хабра. И подпилен чтоб был похож на JavaНасколько я могу судить по "Java SE 8. Вводный курс" Кея Хорстмана, есть isNull, nonNull и Optional.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38911973
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonLeonidvпропущено...

Ужас. От null'ов надо избавляться, а не прятать их за синтаксическим сахаром.
+1. Мы может заменить null на NullObject в СВОЁМ коде. Но OVER9000 библиотек удалённого
вызова или persistence оставляют за собой право возвращать неинициализированные части
объекта (для SOAP) или null филды если это БД. Таковы реалии. Как с этим
бороться - неизвестно.

Изолировать null в слое взаимодействия с этими инструментами.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38912021
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЖду сахара...Я тоже ). Но будет ли такое:
- Оператор ??
- implicit (!)
- explicit (!)
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38912267
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman,

Если хочется такого, то есть Scala. implicit есть, ?? - при работе с option это фактически map, flatMap и т.п.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38912587
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonidvmaytonпропущено...

+1. Мы может заменить null на NullObject в СВОЁМ коде. Но OVER9000 библиотек удалённого
вызова или persistence оставляют за собой право возвращать неинициализированные части
объекта (для SOAP) или null филды если это БД. Таковы реалии. Как с этим
бороться - неизвестно.

Изолировать null в слое взаимодействия с этими инструментами.
Цена этого решения почти такая-же как "лесенка" из if.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38912604
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeonidvЕсли хочется такого, то есть ScalaБез "подмешивания"...
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38913265
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Перегрузка "+","-".... для BigDecimal всё таки нужна. Иначе финансовый софт выглядит лажово.
Здесь как-бе принципы Java-ООП звучат убедительно но рука тянется за перегрузкой.

+Джунгарики-нубасы подкидывают траблов. Только отвернёшся - они "запилят" double или
float в финансовые величины. И ведь хочется выглядеть убедительным.... но этот BigDecimal
не выглядит рефакторингом хотя-бы с эстетической точки зрения.

Ты вроде точность улучшил ... а код превратился в месиво методов.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38917067
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще сахарка подкину.

Код: java
1.
2.
3.
4.
5.
6.
List<ChessPosition> horseRoute(ChessPosition beginPos){
       // many recursive calls horseRoute(....);
       if (someCond){
           yield return chessPosition;
       }
}
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38924250
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прошу прощения. Я сюда припёрся снова сонный и сердитый. Ох встречу я этого
Гослинга - дам ему подсрачника в его джинсовый зад. А потом сниму с него очки
и втопчу в асфальт.

Вот пишу

Код: java
1.
2.
3.
is (someFuckenObj.compareTo(otherFuckenObject) ... ){

}



и каждый рас зависаю на 5 - 15 секунд. Вспоминаю там знак ">" это аналог положительного целого
или наоборот в предикате compareTo.

Ну неужели не мох ты заложить в стандарте хотя-бы этот математический оператор,
чортов ты бородач?!

P.S. Всё аривуар. Расстроен. Пошёл пить лекарство.

P.S. Извините если чо. Простужен.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38925103
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Код: java
1.
2.
3.
if(someFuckenObj.compareTo(otherFuckenObject) > 0){

}




Я за то чтобы такой код не писать. Я за читаемость:

if(someObj.greaterThan(anotherObject)){
if(someObj.olderThan(anotherObject)){
if(greater(someObject, thenObject)){

И в том же духе. Имя метода должно следовать предметной модели.
...
Рейтинг: 0 / 0
Пятничный Best practices.
    #38980515
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczmayton
Код: java
1.
2.
3.
if(someFuckenObj.compareTo(otherFuckenObject) > 0){

}




Я за то чтобы такой код не писать. Я за читаемость:

if(someObj.greaterThan(anotherObject)){
if(someObj.olderThan(anotherObject)){
if(greater(someObject, thenObject)){

И в том же духе. Имя метода должно следовать предметной модели.


прикольно, что Java-программисты называют это "читаемость".

по мне читаемость - это

if( someobject > otherobject )
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Пятничный Best practices.
    #39528711
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
76 сообщений из 76, показаны все 4 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Пятничный Best practices.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]