How to avoid to "fill" a generic class with attributes? - oop

I am trying to translate a poker game to a correct OOP model.
The basics :
class Hand
{
Card cards[];
}
class Game
{
Hand hands[];
}
I get games and hands from a text file. I parse the text file several times, for several reasons:
get somes infos (reason 1)
compute some stats (reason 2)
...
For reason 1 I need some attributes (a1, b1) in class Hand. For reason 2, I need some other attributes (a2, b2). I think the dirty way would be :
class Hand
{
Card cards[];
Int a1,b1;
Int a2,b2;
}
I would mean that some attributes are useless most of the time.
So, to be cleaner, we could do:
class Hand
{
Card cards[];
}
class HandForReason1 extends Hand
{
Int a1,b1;
}
But I feel like using a hammer...
My question is : is there an intermediate way ? Or the hammer solution is the good one ? (in that case, what would be a correct semantic ?)
PS : design patterns welcome :-)
PS2 : strategy pattern is the hammer, isn't it?
* EDIT *
Here is an application :
// Parse the file, read game infos (reason 1)
// Hand.a2 is not needed here !
class Parser_Infos
{
Game game;
function Parse()
{
game.hands[0].a1 = ...
}
}
// Later, parse the file and get some statistics (reason 2)
// Hand.a1 is not needed here !
class Parser_Stats
{
Game game;
function Parse()
{
game.hand[0].a2 = ...
}
}

Using a chain of responsibility to recognize a poker hand is what I would do. Since each hand has it's own characteristics, you can't just have a generic hand.
Something like
abstract class Hand {
protected Hand next;
abstract protected boolean recognizeImpl(Card cards[]);
public Hand setNext(Hand next) {
this.next = next;
return next;
}
public boolean Hand recognize(Card cards[]) {
boolean result = ;
if (recognizeImpl(cards)) {
return this;
} else if (next != null) {
return next.recognize(cards);
} else {
return null;
}
}
}
And then have your implementation
class FullHouse extends Hand {
protected boolean recognizeImpl(Card cards[]) {
//...
}
}
class Triplet extends Hand {
protected boolean recognizeImpl(Card cards[]) {
//...
}
}
Then build your chain
// chain start with "best" hand first, we want the best hand
// to be treated first, least hand last
Hand handChain = new FullHouse();
handChain
.setNext(new Triplet())
//.setNext(...) /* chain method */
;
//...
Hand bestHand = handChain.recognize(cards);
if (bestHand != null) {
// The given cards correspond best to bestHand
}
Also, with each hand it's own class, you can initialize and have then hold and compute very specific things. But since you should manipulate Hand classes as much as you can (to stay as much OO as possible), you should avoid having to cast your hands to a specific hand class.
** UPDATE **
Alright, so to answer your original question (sig) the class Hand is for manipulating and treating "hands". If you need to calculate other statistics or other needs, wrapping your Hand class might not be a good idea as you'll end up with a compound class, which is not desirable (for maintainability's sake and OOP paradigm).
For the reason 1, it is alright to have different kinds of hands, as the chain of responsibility illustrate; you can read your file, create different kinds of hands with the many parameters as is required.
For reason 2, you might look at other solutions. One would be to have your Hand classes fire events (ex: when it is recognized) and your application could register those hands into some other class to listen for events. That other class should also be responsible to collect the necessary data from the files you are reading. Since a hand is not (or should not be) responsible to collect statistical data, the bottom line is that you need to have something else handle that.
One package = coherent API and functionalities
One class = coherent functionalities (a hand is a hand, not a statistical container)
One method = a (single) functionality (if a method needs to handle more than one functionality, break those functionalities into separate private methods, and call them from the public method)
I'm giving you a generic answer here because reason 1 and reason 2 are not specific.

Related

How to avoid if..else(or any conditionals) while deciding which method to be called?

