Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Нужен паттерн / 25 сообщений из 30, страница 1 из 2
16.12.2013, 11:06
    #38501867
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
Доброго времени суток, уважаемые!

Не успел освоить еще паттерны, а задача уже есть.
Надо создать класс/интерфейс, который в зависимости от входящего объекта будет возвращать тоже объект, но с определенным методами в нем. Пример:

Интерфейс - рабочий
Классы: слесарь, сантехник, плотник

нужно что-то типа:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
class РабочийHadler
{
    public РабочийHadler(Рабочий рабочий){}
    public static void сваркаПерекрытий(){}
    public static void починкаСмесителя(){}
    public static void резкаПодсвечника(){}
}

public class Main
{
    public static void main( String ... args )
    {
        Рабочий раб1 = new Слесарь();
        РабочийHandler handler1 = РабочийHandler( раб1 );

        handler1.сваркаПерекрытий();
        handler1.починкаСмесителя(); // compile error
    }
}



Вот. Чтобы handler1-у была доступна только ф-ция "сваркаПерекрытий()" и ничего большего. Через какой паттерн это реализовывается.... Ну или можно без паттерна?
...
Рейтинг: 0 / 0
16.12.2013, 12:11
    #38501946
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
Нельзя управлять из кода тем, что определяется на этапе компиляции.
...
Рейтинг: 0 / 0
16.12.2013, 12:14
    #38501951
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
Код: sql
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.
interface Задача{
   boolean надоРыть();
   boolean надоВарить();
}

interface Работа{
  void рыть();
  void варить();
}

interface Рабочий{
  void поработать(Задача з, Работа р);
}

class Рытель implements Рабочий {
  void поработать(Задача з, Работа р){
    if (з.надоРыть()) р.рыть();
  }

class Сварщик implements Рабочий {
  void поработать(Задача з, Работа р){
    if (з.надоВарить()) р.варить();
  }

class Разнорабочий implements Рабочий {
  void поработать(Задача з, Работа р){
    if (з.надоРыть()) р.рыть();
    if (з.надоВарить()) р.варить();
  }

class НеаккуратныйРазнорабочий implements Рабочий {
  void поработать(Задача з, Работа р){
    р.рыть();
    р.варить();
    р.рыть();
    р.варить();
    р.рыть();
    р.варить();
  }


}
...
Рейтинг: 0 / 0
16.12.2013, 13:25
    #38502073
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
Код: sql
1.
2.
3.
4.
5.
6.
class Начальник implements Рабочий {
  List<Рабочий> подчиненные;

  void поработать(Задача з, Работа р){
    for (Рабочий подчиненный: подчиненные) { подчиненный.поработать(з, р);}
  }
...
Рейтинг: 0 / 0
16.12.2013, 13:57
    #38502123
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
Лагман
Код: sql
1.
2.
3.
4.
5.
6.
class Начальник implements Рабочий {
  List<Рабочий> подчиненные;

