Вопрос о шаблоне разработки

я - новичок к шаблонам разработки и здесь являюсь моим вопросом

если у нас есть абстрактный класс с немногими классами, которые реализуют его и каждое из этого, классы имеют различные атрибуты.

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

у меня есть 2 идеи:

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

Второе Решение: это выглядит несколько странным, и все еще нуждается в улучшениях, но его главная цель состоит в том, чтобы сделать менеджера или любые другие клиентские работы с абстрактным классом, не зная вещи о том, кто расширяет его или ее атрибуты.

solutin - как следует: каждый новый добавленный объект будет иметь сверхъязю один интерфейс, который осуществляет его для генерации полного описания его полей, например, автомобильный объект должен будет возвратить карту хеша, имеющую следующее

поле: {тип поля, fieldValue}

пример

  • модель: {текст, "брод"}
  • manifactureDate: {Дата, "12/1/89"}

и каждый объект должен будет также реализовать метод, названный compareFields, которые берут карту хеша как это и сравнивают ее с ее полем и возвращают TRUE или FALSE.

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

- для поиска я могу получить карту хеша, которые содержат поля, которые пользователь вводит в поисковую форму и цикл на абстрактных объектах, и вызовите сравнивание fieldmethod

я все еще не делаю, как я обработаю сложный объект (которые имеют другой объект как его атрибуты),

я не знаю, какой шаблон - это.. это - просто идея, что я думал о.

РЕДАКТИРОВАНИЕ: КОНКРЕТНЫЙ ПРИМЕР

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

7
задан 2 revs 17 December 2009 в 18:00
поделиться

8 ответов

Инкапсуляция

Объектно-ориентированный принцип инкапсуляции гласит, что ваш объект не должен раскрывать свое состояние извне. Если ваш объект передает внутреннюю информацию, инкапсуляция нарушается. Что все еще нормально согласно объектно-ориентированному дизайну, так это передать критерий поиска объекту и позволить ему решить, совпадают ли они.

interface IVehicle{
   bool doesMatch( Map<String,String> searchCriterion )
}

Вы можете иметь интератор на всех транспортных средствах и извлекать те, которые соответствуют, без нарушения инкапсуляции. Конкретная реализация транспортных средств все еще может быть повторно реализована по желанию.

Посетитель

В противном случае я бы посоветовал вам взглянуть на шаблон Посетитель . Идея состоит в том, чтобы обойти весь объект и получить дополнительный класс для обработки каждого конкретного типа. Это также нарушает чистую инкапсуляцию (потому что объект должен предоставлять свои данные посетителю), но это ' очень элегантно.

class VehicleSearchVisitor
{
   Map<String,String> searchCriterion;
   void visit( Car car ) {...}
   void visit( Bike bike ) { ... }
   ....
}

Мета-программирование

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

Insteanceof

Использование insteanceof также является формой самоанализа (потому что вы спрашиваете объект о его классе) и обычно не приветствуются . Не потому, что это неправильно само по себе, а потому, что им часто злоупотребляют. При любой возможности, полагаться на традиционные принципы объектно-ориентированного программирования. Оскорбительное использование instanceof является запахом кода .

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

9
ответ дан 6 December 2019 в 07:50
поделиться

Итак, вы расширяете класс вместо реализации интерфейса. Если бы у вас были классы Bus, Car, Truck, Train, и все они реализовали IVehicle, для которых требовалась функция, возвращающая значение, доступное для сортировки / поиска, вы могли бы ссылаться на все из них как на тип IVehicle и вызывать этот метод для всех. .

Код ActionScript 3:

package com.transportation.methods {
  public interface IVehicle {
    function getSpeed():Number;
    function getOtherSortableOrSearchableValue():*;
  }
}

и

public class Car extends Sprite implements IVehicle

Вам необходимо определить getSpeed ​​() и getOtherSortableValue () в классе Car, и вы можете ссылаться на него как на автомобиль, так и на транспортное средство. Поскольку все виды транспорта в моем примере будут реализовывать IVehicle, пока вы ссылаетесь на них как на IVehicles, вы можете вызывать эти две функции.

6
ответ дан 6 December 2019 в 07:50
поделиться

Кажется, вы описываете, что Стив Йегге называет универсальным шаблоном проектирования.

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

4
ответ дан 6 December 2019 в 07:50
поделиться

This seems to me like some sort of "centralized" Repository pattern. I don't think that's a good idea.

What you recommend you do is, instead of having one centralized way of generalized searching, you should have several specialized repositories: one for cars, one for boats, one for planes, etc.

