Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите с проектированием 
:(
    Опции темы
korob2001
Дата 16.3.2006, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 1
Всего: 61



Привет!
Мне нужно написать класс который получает 2 числа, это могут быть числа byte, short, int, long, double, float или char. Он сохраняет эти данные в своих полях. Так же есть методы intDiapason(), floatDiapason(), doubleDiapason() и так для каждого типа. Метод возвращает массив чисел соответствующего типа, в заданном диапазоне. Например можно вызвать класс так из командной строки:
Код

C:\MyJava\Diapason>java UsedDiapason 100 1000

Всё вроде бы ничего, но проблема в том, что я не могу спроектировать это. Так как тип заранее не известен, а писать для каждого типа отдельный класс помоему, это не есть верно, а может просто я достаточно ленив? smile
Вобщем единственное что пришло в голову, это написать интерфейс:
Код

interface NumberDiapason
{
    int[] intDiapason();
    double[] doubleDiapason();
    float[] floatDiapason();
    byte[] byteDiapason();
    short[] shortDiapason();
    char[] charDiapason();
}

Затем написал класс, который реализует его:
Код

public class IntDiapason implements NumberDiapason
{
    private int start;
    private int stop;
    private int column = 5;
    
    public IntDiapason(int start, int stop) {
        if ( stop < start ) {
            this.start = stop;
            this.stop  = start;
        } else {
            this.start = start;
            this.stop  = stop;
        }
    }
    
    public int[] intDiapason() {
        int[] res = new int[stop - start + 1];
        for (int i=0; i < res.length; i++)
            res[i] = start + i;
        return res;
    }
    
    public float[] floatDiapason() {
        float[] res = new float[stop - start + 1];
        for (int i=0; i < res.length; i++)
            res[i] = (float)start + i;
        return res;
    }
    
    public double[] doubleDiapason() {
        double[] res = new double[stop - start + 1];
        for (int i=0; i < res.length; i++)
            res[i] = (double)start + i;
        return res;
    }
    
    public char[] charDiapason() {
        char[] res = new char[stop - start + 1];
        for (int i=0; i < res.length; i++)
            res[i] = (char)(start + i);
        return res;
    }
    
    public byte[] byteDiapason() {
        byte[] res = new byte[stop - start + 1];
        for (int i=0; i < res.length; i++)
            res[i] = (byte)(start + i);
        return res;
    }
    
    public short[] shortDiapason() {
        short[] res = new short[stop - start + 1];
        for (int i=0; i < res.length; i++)
            res[i] = (short)(start + i);
        return res;
    }
    
    public String toString() {
        String res = "";
        int[] diap = new int[stop - start + 1];
        for (int i = 0; i < diap.length; i++) {
            res += i + start;
            if ((i+1) % column != 0)
                res += ", ";
            else
                res += "\n";
        }
        return res;
    }
    
    public void columns(int column) {
        this.column = column;
    }
}

Изначально я предполагал написать этот класс, для типа int, но когда реализовал и остальные методы, то подумал, а нужен ли вообще здесь интерфейс?

Подскажите, как грамотнее спроектировать данный класс?
Как вы определяете, где заюзать интерфейс, а где абстрактный класс?

Что-то я вообще запутался. smile


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
LSD
Дата 17.3.2006, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15719
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(korob2001 @ 16.3.2006, 23:54 Найти цитируемый пост)
Так как тип заранее не известен, а писать для каждого типа отдельный класс помоему, это не есть верно, а может просто я достаточно ленив?

В данном случае это верно smile Например классы обертки для примитивных типов, там по классу на каждый примитивный тип.

Я бы сделал базовый абстрактный класс с реализацией методов xxxDiapason() а вот setDiapason() вынес бы в конкретную реализацию.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
korob2001
Дата 17.3.2006, 00:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 1
Всего: 61



Цитата

Я бы сделал базовый абстрактный класс с реализацией методов xxxDiapason() а вот setDiapason() вынес бы в конкретную реализацию.

Да, но насколько я понял. я должен указать тип возвращаемого значения метода xxxDiapason(), в абстрактном классе. А какой, он же может возвращать любой массив типа byte, short, int, long, double, float, char? Если бы возвращаемое значение было бы void, и весь диапазон печатался внутри метода, то проблем не было бы. ;(((((
Добавлено @ 00:36
Вроде дошло smile
Вот о чём подумал:
В интерфейсе обьявить 2 метода getDiaposon() и setDiaposon(), затем каждый класс будет их реализовывать для своего типа. Затем создать класс Diaposon и перегрузить его конструкторы для каждого типа, они и будут возвращать нужный объкт, в зависимости от того, какого типа были получены параметры.
Или я опять, что-то намудрил? smile
Да, вних же тоже я должен укзать тип возвращаемого значения и тип аргументов, которые будет получать метод setDiaposon(тип x, тип у). ;(((((

Это сообщение отредактировал(а) korob2001 - 17.3.2006, 00:41


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
LSD
Дата 17.3.2006, 00:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15719
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



1. Вот ты привел пример класса IntDiapason и там есть методы intDiapason(), doubleDiapason() и т.д. для всех числовых типов. Так почему бы их не вынести в базовый класс? А реализация должна будет только предоставить границы для этого диапазона.

2. Всегда есть выход возвращать Object и приводить его потом к правильному типу массива. Или как вариант, использовать массивы не примитивных типов, а Number[] а в него класть Integer, Double и т.д.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Stampede
Дата 17.3.2006, 00:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 24
Всего: 144



korob2001, коль скоро речь идет о проектировании, будет гораздо лучше, если ты сначала расскажешь, чего ты вообще хочешь добиться. Простыми словами. Ну как в том анекдоте: "ты не умничай, ты пальцем покажи" smile

Сдается мне, что твою задачу можно решить и проще. Например, я вижу, как тут мог бы помочь класс BigDecimal. Но тогда задачу придется переформулировать. А для этого нужно знать исходные требования.

Так что пиши smile

PM WWW   Вверх
korob2001
Дата 17.3.2006, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 1
Всего: 61



1.) Создать класс Diaposon, коструктору будут переданы аргументы: например new Diaposon(100,150). В данном случае, это аргументы типа int, но они могут быть и doble и short и char и т.д. Возможно чуть позже понадобится ещё один аргумент, step, сейчас можно обойтись и без него, используюя шаг в единицу. Опять же тип поля step должет быть того же типа, что и сам диапазон чисел.
2.) В классе Diaposon должен быть метод, который возвращает массив чисел в заданном диапозоне. Тип возвращаемого массива зависит от того, какого типа были переданы параметры.

PS: Аргументы передаваемые конструктору каласса не могут быть разного типа, т.е. они оба либо int, либо short, либо char и т.д. Именно от того какого типа были аргументы и зависит тип возвращаемого массива, который возвращает метод getDiaposon()

Это сообщение отредактировал(а) korob2001 - 17.3.2006, 01:05


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Stampede
Дата 17.3.2006, 01:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гносеолог
**


Профиль
Группа: Участник Клуба
Сообщений: 963
Регистрация: 25.4.2005
Где: Calgary, Alberta, Canada

Репутация: 24
Всего: 144



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

Ну а в том виде, в каком ты его хочешь, можно пойти таким путем.

1. Во-первых, переменные start и stop не могут быть типа int, а иначе при касте из long, float и double может теряться точность. Значит нужно или заводить переменные разных типов, или приводить все к такому типу, который мог бы вместить в себя любые другие: например double.

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

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

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

5. Можно вообще сделать класс с одними статическими методами, к которому можно обращаться так:

Код

byte from = 10;
byte to = 20;
byte[] diapason = Diapason.byteDiapason(from, to);


Короче, вариантов море. Все зависит от того, как ты это собираешься использовать. А ты об этом молчишь, как партизан smile

PM WWW   Вверх
korob2001
Дата 17.3.2006, 04:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 1
Всего: 61



Stampede
Да это не секрет, просто хочется чего-нить написать, с интерфейсом, я их сейчас проходил. smile Вобщем наверное интерфейс не подойдёт для такой задачи, решил с помощью перегруженного статического метода:
Код

public class Diaposon {
    public static byte[] getDiaposon(byte start, byte stop) {
        if (start > stop) {
            byte tmp = start;
            start = stop;
            stop  = tmp;
        }
        byte[] array = new byte[stop - start + 1];
        for (int i=0; i < array.length; i++)
            array[i] = (byte)(start + i);
        return array;
    }
    
    public static short[] getDiaposon(short start, short stop) {
        if (start > stop) {
            short tmp = start;
            start = stop;
            stop  = tmp;
        }
        short[] array = new short[stop - start + 1];
        for (int i=0; i < array.length; i++)
            array[i] = (short)(start + i);
        return array;
    }
    
    public static int[] getDiaposon(int start, int stop) {
        if (start > stop) {
            int tmp = start;
            start = stop;
            stop  = tmp;
        }
        int[] array = new int[stop - start + 1];
        for (int i=0; i < array.length; i++)
            array[i] = start + i;
        return array;
    }
    
    public static long[] getDiaposon(long start, long stop) {
        if (start > stop) {
            long tmp = start;
            start = stop;
            stop  = tmp;
        }
        long[] array = new long[(int)(stop - start + 1)];
        for (int i=0; i < array.length; i++)
            array[i] = (long)(start + i);
        return array;
    }
    
    public static float[] getDiaposon(float start, float stop) {
        if (start > stop) {
            float tmp = start;
            start = stop;
            stop  = tmp;
        }
        float[] array = new float[(int)(stop - start + 1)];
        for (int i=0; i < array.length; i++)
            array[i] = (float)(start + i);
        return array;
    }
    
    public static double[] getDiaposon(double start, double stop) {
        if (start > stop) {
            double tmp = start;
            start = stop;
            stop  = tmp;
        }
        double[] array = new double[(int)(stop - start + 1)];
        for (int i=0; i < array.length; i++)
            array[i] = (double)(start + i);
        return array;
    }
    
    public static char[] getDiaposon(char start, char stop) {
        if (start > stop) {
            char tmp = start;
            start = stop;
            stop  = tmp;
        }
        char[] array = new char[stop - start + 1];
        for (int i=0; i < array.length; i++)
            array[i] = (char)(start + i);
        return array;
    }
}

А это код, который использует этот класс:
Код

public class TestDiaposon {
    public static void main(String[] args) {
        int columns = 5;
        //columns = Integer.parseInt(args[0]);
        
        int[] intdp = Diaposon.getDiaposon(100, 180);
        double[] dbldp = Diaposon.getDiaposon(250.0, 270.0);
        char[] chrdp = Diaposon.getDiaposon('a', 'z');
        
        System.out.println("\n\nInt deaposon:\n");
        for (int i=0; i < intdp.length; i++) {
            if ((i+1) % columns == 0)
                System.out.println(intdp[i] + "\n");
            else
                System.out.print(intdp[i] + ", ");
        }
        
        System.out.println("\n\nDouble diaposon:\n");
        for (int i=0; i < dbldp.length; i++) {
            if ((i+1) % columns == 0)
                System.out.println(dbldp[i] + "\n");
            else
                System.out.print(dbldp[i] + ", ");
        }
        
        System.out.println("\n\nChar diaposon:\n");
        for (int i=0; i < chrdp.length; i++) {
            if ((i+1) % columns == 0)
                System.out.println(chrdp[i] + "\n");
            else
                System.out.print(chrdp[i] + ", ");
        }
    }
}

Спасибо вам за помощь, наверное я не там решил заюзать интерфейсы, а так хотелось. smile


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0585 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.