Does anyone know the best way to refactor a God-object?
Its not as simple as breaking it into a number of smaller classes, because there is a high method coupling. If I pull out one method, i usually end up pulling every other method out.
It's like Jenga. You will need patience and a steady hand, otherwise you have to recreate everything from scratch. Which is not bad, per se - sometimes one needs to throw away code.
Other advice:
Think before pulling out methods: on what data does this method operate? What responsibility does it have?
Try to maintain the interface of the god class at first and delegate calls to the new extracted classes. In the end the god class should be a pure facade without own logic. Then you can keep it for convenience or throw it away and start to use the new classes only
Unit Tests help: write tests for each method before extracting it to assure you don't break functionality
I assume "God Object" means a huge class (measured in lines of code).
The basic idea is to extract parts of its functions into other classes.
In order to find those you can look for
fields/parameters that often get used together. They might move together into a new class
methods (or parts of methods) that use only a small subset of the fields in the class, the might move into a class containing just those field.
primitive types (int, String, boolean). They often are really value objects before their coming out. Once they are value object, they often attract methods.
look at the usage of the god object. Are there different methods used by different clients? Those might go in separate interfaces. Those intefaces might in turn have separate implementations.
For actually doing these changes you should have some infrastructure and tools at your command:
Tests: Have a (possibly generated) exhaustive set of tests ready that you can run often. Be extremely careful with changes you do without tests. I do those, but limit them to things like extract method, which I can do completely with a single IDE action.
Version Control: You want to have a version control that allows you to commit every 2 minutes, without really slowing you down. SVN doesn't really work. Git does.
Mikado Method: The idea of the Mikado Method is to try a change. If it works great. If not take note what is breaking, add them as dependency to the change you started with. Rollback you changes. In the resulting graph, repeat the process with a node that has no dependencies yet. http://mikadomethod.wordpress.com/book/
According to the book "Object Oriented Metrics in Practice" by Lanza and Marinescu, The God Class design flaw refers to classes that tend to centralize the intelligence of the system. A God Class performs too much work on its own, delegating only minor details to a set of trivial classes and using the data from other classes.
The detection of a God Class is based on three main characteristics:
They heavily access data of other simpler classes, either directly or using accessor methods.
They are large and complex
They have a lot of non-communicative behavior i.e., there is a low
cohesion between the methods belonging to that class.
Refactoring a God Class is a complex task, as this disharmony is often a cumulative effect of other disharmonies that occur at the method level. Therefore, performing such a refactoring requires additional and more fine-grained information about the methods of the class, and sometimes even about its inheritance context. A first approach is to identify clusters of methods and attributes that are tied together and to extract these islands into separate classes.
Split Up God Class method from the book "Object-Oriented Reengineering Patterns" proposes to incrementally redistribute the responsibilities of the God Class either to its collaborating classes or to new classes that are pulled out of the God Class.
The book "Working Effectively with Legacy Code" presents some techniques such as Sprout Method, Sprout Class, Wrap Method to be able to test the legacy systems that can be used to support the refactoring of God Classes.
What I would do, is to sub-group methods in the God Class which utilize the same class properties as inputs or outputs. After that, I would split the class into sub-classes, where each sub-class will hold the methods in a sub-group, and the properties which these methods utilize.
That way, each new class will be smaller and more coherent (meaning that all their methods will work on similar class properties). Moreover, there will be less dependency for each new class we generated. After that, we can further reduce those dependencies since we can now understand the code better.
In general, I would say that there are a couple of different methods according to the situation at hand. As an example, let's say that you have a god class named "LoginManager" that validates user information, updates "OnlineUserService" so the user is added to the online user list, and returns login-specific data (such as Welcome screen and one time offers)to the client.
So your class will look something like this:
import java.util.ArrayList;
import java.util.List;
public class LoginManager {
public void handleLogin(String hashedUserId, String hashedUserPassword){
String userId = decryptHashedString(hashedUserId);
String userPassword = decryptHashedString(hashedUserPassword);
if(!validateUser(userId, userPassword)){ return; }
updateOnlineUserService(userId);
sendCustomizedLoginMessage(userId);
sendOneTimeOffer(userId);
}
public String decryptHashedString(String hashedString){
String userId = "";
//TODO Decrypt hashed string for 150 lines of code...
return userId;
}
public boolean validateUser(String userId, String userPassword){
//validate for 100 lines of code...
List<String> userIdList = getUserIdList();
if(!isUserIdValid(userId,userIdList)){return false;}
if(!isPasswordCorrect(userId,userPassword)){return false;}
return true;
}
private List<String> getUserIdList() {
List<String> userIdList = new ArrayList<>();
//TODO: Add implementation details
return userIdList;
}
private boolean isPasswordCorrect(String userId, String userPassword) {
boolean isValidated = false;
//TODO: Add implementation details
return isValidated;
}
private boolean isUserIdValid(String userId, List<String> userIdList) {
boolean isValidated = false;
//TODO: Add implementation details
return isValidated;
}
public void updateOnlineUserService(String userId){
//TODO updateOnlineUserService for 100 lines of code...
}
public void sendCustomizedLoginMessage(String userId){
//TODO sendCustomizedLoginMessage for 50 lines of code...
}
public void sendOneTimeOffer(String userId){
//TODO sendOneTimeOffer for 100 lines of code...
}}
Now we can see that this class will be huge and complex. It is not a God class by book definition yet, since class fields are commonly used among methods now. But for the sake of argument, we can treat it as a God class and start refactoring.
One of the solutions is to create separate small classes which are used as members in the main class. Another thing you could add, could be separating different behaviors in different interfaces and their respective classes. Hide implementation details in classes by making those methods "private". And use those interfaces in the main class to do its bidding.
So at the end, RefactoredLoginManager will look like this:
public class RefactoredLoginManager {
IDecryptHandler decryptHandler;
IValidateHandler validateHandler;
IOnlineUserServiceNotifier onlineUserServiceNotifier;
IClientDataSender clientDataSender;
public void handleLogin(String hashedUserId, String hashedUserPassword){
String userId = decryptHandler.decryptHashedString(hashedUserId);
String userPassword = decryptHandler.decryptHashedString(hashedUserPassword);
if(!validateHandler.validateUser(userId, userPassword)){ return; }
onlineUserServiceNotifier.updateOnlineUserService(userId);
clientDataSender.sendCustomizedLoginMessage(userId);
clientDataSender.sendOneTimeOffer(userId);
}
}
DecryptHandler:
public class DecryptHandler implements IDecryptHandler {
public String decryptHashedString(String hashedString){
String userId = "";
//TODO Decrypt hashed string for 150 lines of code...
return userId;
}
}
public interface IDecryptHandler {
String decryptHashedString(String hashedString);
}
ValidateHandler:
public class ValidateHandler implements IValidateHandler {
public boolean validateUser(String userId, String userPassword){
//validate for 100 lines of code...
List<String> userIdList = getUserIdList();
if(!isUserIdValid(userId,userIdList)){return false;}
if(!isPasswordCorrect(userId,userPassword)){return false;}
return true;
}
private List<String> getUserIdList() {
List<String> userIdList = new ArrayList<>();
//TODO: Add implementation details
return userIdList;
}
private boolean isPasswordCorrect(String userId, String userPassword)
{
boolean isValidated = false;
//TODO: Add implementation details
return isValidated;
}
private boolean isUserIdValid(String userId, List<String> userIdList)
{
boolean isValidated = false;
//TODO: Add implementation details
return isValidated;
}
}
Important thing to note here is that the interfaces () only has to include the methods used by other classes. So IValidateHandler looks as simple as this:
public interface IValidateHandler {
boolean validateUser(String userId, String userPassword);
}
OnlineUserServiceNotifier:
public class OnlineUserServiceNotifier implements
IOnlineUserServiceNotifier {
public void updateOnlineUserService(String userId){
//TODO updateOnlineUserService for 100 lines of code...
}
}
public interface IOnlineUserServiceNotifier {
void updateOnlineUserService(String userId);
}
ClientDataSender:
public class ClientDataSender implements IClientDataSender {
public void sendCustomizedLoginMessage(String userId){
//TODO sendCustomizedLoginMessage for 50 lines of code...
}
public void sendOneTimeOffer(String userId){
//TODO sendOneTimeOffer for 100 lines of code...
}
}
Since both methods are accessed in LoginHandler, interface has to include both methods:
public interface IClientDataSender {
void sendCustomizedLoginMessage(String userId);
void sendOneTimeOffer(String userId);
}
There are really two topics here:
Given a God class, how its members be rationally partitioned into subsets? The fundamental idea is to group elements by conceptual coherency (often indicated by frequent co-usage in client modules) and by forced dependencies. Obviously the details of this are specific to the system being refactored. The outcome is a desired partition (set of groups) of God class elements.
Given a desired partition, actually making the change. This is difficult if the code base has any scale. Doing this manually, you are almost forced to retain the God class while you modify its accessors to instead call new classes formed from the partitions. And of course you need to test, test, test because it is easy to make a mistake when manually making these changes. When all accesses to the God class are gone, you can finally remove it. This sounds great in theory but it takes a long time in practice if you are facing thousands of compilation units, and you have to get the team members to stop adding accesses to the God interface while you do this. One can, however, apply automated refactoring tools to implement this; with such a tool you specify the partition to the tool and it then modifies the code base in a reliable way. Our DMS can implement this Refactoring C++ God Classes and has been used to make such changes across systems with 3,000 compilation units.
Related
Let's say I am making a game of chess. Would it be more effective to have a base class of Piece()? With sub-classes for each type of piece.
Or, an enum
enum Piece{
King,
Queen,
Knight,
etc;
}
It also brings me onto a common problem I have when refining data.
GameObjects
Piece extends GameObjects
Should I stop here and declare the objects with their individual properties?
Piece King = new Piece("King",5,10); //just made up values, no significance.
Or refine it further and have:
King extends Piece
and then handle King Pieces in a polymorphic way:
Piece king = new King("King,5,10);
thanks
Polymorphism
It depends on how you want to structure the logic of your game, but it probably makes sense to define common behavior (methods) and attributes (fields) in an abstract Piece class and then have each subtype implement abstract methods (or override default methods) and set values of inherited fields based on the ways that they vary. Maybe something like:
public abstract class Piece {
protected int value;
public int getValue() {
return value;
}
public abstract boolean isValidMove(String move);
public void move(String move) {
//common logic here
doMove(move);
}
protected abstract void doMove(String move);
}
public class King extends Piece {
public King() {
this.value = 20;
}
public boolean isValidMove(String move) {
//specific king logic here
}
protected void doMove(String move) {
//more specific king logic
}
}
This would allow you to use polymorphism to define various pieces with a common Piece API, while the important differences are handled by each concrete type.
Piece king = new King();
//...
if(king.isValidMove(move)) king.move(move);
Enums
Enums allow you to create a set of optimized singleton instances of a common type, which can also define behavior, but they don't support overriding/implementing type-specific behavior very well because you end up having to check which enum the current instance when implementing variations. You would also end up with a problem of only having a single KING or PAWN instance when you really need multiples of those for a game (one white king and one black king, 8 white pawns and 8 black pawns).
public enum Piece {
KING(20),
PAWN(1);
private int value;
private Piece(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public boolean isValidMove(String move) {
switch(this) {
case KING:
//king specific logic
break;
case PAWN:
//pawn specific logic
break;
}
}
public void move(String move) {
if(this == KING) {
//king specific logic
} else if(this == PAWN) {
//pawn specific logic
}
}
}
So an enum probably wouldn't work very well in this scenario.
Use an enum when there are a limited and defined number if instances.
In this case, clearly there are a defined number of pieces, so use an enum.
Note that enums can have methods just like a regular class, so enums don't have to be just "values", they can do stuff.
I would not try to cram too much into your enum, and in fact I would name it PieceType to make it clear what it represents, and perhaps have a class Piece which is an instance of a piece that has a PieceType, a location (board square) and a color.
The main distinction is that the set of sub-classes is open-ended: you or other people who use your code can create new sub-classes without breaking old code.
Enums are the opposite: other people cannot add new items to your enum and even you, the maintainer of the code, cannot add new enum constants without double-checking every single switch-case statement.
So, use enums if you do not expect new items to be added to the set. Use sub-classes otherwise. This does not mean that sub-classes are better: if you know the set of options to be closed-ended then you should NOT use sub-classes. If you do, you will find yourself writing if (... instanceof ...) chains!
If with enums you find yourself adding new cases to your switch statements (or you can anticipate that) then switch to sub-classes. And if with sub-classes, you find yourself writing instanceof chains, then switch to enums.
I am designing a system that has a simple Entity Framework backed domain object that has fields I need to update based on a series of rules - I want to implement these rules progressively (in an agile style) and as I am using EF I am sceptical about putting each rule into the domain object. However, I want to avoid writing "procedural code" and using anemic domain models. This all needs to be testable as well.
As an example, the object is:
class Employee {
private string Name;
private float Salary;
private float PensionPot;
private bool _pension;
private bool _eligibleForPension;
}
I need to build rules such as "if Salary is higher than 100,000 and _eligibleForPension is false then set _eligibleForPension as true" and "if _pension is true then set _eligibleForPension as true".
There are approximately 20 such rules and I am looking for advice whether they should be implemented in the Employee class or in something like an EmployeeRules class? My first thought was to create a separate class for each rule inheriting from "Rule" and then apply each rule to the Employee class, maybe using the Visitor pattern but I'd have to expose all the fields to the rules to do this so it feels wrong. Having each rule on the Employee class though doesn't feel quite right either. How would this be implemented?
The second concern is that the actual Employees are Entity Framework entities backed to the DB so I don't feel happy adding logic to these "Entities" - especially when I need to mock the objects for unit testing each rule. How could I mock them if they have the rules I'm testing on the same object?
I have been thinking of using AutoMapper to convert to a simpler domain object before applying rules but then need to manage the updates to the fields myself. Any advice on this too?
One approach is to make the rules inner classes of Employee. The benefit of this approach is that the fields can remain private. Also, the invocation of the rules can be enforced by the Employee class itself, ensuring that they are always invoked when needed:
class Employee
{
string id;
string name;
float salary;
float pensionPot;
bool pension;
bool eligibleForPension;
public void ChangeSalary(float salary)
{
this.salary = salary;
ApplyRules();
}
public void MakeEligibleForPension()
{
this.eligibleForPension = true;
ApplyRules(); // may or may not be needed
}
void ApplyRules()
{
rules.ForEach(rule => rule.Apply(this));
}
readonly static List<IEmployeeRule> rules;
static Employee()
{
rules = new List<IEmployeeRule>
{
new SalaryBasedPensionEligibilityRule()
};
}
interface IEmployeeRule
{
void Apply(Employee employee);
}
class SalaryBasedPensionEligibilityRule : IEmployeeRule
{
public void Apply(Employee employee)
{
if (employee.salary > 100000 && !employee.eligibleForPension)
{
employee.MakeEligibleForPension();
}
}
}
}
One problem here is that the Employee class has to contain all rule implementations. This isn't a major problem since the rules embody business logic associated with employee pensions and so they do belong together.
Business rules are usually an interesting topic. There may certainly be a difference between an aggregate / entity invariant and a business rule. Business rules may need external data and I wouldn't agree with a rule changing an aggregate / entity.
You should think specification pattern for rules. The rule should basically just return whether it was broken or not with possibly a description of sorts.
In your example SalaryBasedPensionEligibilityRule, as used by eulerfx, may need some PensionThreshold. This rule really does look more like a task since the rule really isn't checking any validity of the entity.
So I would suggest that rules are a decision mechanism and tasks are for changing the state.
That being said you probably want to ask the entity for advice here since you may not want to expose the state:
public class Employee
{
float salary;
bool eligibleForPension;
public bool QualifiesForPension(float pensionThreshold)
{
return salary > pensionThreshold && !eligibleForPension;
}
public void MakeEligibleForPension()
{
eligibleForPension = true;
}
}
This sticks with the command/query separation idea.
If you are building directly from your ORM objects and do not want to, or cannot, include all the behaviour then that is OK --- but it certainly would help :)
First some background. We recently converted from a Zend_Db_Table-based solution to entity-based solution (Doctrine). As our application grew, the table classes grew uglier and uglier. Some of the tables used ENUM columns to store string-based keys, which were converted into human-readable strings with static methods. Something like this:
public static function getProductType($productKey)
{
if (!array_key_exists($productKey, self::$productTypes)) {
return null;
}
return self::$productTypes[$productKey];
}
public static function getProductTypes()
{
return self::$productTypes;
}
In moving to the entity-based system, I tried to avoid static methods where possible. I moved the key to value translations into a view helper and called it a day. In the end, I found that it was not sufficient, as we needed to return them in JSON objects, which occurred outside of the presentation layer (i.e. no direct access to view helpers).
Does anyone have any theories on the proper place for these types of methods? Should I create separate objects for doing the translation from key to human-readable value, implement static methods on the entity object, or something else?
Well my theory is that this should be done in the model itself. But sometimes when dealing with a complex model, I like to create a separate class that handles any special "presentation" of that model. It takes the model as an argument and encapsulates the presentation logic.
So using your example, perhaps something like this:
class Model_Product
{
public static function getAllTypes()
{
return array(/* key-value pairs */);
}
//returns non human readable value
public function getType()
{
return $this->_type;
}
}
class Model_Product_Presenter
{
protected $_model;
public function __construct(Model_Product $model)
{
$this->_model = $model;
}
//returns human readable value
public function getType()
{
$types = $this->_model->getAllTypes();
if (!array_key_exists($this->_model->type, $types)) {
return null;
}
return $types[$this->_model->type];
}
public function getDateCreated($format = "Y-m-d")
{
return date($format,$this->_model->timestamp);
}
}
You can go further and create a base presenter class to define any common tasks, i.e. converting timestamps to dates, formatting numbers, etc.
Update:
For anonymous access to a list of product types, I don't see any harm in making it the responsibility of the product model via a static method. Not all static methods are evil. In my opinion, the use of static methods for this purpose is fine, because it declares a global constant.
In a more complex scenario, I would delegate this responsibility to a separate class like Model_ProductType. Here is an example of such a complex model in production:
https://github.com/magento/magento2/blob/master/app/code/core/Mage/Catalog/Model/Product/Type.php
I have a singleton IObservable that returns the results of a Linq query. I have another class that listens to the IObservable to structure a message. That class is Exported through MEF, and I can import it and get asynchronous results from the Linq query.
My problem is that after initial composition takes place, I don't get any renotification on changes when the data supplied to the Linq query changes. I implemented INotifyPropertyChanged on the singleton, thinking it word make the exported class requery for a new IObservable, but this doesn't happen.
Maybe I'm not understanding something about the lifetime of MEF containers, or about property notification. I'd appreciate any help.
Below are the singleton and the exported class. I've left out some pieces of code that can be inferred, like the PropertyChanged event handlers and such. Suffice to say, that does work when the underlying Session data changes. The singleton raises a change event for UsersInCurrentSystem, but there is never any request for a new IObservable from the UsersInCurrentSystem property.
public class SingletonObserver: INotifyPropertyChanged
{
private static readonly SingletonObserver _instance = new SingletonObserver();
static SingletonObserver() { }
private SingletonObserver()
{
Session.ObserveProperty(xx => xx.CurrentSystem, true)
.Subscribe(x =>
{
this.RaisePropertyChanged(() => this.UsersInCurrentSystem);
});
}
public static SingletonObserverInstance { get { return _instance; } }
public IObservable<User> UsersInCurrentSystem
{
get
{
var x = from user in Session.CurrentSystem.Users
select user;
return x.ToObservable();
}
}
}
[Export]
public class UserStatus : INotifyPropertyChanged
{
private string _data = string.Empty;
public UserStatus
{
SingletonObserver.Instance.UsersInCurrentSystem.Subscribe(sender =>
{
//set _data according to information in sender
//raise PropertyChanged for Data
}
}
public string Data
{
get { return _data; } }
}
}
My problem is that after initial composition takes place, I don't get any renotification on changes when the data supplied to the Linq query changes.
By default MEF will only compose parts once. When a part has been composed, the same instance will be supplied to all imports. The part will not be recreated unless you explicitly do so.
In your case, if the data of a part change, even if it implements INotifyPropertyChanged, MEF will not create a new one, and you don't need to anyway.
I implemented INotifyPropertyChanged on the singleton, thinking it word make the exported class requery for a new IObservable
No.
Maybe I'm not understanding something about the lifetime of MEF containers, or about property notification.
Property notification allows you to react to a change in the property and has no direct effect on MEF. As for the container's lifetime, it will remain active until it is disposed. While it is still active, the container will keep references to it's compose parts. It's actually a little more complex than that, as parts can have different CreationPolicy that affects how MEF holds the part, I refer you to the following page: Parts Lifetime for more information.
MEF does allow for something called Recomposition. You can set it likewise:
[Import(AllowRecomposition=true)]
What this does tough is allow MEF to recompose parts when new parts are available or existing parts aren't available anymore. From what I understand it isn't what you are referring to in your question.
I have a domain object which has a collection of primitive values, which represent the primary keys of another domain object ("Person").
I have a Wicket component that takes IModel<List<Person>>, and allows you to view, remove, and add Persons to the list.
I would like to write a wrapper which implements IModel<List<Person>>, but which is backed by a PropertyModel<List<Long>> from the original domain object.
View-only is easy (Scala syntax for brevity):
class PersonModel(wrappedModel: IModel[List[Long]]) extends LoadableDetachableModel[List[Person]] {
#SpringBean dao: PersonDao =_
def load: List[Person] = {
// Returns a collection of Persons for each id
wrappedModel.getObject().map { id: Long =>
dao.getPerson(id)
}
}
}
But how might I write this to allow for adding and removing from the original List of Longs?
Or is a Model not the best place to do this translation?
Thanks!
You can do something like this:
class PersonModel extends Model<List<Person>> {
private transient List<Person> cache;
private IModel<List<String>> idModel;
public PersonModel( IModel<List<String>> idModel ) {
this.idModel = idModel;
}
public List<Person> getObject() {
if ( cache == null ) {
cache = convertIdsToPersons( idModel.getObject() );
return cache;
}
public void setObject( List<Person> ob ) {
cache = null;
idModel.setObject( convertPersonsToIds( ob ) );
}
}
This isn't very good code but it shows the general idea. One thing you need to consider is how this whole thing will be serialised between requests, you might be better off extending LoadableDetachableModel instead.
Another thing is the cache: it's there to avoid having to convert the list every time getObject() is called within a request. You may or may not need it in practice (depends on a lot of factors, including the speed of the conversion), but if you use it, it means that if something else is modifying the underlying collection, the changes may not be picked up by this model.
I'm not quite sure I understand your question and I don't understand the syntax of Scala.
But, to remove an entity from a list, you can provide a link that simply removes it using your dao. You must be using a repeater to populate your Person list so each repeater entry will have its own Model which can be passed to the deletion link.
Take a look at this Wicket example that uses a link with a repeater to select a contact. You just need to adapt it to delete your Person instead of selecting it.
As for modifying the original list of Longs, you can use the ListView.removeLink() method to get a link component that removes an entry from the backing list.