  void поработать(Задача з, Работа р){
    for (Рабочий подчиненный: подчиненные) { подчиненный.поработать(з, р);}
  }



спасибо, за отклик, но мне тут посоветовали паттерн Visitor... вроде по первому впечатлению то, что я хотел... щас посмотрю реализацию подробнее...
...
Рейтинг: 0 / 0
16.12.2013, 14:09
    #38502150
Нахлобуч
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
NDAlekseyспасибо, за отклик, но мне тут посоветовали паттерн Visitor... вроде по первому впечатлению то, что я хотел... щас посмотрю реализацию подробнее...
Вообще не из этой оперы.
...
Рейтинг: 0 / 0
16.12.2013, 15:47
    #38502336
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
NDAleksey,

я тащемта визитер и написал)
...
Рейтинг: 0 / 0
16.12.2013, 16:55
    #38502446
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
ЛагманNDAleksey,
я тащемта визитер и написал)

Я не спорю, просто я в шаблонах не бельмесу, к сожалению, а в книжке, которая щас под рукой, "Применение шаблонов в Java" С.Стелтинг., там мне визитер несколько иначе показался реализован.

Но, пораскинув серым веществом, думаю, что он тут не совсем удобен. К примеру, возвращаемся к вашей "структуре". Я могу сделать так:

Код: java
1.
2.
3.
4.
5.
6.
7.
public static void main( String ... args )
{
	Рабочий начальник = new Начальник();
	начальник.подчиненные.add( new Варитель(), new Рытель() );
	
	начальник.поработать( надоРыть(), рыть() );
}



Вопрос: как отработает наш дорогой рабочий-Варитель? Коллизии в логике не возникнет?

Предлагаю на критику следующую "структуру":

Код: 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.
interface Задача{}

class Рытье implements Задача
{
	void рытьВглубину(){}
	void рытьВдлинну(){}
}

class Варение implements Задача
{
	void варитьПластик(){}
	void варитьМеталл(){}
}

interface Рабочий(){}

class Рытель() implements Рабочий
{
	void начатьРыть();
	void закончитьРыть();
}

class Варитель() implements Рабочий
{
	void начатьВарить();
	void закончитьВарить();
}

class ФабрикаРабочих
{
	Рабочий получитьРабочего( Задача задача )
	{
		if ( задача instanceof Рытье() )
			return new Рытель();
			
		if ( задача instanceof Варение() )
			return new Варитель();
	}
}

public static void main( String ... args )
{
	Рабочий варитель = ФабрикаРабочих.получитьРабочего( new Варение() );
	варитель.начатьВарить();
	
	Рабочий рытель = ФабрикаРабочих.получитьРабочего( new Рытье() );
	рытель.начатьРыть();
}
...
Рейтинг: 0 / 0
16.12.2013, 17:08
    #38502474
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
Код: sql
1.
 instanceof 

можно использовать только в самом крайнем случае, если например костылизируете чужой код. Если код пишете Вы сами, стоит избежать.
Зачем вообще фабрики и т.п., если вы в коде явно пишете, что делать рабочим?
...
Рейтинг: 0 / 0
16.12.2013, 17:22
    #38502499
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
Лагман
Код: sql
1.
 instanceof 

можно использовать только в самом крайнем случае, если например костылизируете чужой код. Если код пишете Вы сами, стоит избежать.
Зачем вообще фабрики и т.п., если вы в коде явно пишете, что делать рабочим?

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

а что на счет instanceof? кто-то мне говорил, что это трудоемкая операция и нужно избегать, а на другом собеседовании смеялись в лицо, услышав эту фразу. и я назвал "ФабрикаРабочих" не имея подтекстом AbstractFactory, ибо только слышал об этом паттерне и только...
...
Рейтинг: 0 / 0
16.12.2013, 17:34
    #38502516
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
instanceOf это враг ООП.
Что значит "Оградить" ?
Чтоб оградить программиста от возможности вызвать метод копать() у варщика, есть жесткая типизация.
Если по каким-то причинам оба должны иметь метод копать() и варить(), но не хотят, то вам нужен адаптер, который ничего не делает вместо работы
Код: sql
1.
2.
3.
4.
abstract class РабочийAdapter{
  void   копать(){}
  void   варить(){}
}



а ещё можно сделать так

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Рабочий{
  List<Runnable> навыки(){}
}

Копатель implements Рабочий{
  List<Навыки> навыки(){return Arrays.asList(new Runnable(){ void run(){System.out.println("Я тут копаю на, чё лезешь");}})}
}

void main(){
  for (Runnable навык : new Копатель().навыки() ){
    навык.run();
  }
}
...
Рейтинг: 0 / 0
16.12.2013, 18:04
    #38502551
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
2 Лагман,

ценю участие и советы (особенно последний - поразил! в Java я месяца два только и до этого сталкивался с Runnable только с потоками), поэтому если не возражаете помочь, давайте перейдем к реальной предметной области, а то я с переинтерпретированием уже запутался - сам дурак, не нужно было всяких рабочих придумывать)

есть сущности: CSV-файл, WebService, DB.
пока работаю только с CSV, ибо структуру его только знаю, остальное - потом (сказал начальник)
задача: создать интерфейс типа Container, от которого будут имлементиться все сущности.

еще задача: создать, как бы, описатель файла - поделить его на таблички в БД. допустим таблицы: Files (id, URI, delimeter, is_title), Columns(id, type, position, file_id, title).

к чему это - моя сущность "файл" и, в дальнейшем, "веб-сервис" имплементят "Container".

у "файл" должны быть методы create/update/delete Files + Columns, которые в свою очередь через ejb создаются в БД (не суть).

так вот начальник требует, чтобы именно был один интерфейс и потомки. мне не пришло ничего умного, как создать то, что показал, где "Рабочий" - это "Container", "Рытель" - "CSV-файл", "Копатель" - "WebService".

не зная, как работает сервис и, что в нем будет, я должен иметь объект CSV с только ему доступными вышеуказанными методами.
поэтому и хочу, чтобы ему не были видны методы веб-сервиса, и не имплементить их из "Container".

извиняюсь за писанину - лаконичность не мой конек, но что скажете по теме?)
...
Рейтинг: 0 / 0
16.12.2013, 18:15
    #38502560
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
Ну так у Вас уже наверное есть требования к интерфейсу Container?
...
Рейтинг: 0 / 0
16.12.2013, 21:09
    #38502731
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
ЛагманНу так у Вас уже наверное есть требования к интерфейсу Container?

от начальства - лишь только, чтобы его имплементили классы файла и сервиса, ибо потом нужно будет расширить "потомков". а дальнейшее я должен сам надумать.
если я сделаю в нем методы create/update/delete, то в классах CSV_Container и WS_Container я должен их реализовать. а реализация у них разная, несмотря на то, что у них должны быть различные входные параметры. да и названия методов как бы думаю будут различные.
получив такой аргумент начальник сказал, что я должен Container передавать как параметр в метод и отослал меня. вот я и придумал ту структуру...
...
Рейтинг: 0 / 0
16.12.2013, 22:58
    #38502834
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
Может что-то такое имеется ввиду, не?
Мои навыки телепатии немного слабы..
Код: sql
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.
Container{
  void create(String arg);
  List<String> list();
}
 
Csv implements Container{
  @Override
  void create(String arg){
    ..... добавляется строка с текстом arg в файл ....
  }

  @Override
  List<String> list(){
    .... читаются строки из файла ....
  }
}

WS implements Container{
  @Override
  void create(String arg){
    .... вызывается api www.host.com/insertText?text=arg.... 
  }
  @Override
  List<String> list(){
    .... вызывается api www.host.com/getMyTexts ....
  }
}
...
Рейтинг: 0 / 0
16.12.2013, 23:25
    #38502865
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
ЛагманМожет что-то такое имеется ввиду, не?

ну как же это сказать. моя задача, применительно к CSV - не добавлять строку в файл. мне нужно создать как бы описатель содержимого. отсюда и те таблички Files + Columns. если присмотреться, что я дал выше, то можно.

применительно к коду. мне не хотелось бы создавать общие методы create/update/delete - они же "безлики".
если я определяю их в интерфейсе, то их же реализовывают оба класса: CSV и WS.

а мне хотелось бы, чтобы у одного было что-то типа:

create(URI, columnCount, delimiter, isTitle) - создается описатель для файла с определенным URI, числом колонок, разделителем и есть ли заголовки в колонках - показатель.

также и для WS - я не знаю, что ему передавать в методы.

отсюда вывод - я не могу прописать эти методы в interface Container. отсюда и танцы с бубном. понимаете?

P.S. реально очень признателен за то, что вы уделяете внимание моей теме. спасибо! как новичку - очень вдохновляет!
...
Рейтинг: 0 / 0
17.12.2013, 00:11
    #38502910
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
NDAlekseyбезлики
так в этом и суть, клиент (код пользующийся интерфейсом Container) можно написать один раз, и передавать ему какие угодно реализации Container'а
...
Рейтинг: 0 / 0
17.12.2013, 00:39
    #38502931
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
ЛагманNDAlekseyбезлики
так в этом и суть, клиент (код пользующийся интерфейсом Container) можно написать один раз, и передавать ему какие угодно реализации Container'а

Код: 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.
interface Container {}

class CSV_Container implements Container
{
	CSV_Container( String URI, int colCount, String delimiter, boolean isTitle ) {}
}

class WS_Container implements Container
{
	WS_Container( String URI, ... ){}
}

class Client
{
	void create( Container container ){}
	void update( Container container ){}
	void delete( Container container ){}
}

public static void main( String ... args )
{
	Client.create( new CSV_Container( URI, colCount, delimiter, isTitle ) );
	Client.create( new WS_Container( URI, ... ) );
}



типа того?
...
Рейтинг: 0 / 0
17.12.2013, 11:33
    #38503226
HoBTID
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
NDAlekseyДоброго времени суток, уважаемые!

Не успел освоить еще паттерны, а задача уже есть.
Надо создать класс/интерфейс, который в зависимости от входящего объекта будет возвращать тоже объект, но с определенным методами в нем.

Вот. Чтобы handler1-у была доступна только ф-ция "сваркаПерекрытий()" и ничего большего. Через какой паттерн это реализовывается.... Ну или можно без паттерна?
Это реализуется парой паттернов Стратегия и Фабрика (фабричный метод)
Вместо Фабрики, по вкусу можно использовать Абстрактную фабрику , или Service Locator (на русском нет), или Внедрение зависимости .

Но для начала все же стоит попробовать обычную фабрику.
...
Рейтинг: 0 / 0
17.12.2013, 13:36
    #38503478
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
NDAlekseyНе успел освоить еще паттерны, а задача уже есть
Не надо думать о паттернах, надо думать о задачах. Перекос в сторону паттернов - это классический восходящий подход, заканчивающийся бардаком и развалом проекта под собственной тяжестью. Не читая готов спорить, что дальше будет очень много обсуждения паттернов - причём принципиально разных, несовместимых, и каждый будет говорить, что он прав, а другой предлагает какую-то совсем не подходящую для задачи фигню. И будет очень мало или совсем не будет ничего про задачу - про то, что и зачем Вы вообще хотите сделать. Потому как Ваше описание задачи, мягко говоря, слишком размыто, чтобы советовать какое-то решение.

NDAlekseyНадо создать класс/интерфейс, который в зависимости от входящего объекта будет возвращать тоже объект, но с определенным методами в нем. Пример:
Судя по описанию, нужно примерно следующее:

Код: java
1.
2.
3.
4.
5.
6.
7.
public class Producer {

