what I mean by that is: I basically have a class that has too many properties and functions now. To remain performant and understandable, it needs to shrink somehow. But I still need all those properties and methods somewhere. It's like this right now:
class Apple
float seedCount;
...
...about 25 variables and properties here.
void Update() <-- a huge method that checks for each property and updates if so
In most cases the class needs almost none of those properties. In some cases in needs to be able to grow very selectively and gain a feature or lose a feature. The only solution I have come up with, is that I create a bunch of classes and place some properties in there. I only initialize this classes object when one of those properties is needed, otherwise it remains null.
class Apple
Seed seed;
Many problems because of that: I constantly have to check for every single object and feature each frame. If the seed is not initialized I don't have to calculate anything for it. If it is, I have to. If I decided to put more than 1 property/feature into the Seed class, I need to check every single one of those aswell. It just gets more and more complicated. The problem I have is therefore, that I need granular control over all the features and can't split them intelligently into larger subclasses. Any form of subclass would just contain a bunch of properties that need to be checked and updated if wanted. I can't exactly create subclasses of Apple, because of the need for such high granular control. It would be madness to create as many classes as there are combinations of properties. My main goal: I want short code.
Scalability is the measure of how well that system responds to changes by adding or removing resources to meet demands. The architecture is the hardware, software, technology and best practices used to build the networks, applications, processes, and services that make up your entire system.
To handle 100 million users and beyond: - max out the vertical scaling: using the fastest and best CPU/RAM/SSD disks/RAM Disks. - keep web tier stateless. - build redundancy at every tier.
We have two basic ways to achieve scalability, namely increasing system capacity, typically through replication, and performance optimization of system components. Like any software architecture quality attribute, scalability cannot be achieved in isolation.
It would be madness to create as many classes as there are combinations of properties.
Sounds like you might be looking for the Decorator Pattern. It's purpose is to make it easier to manage objects that can have many different combinations of properties without an exponentially growing heirarchy. You just have one small subclass for each property or behavior (not necessarily one C# property, just something you can group together) and then you can compose them together at runtime.
In your case, each Apple decorator class will override your Update
method, and make the calculations necessary for its parts, and then call base.Update
to pass it to the next in line.
Your final answer will heavily depend on exactly what your "Apple" really is.
After reviewing your comments and samples in my other answer, I've thought about the Decorator pattern and how it was being used vs how you want things to work. I've come to the conclusion that Decorator is not right for this purpose. I'm thinking Strategy instead. I have modified the previous sample code for you to take a look at.
I've gotten rid of the decorators altogether. The Broodfather abstract class remains. It has two additional properties an IBroodfatherMagicAbility and an IBroodfatherBloodthirstAbility. This two properties will allow you to access the different attributes that pertain to those abilities, however the key to this all is that the strategy for implementing the abilities can change at runtime (see Strategy pattern).
There are two classes each that implement a "strategy" for both bloodthrist and magic.
BroodfatherBloodThristy.cs - class that implements the attributes for bloodthirsty.
IBroodfatherMagicAbility.cs - this is the interface that all "magical strategies" must implement.
BroodfatherMagical.cs - class that implements a strategy for magical.
BasicBroodfather.cs - this is similar to the previous example, except that now when an instance is created the magic and bloodthrist properties get set to new instances of the non-magical and non-bloodthristy strategy objects.
Program.cs is the driver that shows the classes and how the different strategies can get swapped in and out at runtime.
I think you'll find that more suited to how you wanted things to work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With