Avoid multiple if-else statements in a factory class [language agnostic] - oop

I have some data that I'm trying to sift through and I can't figure out a smart way of doing this. Let's say I have 3 types:
A, B, C and they all extend a class S.
If I create a factory that just creates and returns and object of type S, it seems like it would be very procedural. The factory's implementation in pseudo-code would be something like this:
class Factory {
func create_obj(input_data) -> S {
if type(input_data) is A {
return A()
}
else if type(input_data) is B {
return B()
}
else {
return C()
}
}
}
Now, I have a lot of different data types that it could possibly be. That means this algorithm in the worst case is in quadratic time. Is there a better solution, design pattern, or any optimizations I can look at? To be more specific, I'm creating instances of certain data types and the input is lines of text.

One way to approach the problem would be to use a pre-populated associative array where the key is a string representing a line/value in the file and the value is the object that should be returned for that line.
Sample implementation :
Let file be an asscociateive array. On startup, the factory should pre-populate this array with string to object mappings :
files["A"] = new A();
files["B"] = new B();
files["C"] = new C();
The factory can then be passed a string which it will lookup in the associative array to fetch the corresponding pre-populated object :
func create_obj(input_data) -> S {
return files[input_data];
}

Related

How to get value from another class's function in Kotlin

Like
class A {
public var tip : String = ""
}
class B {
val tip2 = A().tip
println(tip2)
}
class C {
tiper("abc")
tiper("def")
tiper("ghi")
fun tiper(txt) {
A().tip = txt
B.showTip()
}
}
To be brief, I have a class B, which outputs a 'tip'. There is class C, which creates the text for the 'tip'. And I need to send a value from class C to class B. I tried doing it through class A, sending the value there and then reading it in class B to display it.
But in this case it just displays the value "", i.e. by default from class A.
Why isn't the value passed by class C taken instead?
The above code is greatly simplified and is a hypothetical description of what I actually have in my code. This is just an abstract example.
I'm a terrible Kotlin programmer, I was just asked to do this one job, so I don't know much about it, hope for your help.
You're creating a new object from type A every time you call it's constructor A().
Thus, inside tiper, you're creating an object of type A and setting the tip value on that object instance.
Then however, you create an object of type B which creates a new object of type A internally. This has no link to the first object of type A you've created. Thus, it does not contain the value you wanted to set but rather the default you've set, which is the empty string "".
Keeping close to our example, you can instead adjust the value on the object of type A that is embedded in the object of type B.
class A {
var tip: String = ""
}
class B() {
val tipHolder = A()
fun showTip() {
println(tipHolder.tip)
}
}
fun tiper(txt: String) {
val tipPrinter = B()
tipPrinter.tipHolder.tip = txt
tipPrinter.showTip()
}
fun main() {
tiper("abc")
tiper("def")
tiper("ghi")
}
However, without more details on the actual problem, it's hard to help you with the underlying problem you're trying to solve, as written by #aSemy in the comment section.

Constructors in Go