How to follow Open Close Principle without violating LSP while deciding which method to be invoked with different parameters in a statically typed language?
Consider the requirement like
Action 1: perform DB operation on Table 1
Action 2: Perform DB operation on Table 2 based on input
Action 3: Do Nothing
Code for above requirement would look like
process(obj) {
if(obj.type === action1) {
db.updateTable1()
}
if(obj.type === action2) {
db.updateTable2(obj.status)
}
if(obj.type === action3) {
//May be log action 3 recieved
}
}
Figured out a way to follow OCP in above code for additional actions, by moving body of if statement to method and maintain a map of keys with action as name. Reference
However feels solution is violating the OCP as method wrapping the contents of first if block will not receive any parameter, second method wrapping the contents of second if block will have a parameter.
Either it forces all method to follow the same signature in trade off following OCP but violating LSP or give up OCP itself and thereby live with multi if statements.
A simple solution would be to define a strategy, which execute the code currently contained in the if / else if / else branches:
interface Strategy {
String getType();
void apply();
}
The strategies need to be registered:
class Executor {
private Map<String, Strategy> strategies;
void registerStrategy(strategy Strategy) {
strategies.put(strategy.getType(), strategy);
}
void process(obj) {
if (strategies.containsKey(obj.type)) {
// apply might execute db.updateTable1(),
// depending on the interface's implementation
strategies.get(obj.type).apply();
} else {
System.out.println("No strategy registered for type: " + obj.type);
}
}
}
The tradeoffs you recognise are unfortunately what you'll have to deal with when working with OOP in Java, C++, C# etc as the systems are dynamically put together and SOLID is kind of addresses the flaws. But the SOLID principles are intended to provide guidance, I wouldn't follow them idiomatically.
I hoped to find an example by better programmers than myself illustrating the command pattern. But I was just finding really bad examples which were not really addressing your question.
The problem of defining an associating an intent (defined as string or enum, a button click) with an action (an object, a lambda function) will always require a level of indirection we have to deal with. Some layers of abstractions are acceptable, for example: never call a model or service directly in a view. You could also think of implementing am event dispatcher and corresponding listeners, which would help with the loose coupling. But at some lower level you'll have to look up all listeners ...
The nature of obj is ambiguous, but I would recommend having a well-defined interface and pass it throughout your code where the class implementation of your interface would be equivalent to your 'action'. Here's an example of what that might look like in Typescript:
interface someDBInterface {
performAction() : void;
}
function process(obj : someDBInterface) {
let result = obj.performAction();
}
class action1 implements someDBInterface {
status: any
performAction() {
//db.updateTable1();
}
}
class action2 implements someDBInterface {
status : any
performAction() {
//db.updateTable1(this.status);
}
}
class action3 implements someDBInterface {
performAction() {
//May be log action 3 recieved
}
}
If this doesn't meet your requirements, feel free to reach out :)

Why not use instanceof operator in OOP design?

