Возникает, когда один модуль полагается на внутренние особенности реализации другого модуля.
public class ShopService {
public void addNewItem(Order order, OrderItem newItem) {
order.getItems().add(newItem);
order.setSum(order.getSum() + newItem.getPrice());
}
}
public class ShopService {
public void addNewItem(Order order, OrderItem newItem) {
order.addItem(newItem);
}
}
Объект должен иметь как можно меньше представления о структуре и свойствах другого объекта.
Возникает между модулями, когда они работают с общими данными читая и изменяя их.
Возникает, когда один модуль управляет поведением другого, через передачу каких-то данных или флагов управления.
class OrderService {
private ReportService reportService;
public void placeOrder() {
// ...
reportService.generate(order, ReportType.PDF);
}
}
class ReportService {
public void generate(Order data, ReportType type) {
switch (type) {
case XML:
buildXmlReport(data);
break;
case PDF:
buildPdfReport(data);
break;
}
}
private void buildXmlReport() { ... }
private void buildPdfReport() { ... }
}
class OrderService {
private ReportService reportService;
public void placeOrder() {
// ...
reportService.generate(order);
}
}
public interface ReportService {
void generate(Order order);
}
public class XmlReportBuilder implements ReportService { }
public class PdfReportBuilder implements ReportService { }
Возникает, когда модули обмениваются друг с другом данными через структуру, но при этом из этой структуры модули используют не все поля.
class ValidatorService {
public boolean validateEmail(Customer customer) {
var email = customer.getEmail();
return EMAIL_REGEX.matcher(email).find();
}
}
class Customer {
private String firstName;
private String lastName;
private LocalDate birthDate;
private String livingAddress;
private String email;
}
class ValidatorService {
public boolean validateEmail(String email) {
return EMAIL_REGEX.matcher(email).find();
}
}
Возникает, когда модули обмениваются друг с другом данными через структуру, при этом используется каждое поле в этой структуре.
Модули общаются только через передачу сообщений или вызовы методов без параметров.
Слабейший из видов сочетаемости. Когда элементы внутри модуля собраны по случайному принципу и никак друг с другом не связаны.
Логическая сочетаемость возникает, когда части модуля логически делают похожие вещи, но никак друг с другом не связаны с точки зрения бизнес смысла.
📁 dao 📁 service 📁 model ☕ Application.java
📁 dao ☕ OrderDao.java ☕ UserDao.java ☕ PostDao.java 📁 service ☕ OrderService.java ☕ UserService.java 📁 model ☕ User.java ☕ Order.java ☕ OrderItem.java ☕ OrderState.java ☕ Comment.java ☕ Post.java ☕ Application.java
📁 orders ☕ Order.java ☕ OrderItem.java ☕ OrderState.java ☕ OrderDao.java ☕ OrderService.java 📁 users ☕ User.java ☕ UserDao.java ☕ UserService.java 📁 reviews ☕ Post.java ☕ Comment.java ☕ PostDao.java ☕ Application.java
public MessageSenderService {
public void sendOrderProcessedEvent() { ... }
public void sendReportMessage() { ... }
public void sendEmailNotification() { ... }
}
Элементы группируются в одном модуле, так как вызываются в одно время, но функционально никак друг с другом не связаны.
public interface ApplicationInitializer {
void initDatabase();
void initPrinterService();
void initFtpSerivce();
}
Функции все еще слабо связаны друг с другом, но используются в одном месте, при этом порядок вызова функций имеет значение.
public class RegistrationService {
public void registerUser(String email) {
validateEmail(email);
User user = createNewUser(email);
loadProfileFromFacebook(user);
checkVipStatus(user);
sendGreetings(email, user.getName());
}
}
public interface UserService {
void validateEmail(String email);
User createNewUser(String email);
void loadProfileFromFacebook(User user);
void checkVipStatus(User user);
void sendGreetings(String email, String name);
}
Сочетаемость по последовательности действий возникает в случае если результат работы одной части модуля является исходными данными для другой.
public class RegistrationService {
public void registerUser(String emailStr) {
Email email = validateEmail(emailStr);
User user = createNewUser(email);
UserProfile profile = loadProfileFromFacebook(user);
VipStatus vipStatus = checkVipStatus(user);
sendGreetings(profile, vipStatus);
}
}
public interface UserService {
Email validateEmail(String email);
User createNewUser(Email email);
UserProfile loadProfileFromFacebook(User user);
VipStatus checkVipStatus(User user);
void sendGreetings(UserProfile profile, VipStatus vipStatus);
}
Сочетаемость по взаимодействию возникает, когда группируется в один модуль все функции, которые работают с одними и теми же входными или выходными данными.
interface OrderService {
public void addItem(Order order, Item item);
public void deleteAllItems(Order order);
public Money calculateTotalSum(Order order);
public void startDelivery(Order order);
}
interface ComputerFactory {
public Computer newServer(Integer ram, Integer hdd, Integer cpu);
public Computer newPc(Monitor monitor, Mouse mouse, SystemUnit unit);
public Computer newNotebook(Model model);
}
class User {
private Long id;
private Image avatar;
private String email;
private List<Orders> orders;
private List<Review> reviews;
public void changeAvatar(Image image) { ... }
public void resetPassword() { ... }
public void placeNewOrder(Order order) { ... }
public void postReview(Review review) { ... }
public void assignVipStatus() { ... }
}
Возникает, когда элементы модуля сгруппированы вместе, так как все они вносят вклад в выполнение одной и той же функции.
interface OrderService {
public void addItem(Order order, Item item);
public void deleteAllItems(Order order);
public Money calculateTotalSum(Order order);
public void startDelivery(Order order);
}
interface OrderCart {
public void addItem(Order order, Item item);
public void deleteAllItems(Order order);
}
interface OrderCostCalculator {
public Money calculateTotalSum(Order order);
}
interface OrderDelivery {
public void startDelivery(Order order);
}
Модули, которые следуют принципам слабой связанности и высокой сочетаемости, обладают следующими свойствами:
Design is About Balancing Cohesion and Coupling (not blindly following principles) – Copeland