У меня учебный проект на Spring MVC
и я пытаюсь применить паттерн Chain of responsibility. Создал пакет handler
в котором есть интерфейс Handler
public interface Handler {
void setRelationship(Relationship relationship, User user, String status, Long userIdTo, Long idUserFrom)throws BadRequestException, InternalServerError;
}
Абстрактный класс
public abstract class RelationshipHandler implements Handler, Ordered {
public abstract void setRelationship(Relationship relationship, User user, String status, Long userIdTo, Long idUserFrom)throws BadRequestException, InternalServerError;
boolean checkStatusForChange(Relationship relationship, RelationshipStatusType currentStatus, RelationshipStatusType newStatus, String status){
return relationship != null && relationship.getStatusType().equals(currentStatus) && status.equals(newStatus.toString());
}
}
От которого наследуются четыре обработчика Первый
@Component
public class AcceptedHandler extends RelationshipHandler {
private final RelationshipDAO relationshipDAO;
@Autowired
public AcceptedHandler(RelationshipDAO relationshipDAO) {
this.relationshipDAO = relationshipDAO;
}
@Override
public void setRelationship(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom) throws BadRequestException, InternalServerError{
if (user != null && user.getId().equals(idUserTo) &&
checkStatusForChange(relationship, RelationshipStatusType.REQUESTED, RelationshipStatusType.ACCEPTED, status)){
relationshipDAO.update(addFriendsByRequest(user, relationship));
}
}
private Relationship addFriendsByRequest(User user, Relationship relationship) throws BadRequestException, InternalServerError {
if (user == null || relationship == null){
throw new BadRequestException("User or relationship is not found.");
}
if (checkingNumberFriends(user.getId())){
Date acceptedRequest = new Date();
relationship.setAcceptedFriends(acceptedRequest);
relationship.setStatusType(RelationshipStatusType.ACCEPTED);
}
else {
throw new BadRequestException("Friends limit exceeded.");
}
return relationship;
}
private boolean checkingNumberFriends(Long id) throws BadRequestException, InternalServerError {
if (id == null){
throw new BadRequestException("ID does not exist.");
}
return relationshipDAO.getQuantityFriends(id, RelationshipStatusType.ACCEPTED) < 10;
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
Второй
@Component
public class DeletedHandler extends RelationshipHandler {
private final RelationshipDAO relationshipDAO;
@Autowired
public DeletedHandler(RelationshipDAO relationshipDAO) {
this.relationshipDAO = relationshipDAO;
}
@Override
public void setRelationship(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom) throws BadRequestException, InternalServerError {
if (user != null && (user.getId().equals(idUserFrom) || user.getId().equals(idUserTo)) &&
checkStatusForChange(relationship, RelationshipStatusType.ACCEPTED, RelationshipStatusType.DELETED, status)){
relationshipDAO.update(delFromFriends(idUserFrom, idUserTo, relationship));
}
}
private Relationship delFromFriends(Long idUserFrom, Long idUserTo, Relationship relationship) throws BadRequestException, InternalServerError {
if (idUserFrom == null || idUserTo == null || relationship == null){
throw new BadRequestException("IdUserFrom or idUserTo or relationship is not found.");
}
if (checkingAcceptedDate(idUserFrom, idUserTo)){
relationship.setStatusType(RelationshipStatusType.DELETED);
relationship.setAcceptedFriends(null);
}
else {
throw new BadRequestException("You can not perform an action delete from friends.");
}
return relationship;
}
private boolean checkingAcceptedDate(Long idUserFrom, Long idUserTo) throws BadRequestException, InternalServerError{
if (idUserFrom == null || idUserTo == null){
throw new BadRequestException("IdUserFrom or idUserTo is not found.");
}
return relationshipDAO.getQuantityHoursAfterAccepted(idUserFrom, idUserTo, RelationshipStatusType.ACCEPTED) >= 3;
}
@Override
public int getOrder() {
return 2;
}
}
Третий
@Component
public class CanceledHandler extends RelationshipHandler {
private final RelationshipDAO relationshipDAO;
@Autowired
public CanceledHandler(RelationshipDAO relationshipDAO) {
this.relationshipDAO = relationshipDAO;
}
@Override
public void setRelationship(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom) throws BadRequestException, InternalServerError {
if (user != null && user.getId().equals(idUserFrom) &&
checkStatusForChange(relationship, RelationshipStatusType.REQUESTED, RelationshipStatusType.CANCELED, status)){
relationship.setStatusType(RelationshipStatusType.CANCELED);
relationshipDAO.update(relationship);
}
}
@Override
public int getOrder() {
return 3;
}
}
И четвертый
@Component
public class DeclinedHandler extends RelationshipHandler {
private final RelationshipDAO relationshipDAO;
@Autowired
public DeclinedHandler(RelationshipDAO relationshipDAO) {
this.relationshipDAO = relationshipDAO;
}
@Override
public void setRelationship(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom) throws BadRequestException, InternalServerError {
if (user != null && user.getId().equals(idUserTo) &&
checkStatusForChange(relationship, RelationshipStatusType.REQUESTED, RelationshipStatusType.DECLINED, status)) {
relationship.setStatusType(RelationshipStatusType.DECLINED);
relationshipDAO.update(relationship);
}
}
@Override
public int getOrder() {
return 1;
}
}
Класс в котором строю цепочку
@Component
public class HandlerForUser {
@Autowired
private List<Handler> handlers;
@PostConstruct
public void init(){
handlers.sort(INSTANCE);
}
public void execute(Relationship relationship, User user, String status, Long idUserTo, Long idUserFrom)throws BadRequestException, InternalServerError {
for (Handler handler : handlers){
handler.setRelationship(relationship, user, status, idUserTo, idUserFrom);
}
}
}
И использую это в сервисе:
@Service
public class RelationshipService {
private RelationshipDAO relationshipDAO;
private UserDAO userDAO;
private HandlerForUser handlerForUser;
@Autowired
public RelationshipService(RelationshipDAO relationshipDAO, UserDAO userDAO, HandlerForUser handlerForUser) {
this.relationshipDAO = relationshipDAO;
this.userDAO = userDAO;
this.handlerForUser = handlerForUser;
}
public void setRelationship(String userIdTo, String userIdFrom, HttpSession session)throws BadRequestException, InternalServerError{
User userFrom = (User) session.getAttribute(userIdFrom);
if (userFrom == null){
throw new BadRequestException("User with ID " + userIdFrom + " is not logged in.");
}
User userTo = userDAO.findById(Long.parseLong(userIdTo));
if (userTo == null){
throw new BadRequestException("User with ID " + userIdTo + " is not found in DB.");
}
Relationship relationshipFind = relationshipDAO.getRelationship(userFrom.getId(), userTo.getId());
try {
if (relationshipFind == null){
Relationship relationship = new Relationship();
relationship.setUserFrom(userFrom);
relationship.setUserTo(userTo);
relationship.setStatusType(RelationshipStatusType.REQUESTED);
save(sendRequest(Long.parseLong(userIdFrom), relationship));
}
else if (relationshipFind.getStatusType().equals(RelationshipStatusType.CANCELED) ||
relationshipFind.getStatusType().equals(RelationshipStatusType.DECLINED) ||
relationshipFind.getStatusType().equals(RelationshipStatusType.DELETED)){
relationshipFind.setStatusType(RelationshipStatusType.REQUESTED);
relationshipDAO.update(sendRequest(Long.valueOf(userIdFrom), relationshipFind));
}
else {
throw new BadRequestException("Something is wrong with the input.");
}
}catch (InternalServerError e) {
throw new InternalServerError("Something went wrong...");
}
}
public void setRelationshipByStatus(String status, String userIdTo, String userIdFrom, HttpSession session) throws BadRequestException, InternalServerError {
if (status == null || userIdTo == null || userIdFrom == null){
throw new BadRequestException("Status or userIdTo or userIdFrom is not exist.");
}
User userFrom = (User) session.getAttribute(userIdFrom);
User userTo = (User) session.getAttribute(userIdTo);
Relationship relationshipFind = relationshipDAO.getRelationship(Long.valueOf(userIdFrom), Long.valueOf(userIdTo));
try {
if (userTo != null){
handlerForUser.execute(relationshipFind, userTo, status, Long.valueOf(userIdTo), Long.valueOf(userIdFrom));
}
if (userFrom != null){
handlerForUser.execute(relationshipFind, userFrom, status, Long.valueOf(userIdTo), Long.valueOf(userIdFrom));
}
else {
throw new BadRequestException("Something is wrong with the input. Method setRelationshipByStatus");
}
}catch (InternalServerError e) {
throw new InternalServerError("Something went wrong...");
}
}
public void validationInputData(String idUserFrom, String idUserTo, HttpSession session)throws BadRequestException{
if (idUserFrom == null || idUserTo == null){
throw new BadRequestException("UserFrom or userTo does not exist.");
}
if (idUserFrom.equals(idUserTo)){
throw new BadRequestException("Actions between the same user are not possible.");
}
if (session == null){
throw new BadRequestException("Session is not exist.");
}
}
private Relationship save(Relationship relationship)throws BadRequestException {
if (relationship != null && relationship.getId() != null){
throw new BadRequestException("This Relationship with ID - " + relationship.getId() + " can not save in DB.");
}
else {
relationshipDAO.save(relationship);
}
return relationship;
}
private Relationship sendRequest(Long idUser, Relationship relationship) throws BadRequestException, InternalServerError {
if (idUser == null || relationship == null){
throw new BadRequestException("User or relationship is not found.");
}
if (checkingNumberRequested(idUser)){
relationship.setStatusType(RelationshipStatusType.REQUESTED);
}
else {
throw new BadRequestException("Limit on sent requests exceeded.");
}
return relationship;
}
private boolean checkingNumberRequested(Long id) throws BadRequestException, InternalServerError{
if (id == null){
throw new BadRequestException("ID does not exist.");
}
return relationshipDAO.getQuantityRequests(id, RelationshipStatusType.REQUESTED) < 10;
}
}
Сейчас получается, что запрос проходит по всему списку обработчиков не прерывая цепочку если запрос обработался успешно. Может я структуру построил не правильно. Наверное в абстрактном классе надо задать поведение для передачи ссылки на следующий обработчик. Что-то ни как не соображу, что делать дальше... Помогите разобраться, как правильно построить цепочку
Я отказался от использования списка. Реализовал построение цепочки через передачу ссылок от одного обработчика другому. Теперь класс, в котором создается цепочка обязанностей выглядит вот так:
@Component
public class HandlerChain {
private Handler chain;
public HandlerChain(RelationshipDAO relationshipDAO){
this.chain = new AcceptedHandler(relationshipDAO);
Handler declinedHandlerObj = new DeclinedHandler(relationshipDAO);
Handler canceledHandlerObj = new CanceledHandler(relationshipDAO);
Handler deletedHandlerObj = new DeletedHandler(relationshipDAO);
chain.setNextHandler(declinedHandlerObj);
declinedHandlerObj.setNextHandler(canceledHandlerObj);
canceledHandlerObj.setNextHandler(deletedHandlerObj);
}
public void execute(Relationship relationship, User user, String status, Long userIdTo, Long idUserFrom)throws BadRequestException, InternalServerError{
chain.setRelationship(relationship, user, status, userIdTo, idUserFrom);
}
}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
У меня есть класс AppealTemlate, который содержит список сущностей extends AbstractFieldВыглядит это примерно так:
Как удалить все строки в текстовом файле, начинающиеся с определенного символа?