I have a struct and I would like it to be initialised with some sensible default values.
Typically, the thing to do here is to use a constructor but since go isn't really OOP in the traditional sense these aren't true objects and it has no constructors.
I have noticed the init method but that is at the package level. Is there something else similar that can be used at the struct level?
If not what is the accepted best practice for this type of thing in Go?
There are some equivalents of constructors for when the zero values can't make sensible default values or for when some parameter is necessary for the struct initialization.
Supposing you have a struct like this :
type Thing struct {
Name string
Num int
}
then, if the zero values aren't fitting, you would typically construct an instance with a NewThing function returning a pointer :
func NewThing(someParameter string) *Thing {
p := new(Thing)
p.Name = someParameter
p.Num = 33 // <- a very sensible default value
return p
}
When your struct is simple enough, you can use this condensed construct :
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33}
}
If you don't want to return a pointer, then a practice is to call the function makeThing instead of NewThing :
func makeThing(name string) Thing {
return Thing{name, 33}
}
Reference : Allocation with new in Effective Go.
There are actually two accepted best practices:
Make the zero value of your struct a sensible default. (While this looks strange to most people coming from "traditional" oop it often works and is really convenient).
Provide a function func New() YourTyp or if you have several such types in your package functions func NewYourType1() YourType1 and so on.
Document if a zero value of your type is usable or not (in which case it has to be set up by one of the New... functions. (For the "traditionalist" oops: Someone who does not read the documentation won't be able to use your types properly, even if he cannot create objects in undefined states.)
Go has objects. Objects can have constructors (although not automatic constructors). And finally, Go is an OOP language (data types have methods attached, but admittedly there are endless definitions of what OOP is.)
Nevertheless, the accepted best practice is to write zero or more constructors for your types.
As #dystroy posted his answer before I finished this answer, let me just add an alternative version of his example constructor, which I would probably write instead as:
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33} // <- 33: a very sensible default value
}
The reason I want to show you this version is that pretty often "inline" literals can be used instead of a "constructor" call.
a := NewThing("foo")
b := &Thing{"foo", 33}
Now *a == *b.
There are no default constructors in Go, but you can declare methods for any type. You could make it a habit to declare a method called "Init". Not sure if how this relates to best practices, but it helps keep names short without loosing clarity.
package main
import "fmt"
type Thing struct {
Name string
Num int
}
func (t *Thing) Init(name string, num int) {
t.Name = name
t.Num = num
}
func main() {
t := new(Thing)
t.Init("Hello", 5)
fmt.Printf("%s: %d\n", t.Name, t.Num)
}
The result is:
Hello: 5
I like the explanation from this blog post:
The function New is a Go convention for packages that create a core type or different types for use by the application developer. Look at how New is defined and implemented in log.go, bufio.go and cypto.go:
log.go
// New creates a new Logger. The out variable sets the
// destination to which log data will be written.
// The prefix appears at the beginning of each generated log line.
// The flag argument defines the logging properties.
func New(out io.Writer, prefix string, flag int) * Logger {
return &Logger{out: out, prefix: prefix, flag: flag}
}
bufio.go
// NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) * Reader {
return NewReaderSize(rd, defaultBufSize)
}
crypto.go
// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
if h > 0 && h < maxHash {
f := hashes[h]
if f != nil {
return f()
}
}
panic("crypto: requested hash function is unavailable")
}
Since each package acts as a namespace, every package can have their own version of New. In bufio.go multiple types can be created, so there is no standalone New function. Here you will find functions like NewReader and NewWriter.
In Go, a constructor can be implemented using a function that returns a pointer to a modified structure.
type Colors struct {
R byte
G byte
B byte
}
// Constructor
func NewColors (r, g, b byte) *Colors {
return &Color{R:r, G:g, B:b}
}
For weak dependencies and better abstraction, the constructor does not return a pointer to a structure, but an interface that this structure implements.
type Painter interface {
paintMethod1() byte
paintMethod2(byte) byte
}
type Colors struct {
R byte
G byte
B byte
}
// Constructor return intreface
func NewColors(r, g, b byte) Painter {
return &Color{R: r, G: g, B: b}
}
func (c *Colors) paintMethod1() byte {
return c.R
}
func (c *Colors) paintMethod2(b byte) byte {
return c.B = b
}
another way is;
package person
type Person struct {
Name string
Old int
}
func New(name string, old int) *Person {
// set only specific field value with field key
return &Person{
Name: name,
}
}
If you want to force the factory function usage, name your struct (your class) with the first character in lowercase. Then, it won't be possible to instantiate directly the struct, the factory method will be required.
This visibility based on first character lower/upper case work also for struct field and for the function/method. If you don't want to allow external access, use lower case.
Golang is not OOP language in its official documents.
All fields of Golang struct has a determined value(not like c/c++), so constructor function is not so necessary as cpp.
If you need assign some fields some special values, use factory functions.
Golang's community suggest New.. pattern names.
I am new to go. I have a pattern taken from other languages, that have constructors. And will work in go.
Create an init method.
Make the init method an (object) once routine. It only runs the first time it is called (per object).
func (d *my_struct) Init (){
//once
if !d.is_inited {
d.is_inited = true
d.value1 = 7
d.value2 = 6
}
}
Call init at the top of every method of this class.
This pattern is also useful, when you need late initialisation (constructor is too early).
Advantages: it hides all the complexity in the class, clients don't need to do anything.
Disadvantages: you must remember to call Init at the top of every method of the class.

How to create a method of a structure in golang that is called automatically?

