How to simplify this code or a better design? - optimization

I am developing a game, the game have different mode. Easy, Normal, and Difficult.
So, I'm thinking about how to store the game mode. My first idea is using number to represent the difficulty.
Easy = 0 Normal = 1 Difficult = 2
So, my code will have something like this:
switch(gameMode){
case 0:
//easy
break;
case 1:
//normal
break;
case 3:
//difficult
break;
}
But I think it have some problems, if I add a new mode, for example, "Extreme", I need to add case 4... ... it seems not a gd design.
So, I am thinking making a gameMode object, and different gameMode is sub class of the super class gameMode.
The gameMode object is something like this:
class GameMode{
int maxEnemyNumber;
int maxWeaponNumber;
public static GameMode init(){
GameMode gm = GameMode();
gm.maxEnemyNumber = 0;
gm.maxWeaponNumber = 0;
return gm;
}
}
class EasyMode extends GameMode{
public static GameMode init(){
GameMode gm = super.init();
gm.maxEnemyNumber = 10;
gm.maxWeaponNumber = 100;
return gm;
}
}
class NormalMode extends GameMode{
public static GameMode init(){
GameMode gm = super.init();
gm.maxEnemyNumber = 20;
gm.maxWeaponNumber = 80;
return gm;
}
}
But I think it seems too "bulky" to create an object to store gameMode, my "gameMode" only store different variables for game settings.... Is that any simple way to store data only instead of making an Object? thz u.

I think you are trying to represent a table of configuration data. Either put this in a configuration file if you're using a language that supports that, or use literal data in your code.
For instance, you might write this in C:
typedef enum difficulties {
DIFFICULTY_EASY,
DIFFICULTY_MEDIUM,
DIFFICULTY_HARD
} difficulties;
struct {
int max_enemies;
int max_weapons;
} difficulty_settings[] = {
{10, 4},
{20, 5},
{30, 6}
};
And when you want to read a particular setting, for example max_enemies for the easy level, then you can writedifficulty_settings[DIFFICULTY_EASY].max_enemies
It's easy to add more configuration (either more parameters, or more difficulty levels) by extending the table.

The overriding goal you should have here is to centralize the logic for retrieving the values related to different levels. By providing one place where these values are stored, you minimize the number of places within the code you need to change if you add another level, add other values, etc.
A class interface is a good choice for this solution. However, if you have a limited number of configuration options represented by the class, there is no reason you need to use inheritance. You can start out with a single class that encapsulates the logic. If the rest of your code retrieves its settings via the class interface you can later introduce a more complex design, such as subclasses for each mode, if it becomes necessary with limited modifications to the rest of your game.
For example, a first implementation may be something like
enum mode {
MODE_EASY = 0,
MODE_NORMAL = 1,
MODE_DIFFICULT = 2,
};
class gameSettings {
public gameSettings(mode GameMode) {
m_mode = GameMode;
}
public int getMaxWeaponNumber() {
int maxWeaponNumber;
switch(m_mode) {
case EASY_MODE:
maxWeaponNumber = 100;
break;
// Other mode settings.
}
return maxWeaponNumber;
}
// Other game settings....
private mode m_mode;
}
This combines the straightforwardness of a switch() statement with the benefits of a class interface. You can also swap out your switch() statement with a lookup table, as suggested by another poster, or some other mechanism as appropriate for your application.

I don't know java (which is what your examples look like), so I present my ideas in some simple C#.
Here is an idea. Use your game mode as a flag instead. If you start with:
[Flags]
enum GameModes
{
Unknown = 0,
ModeA = 1,
ModeB = 2,
ModeC = 4,
}
Now you have levels 1-7 available.
GameModes Difficulty = GameModes.ModeA | GameModes.ModeB; // difficulty = 3
GameModes Difficulty = GameModes.ModeB; // difficulty = 2
In addition, either method you showed will require you to add more options should levels (modes) change, get added, etc. Have your mode templates read in from XML (or other source of your choice), save the mode data into a serializable class. I don't think you should need base class extended by anything.

Use the switch approach in the constructor of your GameMode class.

