what are the practices to avoid a class becoming a god class? - class

Let us take an example of a Consumer class. The functions related to a Consumer will go into this class. Gradually the Consumer class has lot of methods in it. And those are supposed to be part of the Consumer class itself. In such cases, how do we break it? are there any strategies related to solving this?

This is quite a broad question but I'll attempt to answer it.
SOLID principles are good practices to follow. If you apply these, especially the Single Responsibility Principle, you will end up with smaller classes with well defined responsibilities.
It's also important to look at cohesion which is a measure of how related the elements of your class are. You want to aim for high cohesion in your classes (and modules). For example, if every method in your class uses a certain member variable, then cohesion is high. If there is a member variable of your class which is only used in one method, this is a good case to be refactored into a separate class.

Use structural design patterns. I would use either the Composite or Decorator design pattern to address your issue. You can learn about them here: https://sourcemaking.com/design_patterns/structural_patterns

As already exposed by #MoonMoo the guidelines for refactoring a fat class should be SOLID principles and cohesion of classes.
The point is: even if a method is related to a Customer, should it stay in Customer class? Or that method can be called by the Customer from another class?
The answer to these question could be a first starting point to understand which methods must stay in the Customer class and which methods can be relocated in another form in another class to which the Customer has a reference.

Related

Deciding on class responsibility