I have to create a something like a substitute of 2 levels of inheritance in golang, i.e.,
in a package, I have a structure(A), which is inherited(embedded as an anonymous field) by another structure(B) in another package, whose object is to be utilized by the "main" package.
Now, I've created an initializer method for the "B" (BPlease) that returns an object of B (say,B_obj). I can call this initializer(BPlease) from my "main" package at the start of the program.
One of the methods of "B" (say, HelloB()), calls a method of "A"(say,HelloA()) during execution, using "B's" object.
But what I really want is, something like a constructor for "A" that can initialize its fields (preferably when B_obj was created in package "main") before "B" calls any methods of "A".
How to achieve this?
I tried creating an initializer(APlease) for "A" as well and called it (BPlease) to get an object of "A" (A_obj). But I found this object useless as I couldn't utilize it to call "A's" method (HelloA()) inside a method of "B" (HelloB()).
It would be great if someone can tell me how to utilize this object (A_obj).
Here's some code to clarify my query:
package A
type A struct { whatever }
func (A_obj *A) HelloA(){performs some operation...} // a method of A()
func APlease() A {
return A{initialize A fields}
}
-------------------------------------------------------------------------------
package B
type B struct {
A
B fields
}
func BPlease() B {
return B{
A_obj := APlease() // useless to me.... how to utilise this?
initialize B fields}
}
func (B_obj *B) HelloB(){ // a method of B{}
call B_obj.HelloA() // valid as A is an anon field in B struct
some other operations // but A's fields are not initialized for B_obj
...}
---------------------------------------------------
package main
import "B"
import "A"
func main(){
B_obj := B.BPlease() // what I want is, calling this should initialize A's fields for B_obj as well so that when HelloB() calls B_obj.HelloA(), it utilises A's field that have been initialized.
}
I cannot pass all field-values as parameters to B_obj as there are a lot of fields, and also, some field values are generated by calling a method of the same structure.
Regardless of anyone's opinion about fighting the language to have inheritance when it doesn't: No, there are no magic methods, like "getter" or "setter" of whatever. Remotely related (magic powers) are perhaps finalizers, but they're surely not going to help in this case.
However, let me suggest to stop coding language X in Go. Just use Go. Go doesn't use "class-like" inheritance, nor a Go programmer (usually) should. Think of Go like a modernized C. There's no much C code out there relying on inheritance. (OK, I know about GObject ;-)
Some meta-remark: "First structure" and "second structure" make it very hard to understand which one is which. Labeling the different things like A, B and C is the tool which make math so powerful.
Is this your question:
You have two type A and B, B embeds A. You want to make sure B is "fully initialized" in the sense of A is also initialized.
Raw sketch:
type A struct { whatever }
type B struct {
A
more stuff
}
func APlease(params for an A) A {
return A{fields set up from params}
}
func BPlease(params forn an A and for an B) B {
return B{
A: APlease(stuff for A),
more: set from params for B,
}
}
Should do this: You can ask for a proper set up B by calling BPlease with the necessary parameters for both, the embedded A and the rest of B.
To expand on Volker's answer a bit, you should be able to call
func BPlease() B {
a_obj := A.APlease() // initialize the fields of A like normal
b_obj := B{} // create a B, whose anonymous fields are not initialized yet
b_obj.A = a_obj // PERHAPS WHAT YOU WANT: copy all a's fields to b's fields.
// if you are relying sending a_obj's address somewhere in
// APlease(), you may be out of luck.
b_obj.field_unique_to_B = "initialized"
return b_obj
}
Now that you can create B objects with fields initialized by APlease(), you can call A's methods on B's objects, and even call A's methods from within B like so:
func (B_obj *B) HelloB(){
// can't call B_obj.HelloA() like you would expect
B_obj.A.HelloA() // this works. Go "promotes" the anonymous field's methods
// and fields to B_obj
// but they don't appear in B_obj, they appear in B_obj.A
fmt.Printf("And hello from B too; %s", B_obj.field_unique_to_B)
}
I will echo Rick-777 here and suggest you stick to go's naming conventions and idioms; NewReader is much easier to read and understand than ReaderPlease.
I contrived an example that I can put on bitbucket if people want. I think it's much easier to read when you are working with real metaphors; also a disclaimer - this is not the best code, but it does some things that answer your question.
file: car/car.go
package car
import "fmt"
type BaseCar struct {
Doors int // by default, 4 doors. SportsCar will have 2 doors
Wheels int
}
func NewBaseCar() BaseCar {
return BaseCar{Wheels: 4, Doors: 4}
}
// this will be used later to show that a "subclass" can call methods from self.BaseCar
func (c *BaseCar) String() string {
return fmt.Sprintf("BaseCar: %d doors, %d wheels", c.Doors, c.Wheels)
}
// this will be promoted and not redefined
func (c *BaseCar) CountDoors() int {
return c.Doors
}
file sportscar/sportscar.go
package sportscar
// You can think of SportsCar as a subclass of BaseCar. But go does
// not have conventional inheritence, and you can paint yourself into
// a corner if you try to force square c++ structures into round go holes.
import ( "../car" ; "fmt" )
type SportsCar struct {
car.BaseCar // here is the anonymous field
isTopDown bool
}
func NewSportsCar() SportsCar {
conv := SportsCar{} // conv.Wheels == 0
conv.BaseCar = car.NewBaseCar() // now conv.Wheels == conv.Doors == 4
conv.isTopDown = false // SportsCar-only field
conv.Doors = 2 // Fewer Doors than BaseCar
return conv
}
// SportsCar only method
func (s *SportsCar) ToggleTop() {
s.isTopDown = !s.isTopDown
}
// "overloaded" string method note that to access the "base" String() method,
// you need to do so through the anonymous field: s.BaseCar.String()
func (s *SportsCar) String() string {
return fmt.Sprintf("Sports%s, topdown: %t", s.BaseCar.String(), s.isTopDown)
}
file main.go
package main
import ( "./car" ; "./sportscar" ; "fmt")
type Stringer interface { // added this complication to show
String() string // that each car calls its own String() method
}
func main() {
boring := car.NewBaseCar()
fancy := sportscar.NewSportsCar()
fmt.Printf(" %s\n", Stringer(&boring))
fmt.Printf("%s\n", Stringer(&fancy))
fancy.ToggleTop()
fmt.Printf("%s\n", Stringer(&fancy))
fmt.Println("BaseCar.CountDoors() method is callable from a SportsCar:", fancy.CountDoors())
}
There are ways to mimic inheritance in Go if this is what you are looking for, see section "Inheritance" in this blog