Besides some syntax issues, I think you're on the right track. I don't think you have to worry about memory, considering there is probably only one mode at once. This is a form of the strategy pattern. You could extend it so the modes do more. For instance, instead of basically just holding constants, perhaps there could be a generateEnemies method that actually creates a set or list of enemies. This moves more of the strategy into the mode object. Sane defaults in the superclass can help avoid redundant code.

Its difficult to say what kind of refactoring could be done here, as there is too less information about other classes. But you could check the State pattern which encapsulates different behaviours in different state objects. Your approach of extending a base GameMode class is very similar to the state pattern. I think it's better than a switch-case-block... and patterns are reliable ways of doing things, if well applied.

Why do you think the switch is harder to mantain? If you add another mode you will have to add code, no matter what solution you employ.
The only case I can think of where you don't have to add code if you add another mode is if you generate the parameters of the game from the value of gameMode.
For instance: maxenemy = 5 * gameMode;
I think that unless you have very complicated initialisation to perform a switch is more than sufficient. I know, I know, objects and classes are nice and all that jazz, but if you just have to define a few vars and the thing works, investing time in developing a complex game mode class may not be a rewarding solution after all (I mean, how many game modes are you planning to add?).

Make use of the strategy pattern.
In Java terms:
public interface Strategy {
void execute();
}
public class SomeStrategy implements Strategy {
public void execute() {
System.out.println("Some logic.");
}
}
which you use as follows:
Map<String, Strategy> strategies = new HashMap<String, Strategy>();
strategies.put("strategyName1", new SomeStrategy1());
strategies.put("strategyName2", new SomeStrategy2());
strategies.put("strategyName3", new SomeStrategy3());
// ...
strategies.get(s).execute();

Related

Creating objects with very many optional fields

I'm trying to recreate Hearthstone cards as objects in Java, but I'm having trouble doing this in a good and efficient way.
All cards have some common properties like a 'name'. But the problem is that there is about 300 cards to generate, and there is about 30 different abilities that each card may or may not have. Now, do I have to create a basic card class with all the possible abilities set to false and then set all its specific ability parameters to true? This approach seems to get very messy with all the getters and all the extra information that some abilities needs to specify... So my question is if there's there a better way to solve this kind of problem?
I would like to create these card objects so that I'm only 'adding' the specific abilities as fields, but I can't figure out how to do this in a good way.
Thankful for help!
Like Dave said, it's a little difficult to be sure what the best solution to your problem is without more context. However, from what I can gather, your problem is a pretty common one. For common problems, programmers often create efficient solutions that can be used over and over again called design patterns.
Design patterns aren't needed in every case, so be careful not to overuse them, but it seems like they could help you here. Both solutions mentioned by Dave may work, but the problem with making each ability an object is that it requires you to make as many classes as you have abilities. Furthermore, if each ability is a simple variable, it may be overkill to create classes for all of them, particularly since so many classes can become difficult to maintain. Although having these abilities inherit from an interface somewhat helps with maintainability, I think an easier solution can probably be found in the builder pattern.
I won't explain it in detail here, but here's a tutorial that seems reasonably simple. It's basic purpose is to
For your particular example it would look something like this:
public class Card
{
private final String name;
private final Ability soundAbility;
private final Ability animationAbility;
private final Ability customMessageAbility;
private final String technology;
// The constructor is private in this case to restrict instantiation to the builder.
private Card(CardBuilder builder)
{
this.name = builder.name;
this.soundAbility = builder.soundAbility;
this.animationAbility = builder.animationAbility;
this.customMessageAbility = builder.customMessageAbility;
this.technology = builder.technology;
}
// Getters
public String getName()
{
return this.name;
}
public Ability getSoundAbility()
{
return this.soundAbility;
}
// ... More getters and stuff ...
#Override
public String toString()
{
String text = "";
text += this.name + ":";
text += "\n\t" + this.soundAbility;
text += "\n\t" + this.animationAbility;
text += "\n\t" + this.customMessageAbility;
text += "\n\tI have the ability of " + this.technology + "!";
return text;
}
// Nested builder class
public static class CardBuilder
{
private final String name;
private Ability soundAbility;
private Ability animationAbility;
private Ability customMessageAbility;
private String technology;
public CardBuilder(String name)
{
this.name = name;
}
public CardBuilder soundAbility(Ability soundAbility)
{
this.soundAbility = soundAbility;
return this;
}
public CardBuilder animationAbility(Ability animationAbility)
{
this.animationAbility = animationAbility;
return this;
}
public CardBuilder customMessageAbility(Ability customMessageAbility)
{
this.customMessageAbility = customMessageAbility;
return this;
}
public CardBuilder technology(String technology)
{
this.technology = technology;
return this;
}
public Card build()
{
return new Card(this);
}
}
}
Then to run the program:
package builderTest;
class BuilderMain
{
public static void main(String[] args)
{
// Initialize ability objects.
Ability a1 = new SoundAbility();
Ability a2 = new AnimationAbility();
Ability a3 = new CustomMessageAbility();
// Build card
Card card = new Card.CardBuilder("Birthday Card")
.soundAbility(a1)
.animationAbility(a2)
.customMessageAbility(a3)
.technology("Flash")
.build();
System.out.println(card);
}
}
The output would be something along the lines of:
Birthday Card:
I have the ability of sound!
I have the ability of animation!
I have the ability of customizing messages!
I have the ability of Flash!
Keep in mind that I'm working without much context, so what you need might be significantly different.
Although previous answers are very good, there is still another way of achieve this Object creation
with very many optional fields
I found myself in similar situation when dealing with DB complexity and Command design pattern. As you know some table columns values are mandatory - some are not. I'm using this Effective Java book
for such cases.
So, useful here is the Consider a builder when faced with many constructor parameters. By doing so, you avoid
first, the Telescoping constructor pattern (does not scale well) - it works, but it is hard to write client code when there are many parameters, and harder still to read it.
second, the JavaBeans Pattern, which is good, but allows inconsistency and mandates mutability. It may be in an inconsistent state partway through its construction and precludes the possibility of making a class immutable too.
The Builder pattern as used simulates named optional parameters as found in Ada and Python.Like a constructor, a builder can impose invariants on its parameters. But it is critical that they be checked after copying the parameters from the builder to the object, and that they be checked on
the object fields rather than the builder fields.
Cheers.