  private static final Map<Class, Class> classMap = new HashMap<Class, Class>();

  public static synchronized void register(Class request, Class performer) {classMap.put(request, performer);}
  public static synchronized Object performer(Object request) {return classMap.get(request.getClass()).newInstance(request);}
}


Или? Лучше забудьте о слесарях и объясните толком, какую задачу решаете.
...
Рейтинг: 0 / 0
17.12.2013, 13:46
    #38503497
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
softwarerИли? Лучше забудьте о слесарях и объясните толком, какую задачу решаете.

не буду с Вами спорить, по поводу "какой подход лучше"... в реальной ООП разработке я новичок, ИМХО... а вот задачу я может сумбурно описал в своем посте №15300624... посмотрите повнимательнее)

2 Лагман,

щас разобрался с Visitor-ом - понравилось... никаких if/instanceof в коде нету) спасибо!
...
Рейтинг: 0 / 0
17.12.2013, 14:54
    #38503658
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
ЛагманЕсли по каким-то причинам оба должны иметь метод копать() и варить(), но не хотят, то вам нужен адаптер, который ничего не делает вместо работы
Скорее - судя по описанию - выбрасывает исключение типа operation not supported. Поможет отлаживать ситуации, когда варщика заставляют копать. Но глобально таких ситуаций однозначно стоит избегать.

