Tuesday, 17 June 2014

Несколько слов о паттернах в Java EE

Начал читать недавно одну книгу о паттернах в Java EE, как они изменились и "как нынче стоит составлять дизайн"! Хочу отметить что нынче паттерны звучат банально, на них не стоит утыкаться и зацикливаться как некоторые авторы этого негласно требуют, можно просто следовать обще принятым принципам таким как например, DRY (Do not repeat yourself), инкапсуляция, разделение обязанностей, в общем все то что ведет нас к выгодной позиции.

Анемическая модель доменов - раскритикована как ни знаю что. Тем не менее она проста и удобна. На мой взгляд, втыкать туда вспомогательные методы к примеру относящиеся только к этой сущности и ее дочерним коллекциям, и не определяя зависимости к внешним факторам а также принимая во внимание что поведение этих методов-аксессуаров возможно таким и останется - это нормально. Ограничимся этим. Выполнять там имплементацию Builder уже сомнительно, уже теряется простота, но все же можно если там нет бизнес логики. EnttyManager к сущности отношение не имеет, ему там сидеть тем более ни к чему. Анемическая модель после этого или нет - это не важно. Главное удобно и сущность не теряет своей эластичности. Сущность часто сильно зависит по своим свойствам от модели БД (трогать которую иногда нельзя), они сами по себе носят не самый доступный характер, но это значит только то что при возможности внося новшество JPA в систему нужно стремиться к упрощению.
К примеру, тут итак модель запутанна, добавлять туда бизнес логику не всегда разумно в особенности если она диктует порядок сохранения, и ее можно оставить за пределами сущности:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorValue("PFH.POINTABLE_SMBLOCK_TYPE")
public class GterPointableSmBlock extends GterSmall {

 @ManyToOne
 @JoinColumn(name="SMBLOCK_TYPE_ID_1")
 private PointableSmBlockType editableSmBlockType1;
 
 @ManyToOne
 @JoinColumn(name="SMBLOCK_TYPE_ID_2")
 private PointableSmBlockType editableSmBlockType2;
 
 @Column(name="ACTIVE")
 private int activeInd;
 
 @Column(name="AUDIT")
 private int auditNum;
 
 @Column(name="ROWSUID")
 private String rowId;
 
 @Column(name="CATSUID")
 private String cater;

Простенькие модельки, часто просто не в чем ином не нуждаются:

 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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
@Entity
public class User {
 
 @Id
 @GeneratedValue(strategy=GenerationType.AUTO)
 private long id;
 
 private String username;
 
 private String first;
 
 private String last;

 public long getId() {
  return id;
 }

 public void setId(long id) {
  this.id = id;
 }

 public String getUsername() {
  return username;
 }

 public void setUsername(String username) {
  this.username = username;
 }

 public String getFirst() {
  return first;
 }

 public void setFirst(String first) {
  this.first = first;
 }

 public String getLast() {
  return last;
 }

 public void setLast(String last) {
  this.last = last;
 }

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((first == null) ? 0 : first.hashCode());
  result = prime * result + ((last == null) ? 0 : last.hashCode());
  result = prime * result
    + ((username == null) ? 0 : username.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  User other = (User) obj;
  if (first == null) {
   if (other.first != null)
    return false;
  } else if (!first.equals(other.first))
   return false;
  if (last == null) {
   if (other.last != null)
    return false;
  } else if (!last.equals(other.last))
   return false;
  if (username == null) {
   if (other.username != null)
    return false;
  } else if (!username.equals(other.username))
   return false;
  return true;
 }
 
 

}

Такие паттерны как Service Facade, Service, вообще в принципе не несут сути в контексте Java EE. Сколько задач, столько и разновидностей, не может быть толкований на основе какой либо иной по мимо поставленной задачей производством и ее выполнения. Тем более о характеристиках таких как TransactionAttribute. Все очень индивидуально, просто раньше технология J2EE несла кучу недоработок, в обход которым были созданы продукты прогресса такие как DI (Dependency Injection), упрощенные EJB и паттерны уже как таковые ни чего не значат. Девелопер уже может больше времени уделять разработке бизнес логики с использованием полиморфизма как метод элегантной обрисовки процесса и.т.д, нежели заниматься демагогией о паттернах в сфере EE.     

No comments:

Post a Comment