OOD: Using factory pattern in combination with strategy pattern

There are a few questions already on Stackoverflow with similar scenarios, but they don't really address my case.
I am currently doing some refactoring and would like to make the code more robust, flexible and readable by applying patterns. Here is the task:
I have a class, let's say class A, which applies some logic when setting one of its members. This logic is prone to change, so I would like to externalise it. This is where the strategy pattern would be useful.
Also, at some stage I need to filter a list of objects of class A. The filter logic should also be configurable, so the stragey pattern would be handy in this task also.
The question is: How do I combine these requirements into the object-oriented design?
My thoughts so far:
- Use a factory for objects of type A, that has two strategy objects: SettingMemberStrategy and FilterStrategy. If the concrete factory is implemented as singleton, the two strategy objects need to be specified before objects can be created.
- Have two methods on the interface of class A: setMember(value); boolean filtered(). The exact implementation of these methods is determined by the strategies. However, should the object then also carry instances of the strategies?
This approach might work, but it seems a bit overengineered for the task and aesthetically not too pleasing.
Could someone hint at a better solution?
Thanks a million.
Cheers,
Martin
public interface IA {
setMember();
filter();
}
public class A implements IA {
private String theMember = "";
getMember() { return this.theMember; }
setMember(String input, otherParameters[]) {
// set value for member based on strategy and parameters
}
boolean filter();
// returns yes/no based on whether this class should be filtered
// as per filter strategy
}
public class myFactory {
private FilterStrategy myFilterStrategy;
private MemberStrategy mySetMemberStrategy;
IA createObjectOfClassA() {
a = new A(mySetMemberStrategy, myFilterStrategy);
}
setFilterStrategy(FilterStrategy s) { this.myFilterStrategy = s }
setMemberStrategy(MemberStrategy s) { this.mySetMemberStrategy = s }
}
This question depends entirely on how you use these objects. My instinct tells me that in most cases you don't need both a factory and a strategy pattern - you would want to choose one or the other, thus simplifying your code.
If for example, you are creating subclasses of object A in your factory, then eliminate the configurable strategy and bake it into your subclasses.
If, however, you don't create subclasses, just have objects with configurable strategies, then eliminate the factory, and just create the objects with the appropriate strategy in their constructor when you need them.
You could also have a combination of the two if you for example create objects based on an input, and use a factory method to give you a proper instance, i.e.
public A MyFactoryMethod(string typeToCreate){
switch(typeToCreate) {
case "AbeforeB":
return new A(new FilterStrategyA(), new MemberStragegyB());
case "allA":
return new A(new FilterA(), new MemberStrategyA());
// etc. etc.
}
}