I know this is an opinionated question. However it comes up often at work.
When creating methods it's often a struggle to know which class should be responsible.
e.g.
bool result = ProductService.CategoryHasSoldOutOfProducts(int categoryId)
vs
bool result = CategoryService.CategoryHasSoldOutOfProducts(int categoryId)
In my opinion, the CategoryService should be responsible, as the method is taking a categoryId and is specific to the Category.
Others at my work say the ProductService should be responsible as the method is dealing with if Products have sold out.
Just trying to develop a better understanding of service architecture and good process. I'm interested in other peoples explanations for why they would choose one over the other.
Thanks
Disclaimer - this is a purely IMHO answer. I am answering this in the spirit of having a design brainstorm.
Based on the OP, it seems the relationship between Category and Product is an optional one to many : Category (0..1) <--------> (*) Product.
Implementation wise, this means that the Category entity probably has a Container of Products, and the Product entity has a reference to a Category which may be NULL.
In this case, I agree with the decision to place CategoryHasSoldOutOfProducts under the responsibility of the Category entity. The method name clearly implies that the Category entity should be responsible for informing its API user on the status of its products.
There is another option, however: An association class/entity. The motivation behind this entity is to describe the relationship between two other entities.
In this case, you can have a functional association entity which we will call ProductContainment for the sake of this example.
ProductContainment will have no internal state, and will hold functions which are provided with Category and/or Product entities as parameters.
It is then the responsibility of the association entity to provide the implementation of functions which relate to how Category and Product relate to one another.
If you end up using ProductContainment - then CategoryHasSoldOutOfProducts should be one of its functions.
Since you're asking for opinions, here is mine:
(Disclaimer: That's probably something you cannot easily implement in the business world)
As you are using the term "class", I assume you want to have something object-oriented. The problem is, a service is nothing a valid object could be created from. Instead, it's just a namespace for functions.
Additionally it's very general. It's like calling a class "Manager". You can put possibly everything inside of it and this class has the potential to grow to have hundreds of functions.
My advice: Create small entities. Small enough to be created without the use of any setters, just by calling the constructor. If you notice your object needs more functionalities, create a decorator that is a little bit smarter and can do the work for you.
I would need a few more details about your environment to be more precise, but I guess in your case, you would have something like a Category class that contains products and knows when it's sold out. Just imagine you have a team of persons and everyone knows something. Ask the right guys to do the stuff and stay away from managers or services.

UML software design (specifically Abstract classes)

When designing software (think UML diagrams for example) and real world objects.
How does one identify a suitable case for an Abstract class?
For example if we had an [Employee] and [Fireman] and [paidFireman] and [unpaidFireman]...I am having trouble seeing whether a Fireman or Employee should be abstract and why?
Abstract classes are one of those more esoteric constructs in UML. Since classes are already an abstraction of real world things, an abstract class is even one level higher. Abstract classes can not be instantiated (since it is assumed they miss something for a real life). Whether you say that Fireman is abstract while the paid/unpaid are not, is a pure point of view and must be argued in the specific domain.
As a rule of thumb: leave abstract classes out of the door until you come to a point where you feel the urgent need for it. Introducing abstractness limits your model (and can help to avoid some malformed results of it). But without those limits the model is still valid as long as the architect sticks to common sense rules.
It mainly depends on your functional requirements.
If it makes sense in your application just to have simple employees (without designating them as firemen, policemen, or craftsmen), then the class may not be abstract, as the application will have to make instances just of the Employee class.
If that doesn't make sense, i.e. the occupation of each of your employees needs to be known at creation time, abstract classes come into consideration. But still they aren't necessary in every case. The easiest way to make sure the occupation is known is to model it as a mandatory attribute. Introducing a subclass only makes sense if there is specialized behavior for each of those subclasses. If, e.g., the salary of the firemen is calculated as 50$ * count of the fires he exstinguished, but the salary of the policemen is 1000$ + 50 * rank, then you model an abstract operation getSalary() in the Employee class, which will be concretely specified and implemented in each of the subclasses.
As the concept of interface also got mentioned in one of the answers, an interface describes the obligation to implement certain operations in all classes realizing that interface. That's much the same as an abstract operation in an abstract class. But the abstract class can contain much more than an interface: attributes and non-abstract operations.
So the rule of thumb is: For concepts of your domain for which interface and behavior can be fully described, use non-abstract classes. For concepts for which only interfaces and no behavior can be described, use interfaces. For concepts for which interfaces and part of the behavior can be described, use abstract classes.
There are many uses for an abstract class. An abstract class is one that cannot have any direct instances.
In software design, it is one way to describe an interface. Some of the declared operations can be implemented in the superclass. Any remaining implementations must be specified in sub-classes. Regardless of where the implementations exist, an abstract class means there can be no direct instances, only instances of some non-abstract subclass.
In a domain analysis, an abstract class is a way of modeling an abstraction. For example, think of the abstraction Role. It is useful to say that a Person plays a number of Roles. However, there is no instance of a Role that makes sense, without it also being a more specific kind of Role, such as Employee, Fireman, or Teacher. For this situation, you not only want Role to be abstract, you also want a covering axiom. For more on that, please read https://stackoverflow.com/a/35950236/2596664.

Deep class inheritance hierarchy -- bad idea?

hoping a grandmaster can shed some light. Very high overview is that I am no beginner to coding, but still new to OOP. This set of message classes is at the heart of a large simulation application we're writing, and I don't want to do it stupidly--this interface cuts the application in half, from sequencer to executer and vice-versa.
My question is whether or not it's a bad idea to have an inheritance hierarchy this deep (image is not yet fleshed out, might go 5 or 6 deep in the end). This is as opposed to having some of the child classes just have a directed association to their parent class, instead of inheriting.
I've read that a deep inheritance hierarchy is not a good idea, and that if a child class is inheriting simply to have the parent's data, then you should simply include the parent as data in the child, but I'm having a hard time wrapping my head around why. What bad thing is going to happen to us if I decided to make an inheritance hierarchy 7-deep or something like that? Clearly there's a small performance hit, and changing things at the top of the hierarchy is going to have huge ripples throughout the app, but other than that I don't see an issue. Aside, I care little about minor differences in performance.
(bonus question: Is there an off-the-shelf package that handles this kind of stuff? We have most of the low level physical simulations handled, but the sequencing program we're going to have to write. I just have this suspicion that what I've laid out is very similar to what about 10,000 simulation developers before me did.)
(bonus question #2: any masters of both simulation systems and OOP programming, that would not hate living in Los Angeles? We're hiring.)
that if a child class is inheriting simply to have the parent's data
This is a bad idea. There's this understanding that you define base classes as the most generic of contracts that a set of (concrete) classes are going to honor. This typically means that your contract is about behavior and not implementation.
What bad thing is going to happen to us if I decided to make an inheritance hierarchy 7-deep or something like that?
The major issues here are mundane:
Fragile base classes (changes to base are a nightmare for the derived)
Increased coupling (with too many base classes comes tight coupling)
Encapsulation weakens
Testing issues (leaf level overridden methods can't just be tested to reproduce end-user behavior correctly always due to multiple chained calls here and there)
Maintenance (comes from strong coupling)
(You many want to peruse this paper on Why Ada isn't popular, particularly, Item 6, para 6.)
Is there an off-the-shelf package that handles this kind of stuff?
I'm not sure what you are looking for, but if you're looking for an automated hierarchy simplifier then I don't know of any. Also if such a package exists it'll be highly dependent on your language of choice and you haven't mentioned one.
Note that most of the times such issues can be resolved by looking at alternatives like aggregation or traits or dependency injection or whatever. These are design time issues and are typically (IMO) best ironed out on a whiteboard than with a compiler and millions of LOC.
Seeing this question quite late, but I have had many thoughts on this and have been bitten with deep inheritance hierarchies. One reason they are bad is because you will inevitably get the classification wrong as you specialize the many subclasses. However, once you have the class structure in place it will be hard to change because doing so would break client code.
I blogged about this here.
Old question, but active issue in software development and wanted to add an opinion that may help.
Maintenance overhead can't be estimated when you touch the base classes with DI. This is a major drawback that recently affected our 3 level deep inheritance structure.
Also, if you base is a template, expect to violate SOL(I)(D) if you have too many children with just 1 derived parent in 3 levels for example.
Generally, just to access data I'd choose an adequate design pattern or pass the data pointer if it doesn't violate SOLID. Depending on whether you just read or write, I'd also avoid getters and setters to avoid the Quasi-Classes. It's rare case that default children are 'protected' and I think the structure in this case is a candidate to be flawed by design.

Consequences of Singletons

So I just delved into the Singleton classes and yes, I find them quite helpful. I use my singletons mostly for data storage for multiple targets (views, tables etc.). That being said, I can already see myself going to implement a lot of singletons in my project.
But can a lot of singletons have a negative impact? From what I've read about singletons is that you create one instance for each of them in a proces. Other class instances get released (assuming they get released properly) from memory, then should singletons be released too?
So to narrow it down to one question: Is it harmful to have a lot of singletons?
Singletons don't scale. No matter what you think should be a singleton, when your system gets bigger, it turns out you needed more than one.
If you NEVER need more than one, a singleton is fine. However, as systems scale, you typically need more than one of anything within its own context.
Singletons are merely another way to say "global". It's not bad, but generally, it's not a good idea for systems that evolve and grow in complexity.
From GOF Book:
The Singleton pattern has several benefits:
Controlled access to sole instance. Because the Singleton class encapsulates its sole instance, it can have strict control over how
and when clients access it.
Reduced name space. The Singleton pattern is an improvement over global variables. It avoids polluting the name space with global
variables that store sole instances.
Permits refinement of operations and representation. The Singleton class may be subclassed, and it's easy to configure an application
with an instance of this extended class. You can configure the
application with an instance of the class you need at run-time.
Permits a variable number of instances. The pattern makes it easy to change your mind and allow more than one instance of the Singleton
class. Moreover, you can use the same approach to control the number
of instances that the application uses. Only the operation that grants
access to the Singleton instance needs to change.
More flexible than class operations. Another way to package a singleton's functionality is to useThe Singleton class can be
subclassed. class operations (that is, static member functions in C++
or class methods in Smalltalk). But both of these language techniques
make it hard to change a design to allow more than one instance
ofclass. Moreover, static member functions in C++ are never virtual,
so subclasses can't override them polymorphically.

What are the important rules in Object Model Design

We are developing an extension (in C# .NET env.) for a GIS application, which will has predefined types
for modeling the real world objects, start from GenericObject, and goes to more specific types like Pipe and Road with their detailed properties and methods like BottomOfPipe, Diameter and so on.
Surely, there will be an Object Model, Interfaces, Inheritance and lots of other essential parts in the TypeLibrary, and by now we fixed some of them. But as you may know, designing an Object Model is a very ambiguous work, and (I as much as I know), can be done in many different ways and many different results and weaknesses.
Is there any distinct rules in designing O.M.: the Hierarchy, the way of defining Interfaces, abstract and coclasses enums?
Any suggestion, reference or practice?
A couple of good ones:
SOLID
Single responsibility principle
Open/closed principle
Liskoff substitution principle
Interface segregation principle
Dependency inversion principle
More information and more principles here:
http://mmiika.wordpress.com/oo-design-principles/
Check out Domain-Driven Design: Tackling Complexity in the Heart of Software. I think it will answer your questions.
what they said, plus it looks like you are modeling real-world entities, so:
restrict your object model to exactly match the real-world entities.
You can use inheritance and components to reduce the code/model, but only in ways that make sense with the underlying domain.
For example, a Pipe class with a Diameter property would make sense, while a DiameterizedObject class (with a Diameter property) with a GeometryType property of GeometryType.Pipe would not. Both models could be made to work, but the former clearly corresponds to the problem domain, while the latter implements an artificial (non-real-world) perspective.
One additional clue: you know you've got the model right when you find yourself discovering new features in the code that you didn't plan from the start - they just 'naturally' fall out of the model. For example, your model may have Pipe and Junction classes (as connectivity adapters) sufficient to solve the immediate problem of (say) joining different-diameter pipes to each other and calculating flow rates, maximum pressures, and structural integrity. You later realize that since you modeled the structural and connectivity properties of the Pipes and Junctions accurately (within the requirements of the domain) you can also create a JungleGym object from connected pipes and correctly calculate how much structural load it will bear.
This is an extreme example, but it should get the point across: correct object models support extension and often manifest beneficial unexpected properties and features (not bugs!).
The Liskov Substitution Principle, often expressed in terms of "is-a".
Many examples of OOP would be better off making use of "has-a" (in c++ private inheritance or explicit composition) rather than public inheritance ("is-a")
Getting Inheritance right is hard. Doing so with interfaces (pure virtual classes) is often easier than for base/sub classes
Check out the "principles" of Object oriented design. These have guidelines for all the questions you ask.
References:
"Object oriented software construction" by Robert Martin
http://www.objectmentor.com/resources/publishedArticles.html
Checkout the "Design Principles" articles at the above site. They are the best references available.
"BottomOfPipe"? Is that another way of saying the depth of the Pipe below the Road?
Any kind of design is difficult and can be done different ways. There are no guarantees that your design will work when you create it.
The advantage that people who design ball bearings and such have is many more years of experience and data to determine what works and what does not. Software doesn't have as much time or hard data.
Here's some advice:
Inheritance means IS-A. If that doesn't hold, don't use inheritance.
A deep hierarchy is probably a sign of trouble.
From Scott Meyers: Make non-leaf classes interfaces or abstract.
Prefer composition to inheritance.