It has been repeatedly said that the instanceof operator should not be used except in the equals() method, otherwise it's a bad OOP design.
Some wrote that this is a heavy operation, but it seems that, at least java, handles it pretty well (even more efficiently than Object.toString() comparison).
Can someone please explain, or direct me to some article which explains why is it a bad design?
Consider this:
Class Man{
doThingsWithAnimals(List<Animal> animals){
for(Animal animal : animals){
if(animal instanceOf Fish){
eatIt(animal);
}
else if(animal instanceof Dog){
playWithIt(animal);
}
}
}
...
}
The decision of what to do with the Animal, is up to the Man. Man's desires can also change occasionally, deciding to eat the Dog, and play with the Fish, while the Animals don't change.
If you think the instanceof operator is not the correct OOP design here, please tell how would you do it without the instanceof, and why?
instanceof simply breaks the Open/Close principle. and/or Liskov substitution principle
If we are not enough abstract because of instanceof usage, each time a new subclass makes an entrance, the main code gathering the logic of the application might be updated.
This is clearly not what we want, since it could potentially break the existing code and reduce its reusability.
Therefore, a good usage of polymorphism should be preferred over the basic use of conditional.
There's a good blog post called When Polymorphism Fails which is about this kind of scenario. Basically, you're right that it should be up to the Man to decide what to do with each kind of Animal. Otherwise, the code becomes fragmented and you end up violating principles such as Single Responsibility and Law of Demeter.
It wouldn't make sense to have code such as e.g. the following:
abstract class Animal {
abstract void interactWith(Man man);
}
class Fish extends Animal {
#Override
void interactWith(Man man) {
man.eat(this);
}
}
class Dog extends Animal {
#Override
void interactWith(Man man) {
man.playWith(this);
}
}
In that example, we're putting Man's logic outside of the Man class.
The problem with instanceof is that if you have a large amount of Animals, you'll end up with a long if-else-if for every one of them. It's hard to maintain and prone to errors where e.g. a new type of Animal is added, but you forget to add it to the if-else-if chain. (The visitor pattern is partly a solution to the latter problem, because when you add a new type to the visitor class, all of the implementations stop compiling and you're forced to go update them all.)
However, we can still use polymorphism to make the code simpler and avoid instanceof.
For example, if we had a feeding routine such as:
if (animal instanceof Cat) {
animal.eat(catFood);
} else if (animal instanceof Dog) {
animal.eat(dogFood);
} else if (...) {
...
}
We could eliminate the if-else-if by having methods such as Animal.eat(Food) and Animal.getPreferredFood():
animal.eat(animal.getPreferredFood());
With methods such as Animal.isFood() and Animal.isPet(), the example in the question could be written without instanceof as:
if (animal.isFood()) {
eatIt(animal);
} else if (animal.isPet()) {
playWithIt(animal);
}
instanceof is a type system escape hatch. It can be used to do really evil things, like make generics not really generic, or extend a class hierarchy with ad-hoc virtual methods that never appear in the visible interface of those classes. Both of these things are bad for long-term maintainability.
More often than not, if you find yourself wanting to use instanceof, it means that there is something wrong with your design. Breaking the type system should always be a last resort, not something to be taken lightly.
I do not think your particular example warrants using instanceof. The object-oriented way to do this is to use the visitor pattern:
abstract class Animal {
def accept(v: AnimalVisitor)
}
trait Edible extends Animal {
def taste : String
def accept(v: AnimalVisitor) = v.visit(this)
}
trait Pet extends Animal {
def growl : String
def accept(v: AnimalVisitor) = v.visit(this)
}
abstract class AnimalVisitor {
def visit(e: Edible)
def visit(p: Pet)
}
class EatOrPlayVisitor {
def visit(e: Edible) = println("it tastes " + e.taste)
def visit(p: Pet) = println("it says: " + p.growl)
}
class Chicken extends Animal with Edible {
def taste = "plain"
}
class Lobster extends Animal with Edible {
def taste = "exotic"
}
class Cat extends Animal with Pet {
def growl = "meow"
}
class Dog extends Animal with Pet {
def growl = "woof"
}
object Main extends App {
val v = new EatOrPlayVisitor()
val as = List(new Chicken(), new Lobster(), new Cat(), new Dog())
for (a <- as) a.accept(v)
}
NOTE: I am aware that Scala has case classes, but I wanted to provide a general object-oriented solution.
using instance of is a bad practise because in the OOP there is no need to check what the class is,
if the method is compatible you should to be able to call it with such arguments, otherwise design is spoiled, flawed,
but it exist the same way as goto in C and C++,
I think sometimes it might be easier to integrate a bad code using instance of but if you make your own proper code avoid it
so basically this is about of programming style what is good and what is bad,
when and why
in some curcumstances bad style is used, because sometimes the code quality is secondary, perhaps
sometimes the goal is to make the code not easy to understand by others so that would be the way to do it

code in the middle is different, everything else the same

I often have a situation where I need to do:
function a1() {
a = getA;
b = getB;
b.doStuff();
.... // do some things
b.send()
return a - b;
}
function a2() {
a = getA;
b = getB;
b.doStuff();
.... // do some things, but different to above
b.send()
return a - b;
}
I feel like I am repeating myself, yet where I have ...., the methods are different, have different signatures, etc..
What do people normally do? Add an if (this type) do this stuff, else do the other stuff that is different? It doesn't seem like a very good solution either.
Polymorphism and possibly abstraction and encapsulation are your friends here.
You should specify better what kind of instructions you have on the .... // do some things part. If you're always using the same information, but doing different things with it, the solution is fairly easy using simple polymorphism. See my first revision of this answer. I'll assume you need different information to do the specific tasks in each case.
You also didn't specify if those functions are in the same class/module or not. If they are not, you can use inheritance to share the common parts and polymorphism to introduce different behavior in the specific part. If they are in the same class you don't need inheritance nor polymorphism.
In different classes
Taking into account you're stating in the question that you might need to make calls to functions with different signature depending on the implementation subclass (for instance, passing a or b as parameter depending on the case), and assuming you need to do something with the intermediate local variables (i.e. a and b) in the specific implementations:
Short version: Polymorphism+Encapsulation: Pass all the possible in & out parameters that every subclass might need to the abstract function. Might be less painful if you encapsulate them in an object.
Long Version
I'd store intermediate state in generic class' member, and pass it to the implementation methods. Alternatively you could grab the State from the implementation methods instead of passing it as an argument. Then, you can make two subclasses of it implementing the doSpecificStuff(State) method, and grabbing the needed parameters from the intermediate state in the superclass. If needed by the superclass, subclasses might also modify state.
(Java specifics next, sorry)
public abstract class Generic {
private State state = new State();
public void a() {
preProcess();
prepareState();
doSpecificStuf(state);
clearState();
return postProcess();
}
protected void preProcess(){
a = getA;
b = getB;
b.doStuff();
}
protected Object postProcess(){
b.send()
return a - b;
}
protected void prepareState(){
state.prepareState(a,b);
}
private void clearState() {
state.clear();
}
protected abstract doSpecificStuf(State state);
}
public class Specific extends Generic {
protected doSpecificStuf(State state) {
state.getA().doThings();
state.setB(someCalculation);
}
}
public class Specific2 extends Generic {
protected doSpecificStuf(State state) {
state.getB().doThings();
}
}
In the same class
Another possibility would be making the preProcess() method return a State variable, and use it inthe implementations of a1() and a2().
public class MyClass {
protected State preProcess(){
a = getA;
b = getB;
b.doStuff();
return new State(a,b);
}
protected Object postProcess(){
b.send()
return a - b;
}
public void a1(){
State st = preProcess();
st.getA().doThings();
State.clear(st);
return postProcess();
}
public void a2(){
State st = preProcess();
st.getB().doThings();
State.clear(st);
return postProcess();
}
}
Well, don't repeat yourself. My golden rule (which admittedly I break from time on time) is based on the ZOI rule: all code must live exactly zero, one or infinite times. If you see code repeated, you should refactor that into a common ancestor.
That said, it is not possible to give you a definite answer how to refactor your code; there are infinite ways to do this. For example, if a1() and a2() reside in different classes then you can use polymorphism. If they live in the same class, you can create a function that receives an anonymous function as parameter and then a1() and a2() are just wrappers to that function. Using a (shudder) parameter to change the function behavior can be used, too.
You can solve this in one of 2 ways. Both a1 and a2 will call a3. a3 will do the shared code, and:
1. call a function that it receives as a parameter, which does either the middle part of a1 or the middle part of a2 (and they will pass the correct parameter),
- or -
2. receive a flag (e.g. boolean), which will tell it which part it needs to do, and using an if statement will execute the correct code.
This screams out loud for the design pattern "Template Method"
The general part is in the super class:
package patterns.templatemethod;
public abstract class AbstractSuper {
public Integer doTheStuff(Integer a, Integer b) {
Integer x = b.intValue() + a.intValue();
Integer y = doSpecificStuff(x);
return b.intValue() * y;
}
protected abstract Integer doSpecificStuff(Integer x);
}
The spezific part is in the subclass:
package patterns.templatemethod;
public class ConcreteA extends AbstractSuper {
#Override
protected Integer doSpecificStuff(Integer x) {
return x.intValue() * x.intValue();
}
}
For every spezific solution you implement a subclass, with the specific behavior.
If you put them all in an Collection, you can iterate over them and call always the common method and evry class does it's magic. ;)
hope this helps

Object oriented design

I have two csv files A and B. A is the master repository. I need to read those files, map the records of B to A and save the mapped records to another file.
The class to hold records is, say Record. The class to hold the matched records is, say, RecordMatch.
class Record
{
string Id;
string Name;
string Address;
string City;
string State;
string Zipcode;
}
class RecordMatch
{
string Aid;
string AName;
string Bid;
string BName;
double NameMatchPercent;
}
The mapping scenario goes thus : First, against each record of B, the records of A are filtered using state, city and then zipcode. The records of A thus filtered are then compared with the record of B. This comparison is between the name field, and is a best-match comparison using a fuzzy string algorithm. The best match is selected and saved.
The string matching algorithm will give a percentage of match. Thus, the best result out of all the matches have to be selected.
Now that I tried my best to explain the scenario, I will come to the design issue. My initial design was to make a Mapper class, which will be something as below :
class Mapper
{
List<Record> ReadFromFile(File);
List<Record> FilterData(FilterType);
void Save(List<Record>);
RecordMatch MatchRecord(Record A, Record B);
}
But looking at the design, it simply seems to be a class wrapper over some methods. I dont see any OO design in it. I also felt that the Match() belongs more to the Record class than the Mapper class.
But on another look, I saw the class as implementing something resembling to Repository pattern.
Another way I think is to keep the Mapper class, and just move the Match() method to the Record class, something like this :
class Mapper
{
List<Record> ReadFromFile(File);
List<Record> FilterData(FilterType);
void Save(List<Record>);
}
class Record
{
string id;
string name;
string address;
// other fields;
public RecordMatch Match (Record record)
{
// This record will compare the name field with that of the passed Record.
// It will return RecordMatch specifyin the percent of match.
}
}
Now I am totally confused in this simple scenario. What would ideally be a good OO design in this scenario?
Amusingly enough, I am working on a project almost exactly like this right now.
Easy Answer: Ok, first off, it is not the end of the world if a method is in the wrong class for a while! If you have your classes all covered with tests, where the functions lives is important, but can be changed around fluidly as you, the king of your domain, sees fit.
If you are not testing this, well, that would be my first suggestion. Many many smarter people than me have remarked on how TDD and testing can help bring your classes to the best design naturally.
Longer Answer: Rather than looking for patterns to apply to a design, I like to think it through like this: what are the reasons each of your classes has to change? If you separate those reasons from each other (which is one thing TDD can help you do), then you will start to see design patterns naturally emerge from your code.
Here are some reasons to change I could think of in a few passes reading through your question:
The data file changes format/adds columns
You find a better matching algorithm, or: "now we want to filter on cell phone number too"
You are asked to make it match xml/yaml/etc files as well
You are asked to save it in a new format/location
Ok, so, if implementing any of those would make you need to add an "if statement" somewhere, then perhaps that is a seam for a subclasses implementing a common interface.
Also, let's say you want to save the created file in a new place. That is one reason to change, and should not overlap with you needing to change your merging strategy. If those two parts are in the same class, that class now has two responsibilities, and that violates the single responsibility principle.
So, that is a very brief example, to go further in depth with good OO design, check out the SOLID principles. You can't go wrong with learning those and seeking too apply them with prudence throughout your OO designs.
I gave this a try. There's not so much you can do when it comes to OO principles or design patterns I think, except for maybe using composition for the MatchingAlgorithm (and perhaps Strategy and Template if needed). Here's what I've cooked up:
class Mapper {
map(String fileA, String fileB, String fileC) {
RecordsList a = new RecordsList(fileA);
RecordsList b = new RecordsList(fileB);
MatchingRecordsList c = new MatchingRecordsList();
for(Record rb : b) {
int highestPerc = -1;
MatchingRecords matchingRec;
for(Record ra : a) {
int perc;
rb.setMatchingAlgorithm(someAlgorithmYouVeDefined);
perc = rb.match(ra);
if(perc > highestPerc) {
matchingRec = new MatchingRecords(rb, ra, perc);
}
}
if(matchingRec != null) {
c.add(matchingRec);
}
}
c.saveToFile(fileC);
}
}
class MatchingAlgorithm {
int match(Record b, Record a) {
int result;
// do your magic
return result;
}
}
class Record {
String Id;
String Name;
String Address;
String City;
String State;
String Zipcode;
MatchingAlgorithm alg;
setMatchingAlgorithm(MatchingAlgorithm alg) {
this.alg = alg;
}
int match(Record r) {
int result; -- perc of match
// do the matching by making use of the algorithm
result = alg.match(this, r);
return result;
}
}
class RecordsList implements List<Record> {
RecordsList(file f) {
//create list by reading from csv-file)
}
}
class MatchingRecords {
Record a;
Record b;
int matchingPerc;
MatchingRecords(Record a, Record b, int perc) {
this.a = a;
this.b = b;
this.matchingPerc = perc;
}
}
class MatchingRecordsList {
add(MatchingRecords mr) {
//add
}
saveToFile(file x) {
//save to file
}
}
(This is written in Notepad++ so there can be typos etc; also the proposed classes can surely benefit from a little more refactoring but I'll leave that to you if you choose to use this layout.)

Best design for lookup-and-possibly-change method

I am designing a class that stores (caches) a set of data. I want to lookup a value, if the class contains the value then use it and modify a property of the class. I am concerned about the design of the public interface.
Here is how the class is going to be used:
ClassItem *pClassItem = myClass.Lookup(value);
if (pClassItem)
{ // item is found in class so modify and use it
pClassItem->SetAttribute(something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
However I don't want to have to expose ClassItem to this client (ClassItem is an implementation detail of MyClass).
To get round that the following could be considered:
bool found = myClass.Lookup(value);
if (found)
{ // item is found in class so modify and use it
myClass.ModifyAttribute(value, something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
However this is inefficient as Modify will have to do the lookup again. This would suggest a lookupAndModify type of method:
bool found = myClass.LookupAndModify(value, something);
if (found)
{ // item is found in class
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
But rolling LookupAndModify into one method seems like very poor design. It also only modifies if value is found and so the name is not only cumbersome but misleading as well.
Is there another better design that gets round this issue? Any design patterns for this (I couldn't find anything through google)?
Actually std::set<>::insert() does precisely this. If the value exists, it returns the iterator pointing to the existing item. Otherwise, the iterator where the insertion was made is returned.
It is likely that you are using a similar data structure for fast lookups anyway, so a clean public interface (calling site) will be:
myClass.SetAttribute(value, something)
which always does the right thing. MyClass handles the internal plumbing and clients don't worry about whether the value exists.
Two things.
The first solution is close.
Don't however, return ClassItem *. Return an "opaque object". An integer index or other hash code that's opaque (meaningless) to the client, but usable by the myClass instance.
Then lookup returns an index, which modify can subsequently use.
void *index = myClass.lookup( value );
if( index ) {
myClass.modify( index, value );
}
else {
myClass.add( value );
}
After writing the "primitive" Lookup, Modify and Add, then write your own composite operations built around these primitives.
Write a LookupAndModify, TryModify, AddIfNotExists and other methods built from your lower-level pieces.
This assumes that you're setting value to the same "something" in both the Modify and Add cases:
if (!myClass.AddIfNotExists(value, something)) {
// use myClass
}
Otherwise:
if (myClass.TryModify(value, something)) {
// use myClass
} else {
myClass.Add(value, otherSomething);
}