NDAlexeyесть сущности: CSV-файл, WebService, DB.
пока работаю только с CSV, ибо структуру его только знаю, остальное - потом (сказал начальник)
задача: создать интерфейс типа Container, от которого будут имлементиться все сущности.
Сочувствую, задача довольно противная, и вот в таком подходе - сначала что есть, потом натянем на остальное - в ней очень легко наломать дров. Так или иначе, Ваша главная задача - очень вдумчиво и аккуратно специфицировать этот интерфейс. В "обычном стиральном порошке" это выглядит так:

- придумываем интерфейс, подходящий для csv, реализуем для csv класс А
- реализуем (основной) код, работающий через этот интерфейс
- начинаем натягивать на webservice, обнаруживаем, что интерфейс не натягивается
- придумываем, как дописать интерфейс, чтобы он "малой кровью" натягивался и туда, и туда
- реализуем для webservice класс Б
- обычно на этом этапе появляются методы-заглушки в реализациях, ничего не делают, но есть в классе А потому, что через них работает тоже реализующий интерфейс класс Б
- допиливаем (основной) код, чтобы он работал с новой версией интерфейса и выполнялся через класс Б
- обнаруживаем, что при этом сломали его работу через класс А, правим
- начинаем натягивать на DB, обнаруживаем, что не натягивается....