Each of the repositories knows about the details of the respective objects. You can then factor out common operations between these specialized repositories, to a Repository base class or interface. When you don't care about the details, you use the base Repository interface. When you care about the details you use the specialized Repository.

Here's a simplistic example in Java (I'm leaving getters/setters out for shortness - don't make your fields public):

interface Vehicle { int id; int maxSpeed; }
class Car implements Vehicle { int doors; int id; int maxSpeed; }
class Boat implements Vehicle { int buoyancy; int id; int maxSpeed; }
class Plane implements Vehicle { int wingSpan; int id; int maxSpeed; }

interface VehicleRepository<T extends Vehicle> {
    T getFastest();
    T getSlowest();
    T getById(int id);
}

interface CarRepository inherits VehicleRepository<Car> {
    List<Car> getCarsWithTwoDoors();
}

interface BoatRepository inherits VehicleRepository<Boat> {
    Boat getMostBuoyantBoat();
}

interface PlaneRepository inherits VehicleRepository<Plane> {
    List<Plane> getPlanesByWingspan();
}
2
ответ дан 6 December 2019 в 07:50
поделиться

Похоже, это работа для шаблона "Посетитель". У вас есть коллекция абстрактных объектов, и вы не знаете, что это за каждый из них. Используя Visitor, вы можете перебирать все объекты и выполнять действие, специфичное для каждого из них. В книге «Шаблоны GOF» подробно описан шаблон «Посетитель», но я постараюсь привести здесь хороший пример Java.

public class Vehicle {
    public void accept( VehicleVisitor visitor ) {
        visitor.visit( this );
    }
}

public interface VehicleVisitor {
    public void visit( Vehicle vehicle );
    public void visit( Car car );
    public void visit( Bus bus );
    public void visit( Truck truck );
    // Augment this interface each time you add a new subclass.
}

public class Car extends Vehicle {
    public void accept( VehicleVisitor visitor ) {
        visitor.visit( this );
    }
}

public class Bus extends Vehicle {
    public void accept( VehicleVisitor visitor ) {
        visitor.visit( this );
    }
}

public class Truck extends Vehicle {
    public void accept( VehicleVisitor visitor ) {
        visitor.visit( this );
    }
}

public class VehicleSearch implements VehicleVisitor {
    protected String name;
    public List<Vehicle> foundList =
        new ArrayList<Vehicle>();
    public VehicleSearch( String name ) {
        this.name = name;
    }
    public void visit( Vehicle vehicle ) {
        return;
    }
    public void visit( Car car ) {
        if ( car.getModel().contains( name ) ) {
            foundList.add( car );
        }
    }
    public void visit( Bus bus ) {
        if ( bus.getManufacturerModel().contains( name ) ) {
            foundList.add( bus );
        }
    }
    public void visit( Truck truck ) {
        if ( truck.getLineModel().contains( name ) ) {
            foundList.add( truck );
        }
    }
}

public class Manager {
    protected List<Vehicle> vehicleList;
    public List<Vehicle> search( String name ) {
        VehicleSearch visitor =
            new VehicleSearch( name );
        for ( Vehicle vehicle : vehicleList ) {
            vehicle.accept( visitor );
        }
        return visitor.foundList;
    }
}

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

Однако один недостаток шаблона Visitor , заключается в том, что при добавлении нового класса посещаемого объекта необходимо изменить самого посетителя. В этом примере если вы добавляете в систему транспортное средство RocketShip, вам нужно будет добавить посетителю метод visit (RocketShip rocketShip) .

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

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

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

2
ответ дан 6 December 2019 в 07:50
поделиться

Звучит как пример использования шаблона спецификации.

http://en.wikipedia.org/wiki/Specification_pattern

http://devlicio.us/blogs/ casey / archive / 2009/03/02 / ddd-the-спецификация-pattern.aspx

Удачи!

0
ответ дан 6 December 2019 в 07:50
поделиться

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

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

Или я бы попытался использовать средства RTTI C ++ или функция Python instanceof () .

Помогает ли это, или я отвечаю не на тот вопрос?

0
ответ дан 6 December 2019 в 07:50
поделиться

I don't see what language you're using, but why not have the abstract class implement the interface? That way, it won't matter how many concrete classes you have as long as they all inherit from the abstract class, which implements the interface.

Here's how the hierarchy would look if you are using Java:

public interface IVehicle {/*your code goes here*/}

public abstract class AbstractVehicle implements IVehicle{/*your code goes here*/}

public class Car extends AbstractVehicle{/*your code goes here*/}

These would all, of course, be defined in different files.

0
ответ дан 6 December 2019 в 07:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: