Ответ 1
Используйте композицию. Чтобы сделать вещи проще и чище, не реплицируйте все атрибуты в классе источника (Foo
) и строителя (Builder
).
Например, у меня есть Foo
class внутри Builder
вместо каждого из атрибутов Foo
.
простой фрагмент кода:
import java.util.*;
class UserBasicInfo{
String nickName;
String birthDate;
String gender;
public UserBasicInfo(String name,String date,String gender){
this.nickName = name;
this.birthDate = date;
this.gender = gender;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("Name:DOB:Gender:").append(nickName).append(":").append(birthDate).append(":").
append(gender);
return sb.toString();
}
}
class ContactInfo{
String eMail;
String mobileHome;
String mobileWork;
public ContactInfo(String mail, String homeNo, String mobileOff){
this.eMail = mail;
this.mobileHome = homeNo;
this.mobileWork = mobileOff;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("email:mobile(H):mobile(W):").append(eMail).append(":").append(mobileHome).append(":").append(mobileWork);
return sb.toString();
}
}
class FaceBookUser {
String userName;
UserBasicInfo userInfo;
ContactInfo contactInfo;
public FaceBookUser(String uName){
this.userName = uName;
}
public void setUserBasicInfo(UserBasicInfo info){
this.userInfo = info;
}
public void setContactInfo(ContactInfo info){
this.contactInfo = info;
}
public String getUserName(){
return userName;
}
public UserBasicInfo getUserBasicInfo(){
return userInfo;
}
public ContactInfo getContactInfo(){
return contactInfo;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("|User|").append(userName).append("|UserInfo|").append(userInfo).append("|ContactInfo|").append(contactInfo);
return sb.toString();
}
static class FaceBookUserBuilder{
FaceBookUser user;
public FaceBookUserBuilder(String userName){
this.user = new FaceBookUser(userName);
}
public FaceBookUserBuilder setUserBasicInfo(UserBasicInfo info){
user.setUserBasicInfo(info);
return this;
}
public FaceBookUserBuilder setContactInfo(ContactInfo info){
user.setContactInfo(info);
return this;
}
public FaceBookUser build(){
return user;
}
}
}
public class BuilderPattern{
public static void main(String args[]){
FaceBookUser fbUser1 = new FaceBookUser.FaceBookUserBuilder("Ravindra").build(); // Mandatory parameters
UserBasicInfo info = new UserBasicInfo("sunrise","25-May-1975","M");
// Build User name + Optional Basic Info
FaceBookUser fbUser2 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
setUserBasicInfo(info).build();
// Build User name + Optional Basic Info + Optional Contact Info
ContactInfo cInfo = new ContactInfo("[email protected]","1111111111","2222222222");
FaceBookUser fbUser3 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
setUserBasicInfo(info).
setContactInfo(cInfo).build();
System.out.println("Facebook user 1:"+fbUser1);
System.out.println("Facebook user 2:"+fbUser2);
System.out.println("Facebook user 3:"+fbUser3);
}
}
выход:
Facebook user 1:|User|Ravindra|UserInfo|null|ContactInfo|null
Facebook user 2:|User|Ravindra|UserInfo|Name:DOB:Gender:sunrise:25-May-1975:M|ContactInfo|null
Facebook user 3:|User|Ravindra|UserInfo|Name:DOB:Gender:sunrise:25-May-1975:M|ContactInfo|email:mobile(H):mobile(W):[email protected]:1111111111:2222222222
Пояснение:
-
FaceBookUser
- сложный объект с атрибутами ниже с использованием композиции:String userName; UserBasicInfo userInfo; ContactInfo contactInfo;
-
FaceBookUserBuilder
- это класс статического строителя, который содержит и строитFaceBookUser
. -
userName - это только обязательный параметр для создания FaceBookUser
-
FaceBookUserBuilder
строитFaceBookUser
, устанавливая необязательные параметры:UserBasicInfo
иContactInfo
-
В этом примере показаны три разных
FaceBookUsers
с разными атрибутами, построенными из Builder.- fbUser1 был создан как FaceBookUser только с атрибутом userName
- fbUser2 был создан как FaceBookUser с именем пользователя и UserBasicInfo
- fbUser3 был создан как FaceBookUser с именем пользователя, UserBasicInfo и ContactInfo
В этом примере композиция использовалась вместо дублирования всех атрибутов FaceBookUser в классе Builder.
EDIT:
Группировать все связанные атрибуты в логические классы. Определите все эти классы в FaceBookUser. Вместо добавления всех этих переменных-членов в Builder
, введите FaceBookUser
в классе Builder
.
Для простоты я добавил два класса: UserBasicInfo и ContactInfo. Теперь взорвите этот класс FaceBookUser с другими атрибутами, например
NewsFeed
Messages
Friends
Albums
Events
Games
Pages
Ads
и др.
Если вы дублируете все эти атрибуты как в Builder
, так и в FaceBookUser
, код будет трудно справиться. Вместо этого, используя композицию FaceBookUser
в FaceBookUserBuilder
, вы можете просто построить процесс.
После добавления выше атрибутов вы будете строить FaceBookUser
в пошаговом процессе, как обычно.
Это будет так:
FaceBookUser fbUser3 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
setUserBasicInfo(info).
setNewsFeed(newsFeed).
setMessages(messages).
setFriends(friends).
setAlbums(albums).
setEvents(events).
setGames(games).
setAds(ads).build();