Чтобы не мучиться с таким уродцем, нужно хорошо понять ту абстракцию, которую Вы должны реализовать. Скажем, ИсточникДанных. Отталкиваясь от основного кода (того, который будет использовать эту абстракцию), нужно понять его методы. Требования при этом следующие:

- опираясь только на эти методы, вызывающий код сможет решить свои задачи
- этих методов достаточно мало, минимальное возможное количество, и они не альтернативны (избегаем ситуации "в классе А эту задачу решает метод АА, в классе Б - метод ББ, а в интерфейсе нужны оба, а в вызывающем коде вызывать оба каждый в своём месте)
- эти методы реализуемы для тех объектов, с которыми реально потребуется работать, причём без недопустимых извращений (скажем, БД не потребуется целиком считывать в память)

В целом, с первого раза - не получится. Не бывает такого счастья :) Но сразу подойдя правильно, Вы кардинально сократите мучения на последующих этапах.

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

NDAlexeyНужно было просто оградить варщика от копания, а копателя от варщика. это было нужно.
Их не нужно ограждать. У них обоих нужно сделать метод работать(), при вызове которого варщик варит, а копатель копает. Пусть этот метод возвращает РезультатРаботы (когда перестаёт хватать boolean). Итп.
...
Рейтинг: 0 / 0
17.12.2013, 15:28
    #38503727
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
softwarerNDAlexeyНужно было просто оградить варщика от копания, а копателя от варщика. это было нужно.
Их не нужно ограждать. У них обоих нужно сделать метод работать(), при вызове которого варщик варит, а копатель копает. Пусть этот метод возвращает РезультатРаботы (когда перестаёт хватать boolean). Итп.

да, я это понял, хоть и не сразу... кстати, если у Вас есть желание, могу скинуть код (кусок)... тут приведу UML-ку, что у меня в итоге получилось( Container - это Mapper, Actor - бывший рабочий ). оцените...

P.S. рисую UML-диаграмму первый раз, просьба по ушам не бить)
...
Рейтинг: 0 / 0
17.12.2013, 15:43
    #38503761
NDAleksey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
...
Рейтинг: 0 / 0
17.12.2013, 15:47
    #38503772
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Нужен паттерн
NDAleksey,

это любая из фабрик.
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Нужен паттерн / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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