Design Pattern for late binding class (without switch case for class assignment)

I have a base class where all common functions are written. I many classes which override this functions by virtual keyword. Like,
public class Base
{
public virtual void sample()
{
..............
}
}
public class a : Base
{
public override sample()
{
}
}
public class implement
{
public void ToSample()
{
Base baseclass = new Base();
Switch(test)
{
case a: baseclass = a();
break;
case b: baseclass = b();
break;
}
baseclass.sample();
}
}
This perfect code for current situation but now I have more class to be assign in switch case. It is not good practice for adding huge amount of cases so I want something that automatically assign child class.
Is anybody know something to be implement ?
As stated in the comment, you can decouple the implementation by using dependency injection. Note however, that in some cases you have no choice but doing that kind of switch (e.g. when you need to create a class based on a text received in a socket). In such cases the important thing is to always keep the switch statement encapsulated in one method and make your objects rely on it (or, in other words, don't copy-and-paste it everywhere :)). The idea here is too keep your system isolated from a potentially harmful code. Of course that if you add a new class you will have to go and modify that method, however you will only have to do it in one time and in one specific place.
Another approach that I have seen (and sometimes used) is to build a mapping between values an classes. So, if your class-creation switch depends on an integer code, you basically create a mapping between codes and classes. What you are doing here is turning a "static" switch into a dynamic behavior, since you can change the mappings contents at any time and thus alter the way your program behaves. A typical implementation would be something like (sorry for the pseudocode, I'm not familiar with C#):
public class implement
{
public void ToSample()
{
class = this.mapping.valueForKey(test);
Base baseclass = new class();
baseclass.sample();
}
}
Note however that for this example to work you need reflection support, which varies according to the language you are using (again, sorry but I don't know the C# specifics).
Finally, you can also check the creational family of patterns for inspiration regarding object creation issues and some well known forms of solving them.
HTH

Monkey Patching in C#

Is it possible to extend or modify the code of a C# class at runtime?
My question specifically revolves around Monkey Patching / Duck Punching or Meta Object Programming (MOP), as it happens in scripting languages such as Groovy, Ruby etc.
For those still stumbling on this question in the present day, there is indeed a present-day library called Harmony that relatively-straightforwardly enables such monkey-patching at runtime. Its focus is on video game modding (particularly games built with Unity), but there ain't much stopping folks from using it outside of that use case.
Copying the example from their introduction, if you have an existing class like so:
public class SomeGameClass
{
public bool isRunning;
public int counter;
private int DoSomething()
{
if (isRunning)
{
counter++;
}
return counter * 10;
}
}
Then Harmony can patch it like so:
using HarmonyLib;
using Intro_SomeGame;
public class MyPatcher
{
// make sure DoPatching() is called at start either by
// the mod loader or by your injector
public static void DoPatching()
{
var harmony = new Harmony("com.example.patch");
harmony.PatchAll();
}
}
[HarmonyPatch(typeof(SomeGameClass))]
[HarmonyPatch("DoSomething")]
class Patch01
{
static AccessTools.FieldRef<SomeGameClass, bool> isRunningRef =
AccessTools.FieldRefAccess<SomeGameClass, bool>("isRunning");
static bool Prefix(SomeGameClass __instance, ref int ___counter)
{
isRunningRef(__instance) = true;
if (___counter > 100)
return false;
___counter = 0;
return true;
}
static void Postfix(ref int __result)
{
__result *= 2;
}
}
Here, we have a "prefix" patch which gets inserted before the original method runs, allowing us to set variables within the method, set fields on the method's class, or even skip the original method entirely. We also have a "postfix" patch which gets inserted after the original method runs, and can manipulate things like the return value.
Obviously this ain't quite as nice as the sorts of monkey-patching you can do in e.g. Ruby, and there are a lot of caveats that might hinder its usefulness depending on your use case, but in those situations where you really do need to alter methods, Harmony's a pretty proven approach to doing so.
Is it possible to extend or modify the code of a C# class at run-time?
No it is not possible to do this in .NET. You could write derived classes and override methods (if they are virtual) but you cannot modify an existing class. Just imagine if what you were asking was possible: you could modify the behavior of some existing system classes like System.String.
You may also take a look at Extension methods to add functionality to an existing class.
You can add functionality, but you cannot change or remove functionality.
You can extend classes by adding extra methods, but you cannot override them because added methods have always lower priority than existing ones.
For more info, check Extension Methods in C# Programming Guide.

Encapsulation within class definitions

For example, do you use accessors and mutators within your method definitions or just access the data directly? Sometimes, all the time or when in Rome?
Always try to use accessors, even inside the class. The only time you would want to access state directly and not through the public interface is if for some reason you needed to bypass the validation or other logic contained in the accessor method.
Now if you find yourself in the situation where you do need to bypass that logic you ought to step back and ask yourself whether or not this need betrays a flaw in your design.
Edit: Read Automatic vs Explicit Properties by Eric Lippert in which he delves into this very issue and explains things very clearly. It is about C# specifically but the OOP theory is universal and solid.
Here is an excerpt:
If the reason that motivated the
change from automatically implemented
property to explicitly implemented
property was to change the semantics
of the property then you should
evaluate whether the desired semantics
when accessing the property from
within the class are identical to or
different from the desired semantics
when accessing the property from
outside the class.
If the result of that investigation is
“from within the class, the desired
semantics of accessing this property
are different from the desired
semantics of accessing the property
from the outside”, then your edit has
introduced a bug. You should fix the
bug. If they are the same, then your
edit has not introduced a bug; keep
the implementation the same.
In general, I prefer accessors/mutators. That way, I can change the internal implementation of a class, while the class functions in the same way to an external user (or preexisting code that I dont want to break).
The accessors are designed so that you can add property specific logic. Such as
int Degrees
{
set
{
_degrees = value % 360;
}
}
So, you would always want to access that field through the getter and setter, and that way you can always be certain that the value will never get greater than 360.
If, as Andrew mentioned, you need to skip the validation, then it's quite possible that there is a flaw in the design of the function, or in the design of the validation.
Accessors and Mutators are designed to ensure consistency of your data, so even within your class you should always strive to make sure that there's no possible way of injecting unvalidated data into those fields.
EDIT
See this question as well:
OO Design: Do you use public properties or private fields internally?
I don't tend to share with the outside world the 'innards' of my classes and so my internal needs for data (the private method stuff) tends to not do the same sort of stuff that my public interface does, typically.
It is pretty uncommon that I'll write an accessor/mutator that a private method will call, but I suspect I'm in the minority here. Maybe I should do more of this, but I don't tend to.
Anyway, that's my [patina covered] two cents.
I will often start with private auto properties, then refactor if necessary. I'll refactor to a property with a backing field, then replace the backing field with the "real" store, for instance Session or ViewState for an ASP.NET application.
From:
private int[] Property { get; set; }
to
private int[] _property;
private int[] Property
{
get { return _property; }
set { _property = value; }
}
to
private int[] _property;
private int[] Property
{
get
{
if (_property == null)
{
_property = new int[8];
}
return _property;
}
set { _property = value; }
}
to
private int[] Property
{
get
{
if (ViewState["PropertyKey"] == null)
{
ViewState["PropertyKey"] = new int[8];
}
return (int[]) ViewState["PropertyKey"];
}
set { ViewState["PropertyKey"] = value; }
}
Of course, I use ReSharper, so this takes less time to do than to post about.