powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Нужен паттерн
25 сообщений из 30, страница 1 из 2
Нужен паттерн
    #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
Нужен паттерн
    #38501946
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нельзя управлять из кода тем, что определяется на этапе компиляции.
...
Рейтинг: 0 / 0
Нужен паттерн
    #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
Нужен паттерн
    #38502073
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
class Начальник implements Рабочий {
  List<Рабочий> подчиненные;

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

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



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

я тащемта визитер и написал)
...
Рейтинг: 0 / 0
Нужен паттерн
    #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
Нужен паттерн
    #38502474
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
 instanceof 

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

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

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

а что на счет instanceof? кто-то мне говорил, что это трудоемкая операция и нужно избегать, а на другом собеседовании смеялись в лицо, услышав эту фразу. и я назвал "ФабрикаРабочих" не имея подтекстом AbstractFactory, ибо только слышал об этом паттерне и только...
...
Рейтинг: 0 / 0
Нужен паттерн
    #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
Нужен паттерн
    #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
Нужен паттерн
    #38502560
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну так у Вас уже наверное есть требования к интерфейсу Container?
...
Рейтинг: 0 / 0
Нужен паттерн
    #38502731
NDAleksey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛагманНу так у Вас уже наверное есть требования к интерфейсу Container?

от начальства - лишь только, чтобы его имплементили классы файла и сервиса, ибо потом нужно будет расширить "потомков". а дальнейшее я должен сам надумать.
если я сделаю в нем методы create/update/delete, то в классах CSV_Container и WS_Container я должен их реализовать. а реализация у них разная, несмотря на то, что у них должны быть различные входные параметры. да и названия методов как бы думаю будут различные.
получив такой аргумент начальник сказал, что я должен Container передавать как параметр в метод и отослал меня. вот я и придумал ту структуру...
...
Рейтинг: 0 / 0
Нужен паттерн
    #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
Нужен паттерн
    #38502865
NDAleksey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛагманМожет что-то такое имеется ввиду, не?

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

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

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

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

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

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

P.S. реально очень признателен за то, что вы уделяете внимание моей теме. спасибо! как новичку - очень вдохновляет!
...
Рейтинг: 0 / 0
Нужен паттерн
    #38502910
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NDAlekseyбезлики
так в этом и суть, клиент (код пользующийся интерфейсом Container) можно написать один раз, и передавать ему какие угодно реализации Container'а
...
Рейтинг: 0 / 0
Нужен паттерн
    #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
Нужен паттерн
    #38503226
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NDAlekseyДоброго времени суток, уважаемые!

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

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

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

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

2 Лагман,

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

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

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

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

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

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

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

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

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

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

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


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