Scala class inheritance

Tagged as homework.
I'm having trouble in the object oriented world while trying to implement a class.
I'm implenting various functions to take action on lists, that I'm using to mock a set.
I'm not too worried about my logic on how to find union, for example, but really just the structure.
For eg:
abstract class parentSet[T] protected () {
def union(other:parentSet[T]):parentSet[T]
}
Now I want a new class extending parentSet:
class childSet[T] private (l: List[T]) extends parentSet[T] {
def this() = this(List())
private val elems = l
val toList = List[T] => new List(l)
def union(other:parentSet[T]):childSet[T] = {
for (i <- this.toList) {
if (other contains i) {}
else {l :: i}
}
return l
}
}
Upon compiling, I receive errors such that type childSet isn't found in def union, nor is type T to keep it parametric. Also, I assume my toList isn't correct as it complains that it isn't a member of the object; to name a few.
Where in my syntax am I wrong?
EDIT
Now I've got that figured out:
def U(other:parentSet[T]):childSet[T] = {
var w = other.toList
for (i <- this.toList) {
if (!(other contains i)) {w = i::w}
}
return new childSet(w)
}
Now, I'm trying to do the same operations with map, and this is what I'm working on/with:
def U(other:parentSet[T]):MapSet[T] = {
var a = Map[T,Unit]
for (i <- this.toList) {
if (!(other contains i)) {a = a + (i->())}
}
return new MapSet(elems + (a->()))
}
I still want to use toList to make it easily traversable, but I'm still getting type errors while messing with maps..
This code has a few problems:
It seems that you are not realizing that List[T] is an immutable type, meaning you cannot change its value once created. So if you have a List[T] and you call the :: method to prepend a value, the function returns a new list and leaves your existing one unchanged. Scala has mutable collections such as ListBuffer which may behave more like you expect. So when you return l, you're actually returning the original list.
Also, you have the order wrong in using ::. It should go i :: l, since :: is a right-binding function (because it ends with a :).
Lastly, in your union method you are doing (other contains i). Maybe it's just the Scala syntax that's confusing you, but this is the same as doing (other.contains(i)) and clearly contains is not a defined method of parentSet. It is a method on the List[T] type, but you're not calling contains on a list.
You tagged this as homework so I'm not going to fix your code, but I think you should
Look at some examples of correct Scala code involving lists, try here for starters
Play around in the Scala REPL and try creating and working with some lists, so you get a feel for how immutable collections work.
To answer your direct question, even though childSet is inheriting parentSet the original method specify parentSet as the return type and not childSet. You can either only use parentSet as the type OR you could specify the return type to be anything that inherits parentSet.

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.)