Big class decomposition in Java

I have just started to learn Java and is curious is it any good practice in Java for good object decomposition? Let me describe a problem. In big software project it's always a big classes like 'core' or 'ui' that tends to have a lot of methods and are intended as a mediators between smaller classes. For example, if user clicks a button on some window, this window's class sends a message to 'ui' class. This 'ui' class catches this message and acts accordingly by doing something with application user interface ( via calling method of one of it's member objects ) or by posting message to application 'core' if it's something like 'exit application' or 'start network connection'.

Such objects is very hard to break apart since they are a mere mediators between a lots of small application objects. But having a classes in application with hundreds and thousands of methods is not very handy, event if such methods are trivial task delegation from one object to another. C# solves such problem by allowing to break class implementation into multiple source files: you can divide god object any way you choose, and it will work.

Any practices by dividing such objects in Java?


====================================

One way to begin breaking such a large object apart is to first find a good subset of fields or properties managed by the large object that are related to each other and that don't interact with other fields or properties of the object. Then, create a new, smaller object using only those fields. That is, move all logic from the large class to the new smaller class. In the original large class, create a delegation method that simply passes the request along. This is a good first step that only involves changing the big object. It doesn't reduce the number of methods, but it can greatly reduce the amount of logic needed in the large class.

After a few rounds of doing this, you can begin to remove some of the delegation by pointing other objects directly at the newer, smaller objects, rather than going through the previously-huge object that was in the middle of everything.

See Wikipedia's Delegation pattern discussion for example.

As a simple example, if you have a personnel object to represent staff at a company, then you could create a payroll object to keep track of payroll-related values, a ratings object to keep track of employee ratings, an awards object to keep track of awards that the person has won, and so on.

To wit, if you started out with one big class containing the following methods, each containing business logic, among many other methods:

... public boolean isManagement() { ... } public boolean isExecutive() { ... } public int getYearsOfService() { ... } public Date getHireDate() { ... } public int getDepartment() { ... } public BigDecimal getBasePay() { ... } public BigDecimal getStockShares() { ... } public boolean hasStockSharePlan() { ... } ...

then this big object could, in its constructor, create a newly created objectStaffTypeand a newly created objectPayInformationand a newly created objectStaffInformation, and initially these methods in the big object would look like:

// Newly added variables, initialized in the constructor (or as appropriate) private final StaffType staffType; private final PayInformation payInformation; private final PayInformation payInformation; ... public boolean isManagement() { return staffType.isManagement(); } public boolean isExecutive() { return staffType.isExecutive(); } public int getYearsOfService() { return staffInformation.getYearsOfService(); } public Date getHireDate() { return staffInformation.getHireDate(); } public int getDepartment() { return staffInformation.getDepartment(); } public BigDecimal getBasePay() { return payInformation.getBasePay(); } public BigDecimal getStockShares() { return payInformation.getStockShares(); } public boolean hasStockSharePlan() { return payInformation.hasStockSharePlan(); } ...

where the full logic that used to be in the big object has been moved to these three new smaller objects. With this change, you can break the big object into smaller parts without having to touch anything that makes use of the big object. However, as you do this over time, you'll find that some clients of the big object may only need access to one of the divisible components. For these clients, instead of them using the big object and delegating to the specific object, they can make direct use of the small object. But even if this refactoring never occurs, you've improved things by separating the business logic of unrelated items into different classes.

你可能感兴趣的:(Big class decomposition in Java)