Middle Man
Description (What)
Middle Man is a class whose sole purpose in existence is to act as an intermediary between two other classes.
How to Locate It (Where)
Look at classes that simply act as a gateway for data to passed between two other classes. Classes that do only delegation work of moving data are generally considered as Middle Mans. Remember that a Middle Man doesn't do anything more than this. If a class looks like a Middle Man but also performs actual work on the data itself like processing, cleaning, converting, it is not a Middle Man.
How It Manifests (Why)
Trying to minimize the Message Chains code smell might end up bringing about this code smell.
It can also occur due to the slow removal of functions of a class to the point where it only delegates work at one stage.
How to Fix It (Possible Treatments)
In Example 1, Remove Middle Man treatment is used which simply means deleting the class that acts as a middle man and rerouting method calls directly to the main class which the middle man was acting as a facade for.
Example 2 is an ignoring case, please see When to Igonore on the page below.
Other treatments are also possible based on the specific scenario, they can be found here
Examples
Example 1
Before:
ProductHandler acts as a middleman to ProductManager by giving it access to only what it needs.
Observed Code Smells:
- Middle Man (lines 55-66)
- Data Class (line 55-66)
After:
Used Remove Middle Man by removing ProductHandler and letting ProductManager directly use Product methods
Refactoring Applied:
- Middle Man
- Remove Middle Man (removed ProductHandler)
Observed Code Smells After Refactoring:
- None
Example 2
Before:
The class LucyChart is a proxy to gate keeping all the original servicing objects: Draw, Move and Resize.
The class LucyChart is doing little other than delegating all the works to other classes.
The class LucyChart is a 'middle man' in this case.
Observed Code Smells:
- Middle Man (line 60-91)
- In this case, the coding follows the proxy pattern, where the 'middle man' code smell can be ignored.
When to Ignore
In cases where a design pattern like the Proxy or Decorator Design Patterns are used
In cases where adding a middle man removes unnecessary interdependence between two classes
More
- Example 1
- Example 2
- Before
- After
001 import java.util.HashMap;002 import java.util.Map;003004 class Product {005 private String name;006 private String type;007 private int stock;008009 public Product(String name, String type, int stock) {010 this.name = name;011 this.type = type;012 this.stock = stock;013 }014015 public String getName() {016 return name;017 }018019 public String getType() {020 return type;021 }022023 public int getStock() {024 return this.stock;025 }026027 public void reduceStock() {028 this.stock -= 1;029 }030031 }032033 class ProductHandler {034 private Product product;035 private int id;036037 public ProductHandler(Product product, int id) {038 this.product = product;039 this.id = id;040 }041042 public int getStock() {043 return this.product.getStock();044 }045046 public String getProductName() {047 return this.product.getName();048 }049050 public String getProductType() {051 return this.product.getType();052 }053054 public void reduceStock() {055 this.product.reduceStock();056 }057058 public void showDetails() {059 System.out.println("Product Name: " + this.product.getName());060 System.out.println("Product Type: " + this.product.getType());061 System.out.println("Stock: " + this.product.getStock());062 }063064 }065066 class ProductManager {067 Map<Integer, ProductHandler> productHandlers;068069 public ProductManager() {070 this.productHandlers = new HashMap<>();071 }072073 public void addProductHandler(int id, ProductHandler productHandler) {074 productHandlers.put(id, productHandler);075 }076077 public void removeProductHandler(int id) {078 productHandlers.remove(id);079 }080081 public void showTotalStock() {082 int totalStock = 0;083 for (ProductHandler productHandler : productHandlers.values()) {084 totalStock += productHandler.getStock();085 }086 System.out.println("Total Stock: " + totalStock);087 }088089 public void showAllDetails() {090 for (ProductHandler productHandler : productHandlers.values()) {091 productHandler.showDetails();092 }093 }094095 }096097 public class MMBE1 {098099 public static void main(String[] args) {100 Product redsoxcap = new Product("Baseball Cap", "Hat", 10);101 ProductHandler redsoxcapHandler = new ProductHandler(redsoxcap, 123);102103 Product stanley = new Product("Stanley Cup", "Mug", 15);104 ProductHandler stanleyHandler = new ProductHandler(stanley, 234);105106 ProductManager pm = new ProductManager();107 pm.addProduct(1, redsoxcapHandler);108 pm.addProduct(2, stanleyHandler);109110 pm.showTotalStock();111 redsoxcapHandler.reduceStock();112 pm.showTotalStock();113 }114115 }116