DECORATOR
The Decorator pattern is a structural design that allows you to improve or change the behavior of objects at runtime. This is done by creating a set of decoration classes used to wrap the components. Each decorator adds a specific functionality or behavior to the component, and you can stack multiple decorators to create various combinations. In this section we implement the model under spring.
Implementing the Decorator Pattern in Spring
Let’s illustrate the Decorator pattern with a fun example about a user with various roles who can create a practice, but by role type you can create different practices with specific rules. We’ll start with a simple explanation.
Overall, the hierarchy of classes that have been implemented therefore becomes the one shown in the following figure.

Step 1: Create the Interface
// Interface
interface IPracticesService {
PraticeValidDTO validPractice (PracticeDTO praticaDTO);
PracticeDTO updatePractice (PracticeDTO praticaDTO);
void archivePractice (Long idPractice);
void cancelPractice (Long idPractice);
PracticeDTO saveDraft (PracticeDTO practiceDTO);
void saveStatusPractice (Long idPractice, String statusPractice);
Boolean deleteDraft (Long id);
void revocationPractice (RevocationPracticeDTO revocationPracticeDTO);
List<SearchPracticeResponseDTO> searchPractices (SearchPracticeRequestDTO searchPracticeRequestDTO);
}
Step 2: Implement the Concrete Service
// Concrete Service
@service ("ciPracticeBaseService")
public class CIPracticeBaseService implements IPracticesService {
@Override
public PraticeValidDTO validPractice(PracticeDTO praticaDTO) {
//logic to validate practice
System.out.println("Call validPractice of ciPracticeBaseService");
return new PraticeValidDTO();
}
@Override
public PracticeDTO updatePractice(PracticeDTO praticaDTO) {
// logic to update practice
System.out.println("Call updatePractice of ciPracticeBaseService");
return new PracticeDTO();
}
@Override
public void archivePractice(Long idPractice) {
System.out.println("Call archivePractice of ciPracticeBaseService");
}
}
Step 3: Develop the Decorator
// Decorator
@Service("ciPracticeBaseDecoratorService")
public class CIPracticeBaseDecoratorService implements IPracticesService {
protected IPracticesService ciWrapperService;
public CIPracticeBaseDecoratorService(@Qualifier("ciPracticeBaseService") IPracticesService ciPracticeService) {
ciWrapperService = ciPracticeService;
}
@Override
public PraticeValidDTO validPractice(PracticeDTO praticaDTO) {
return ciWrapperService.validPractice(praticaDTO);
}
@Override
public PracticeDTO updatePractice(PracticeDTO praticaDTO) {
return ciWrapperService.updatePractice(praticaDTO);
}
}
Step 4: Create Concrete Decorators for user for every role
// Concrete Decorators
@Service("ciCompanyDecoratorService")
public class CICompanyDecoratorService extends CIPracticeBaseDecoratorService {
public CICompanyDecoratorService(@Qualifier("ciPracticeBaseDecoratorService") IPracticesService ciPracticeService) {
super(ciPracticeService);
}
@Override
public PraticeValidDTO validPractice(PracticeDTO praticaDTO) {
return super.validPractice(praticaDTO);
}
@Override
public PracticeDTO updatePractice(PracticeDTO praticaDTO) {
System.out.println("Call updatePractice of ciCompanyDecoratorService");
return new PracticeDTO();
}
@Override
public void archivePractice(Long idPractice) {
super.archivePractice(idPractice);
}
.
.
}
@Service("ciIntermDecoratorService")
public class CIIntermDecoratorService extends CIPracticeBaseDecoratorService {
public CIIntermDecoratorService(@Qualifier("ciPracticeBaseDecoratorService") IPracticesService ciPracticeService) {
super(ciPracticeService);
}
@Override
public PraticeValidDTO validPractice(PracticeDTO praticaDTO) {
return super.validPractice(praticaDTO);
}
@Override
public PracticeDTO updatePractice(PracticeDTO praticaDTO) {
System.out.println("Call updatePractice of ciIntermDecoratorService");
return new PracticeDTO();
}
@Override
public void archivePractice(Long idPractice) {
System.out.println("Call archivePractice of ciIntermDecoratorService");
}
}
Step 5: Using the Decorators
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
@Autowired
private PracticeFactory factory;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
IPracticesService serviceFactory = factory.getService(EnumUser.COMPANY);
System.out.println("User to call function company");
serviceFactory.validPractice(new PracticeDTO());
serviceFactory.updatePractice(new PracticeDTO());
serviceFactory.saveDraft(new PracticeDTO());
serviceFactory.saveStatusPractice(Long.getLong("123456"), "ACTIVE");
System.out.println("");
System.out.println("User to call function intermediary");
serviceFactory = factory.getService(EnumUser.INTERMEDIARY);
serviceFactory.validPractice(new PracticeDTO());
serviceFactory.updatePractice(new PracticeDTO());
serviceFactory.saveDraft(new PracticeDTO());
serviceFactory.saveStatusPractice(Long.getLong("123456"), "NO ACTIVE");
System.out.println("");
System.out.println("User to call function regional");
serviceFactory = factory.getService(EnumUser.REGIONAL);
serviceFactory.validPractice(new PracticeDTO());
serviceFactory.updatePractice(new PracticeDTO());
serviceFactory.saveDraft(new PracticeDTO());
serviceFactory.saveStatusPractice(Long.getLong("123456"), "ENDED");
System.out.println("");
}
}
In this example, we have a Practice interface, a CIPracticeBaseService concrete service, and decorator: CICompanyDecoratorService. These decorator extend for user with different role other decoretors for CICompanyDecoratorService, CIIntermDecoratorService and CIRegDecoratorService class.
Conclusion
The Decorator model is a versatile tool for building flexible and extensible systems. It allows you to dynamically improve the behavior of objects, making your code more maintainable and adaptable to different needs. Using this model you can create various combinations with complex functionality without the need for a convoluted class hierarchy. Here you can found code example.






