How to inherit fields in a data constructor? - oop

I am new to Haskell and want to realize this C# code in Haskell. I want to inherit the field "title" or make it required to all products, but all examples that I founded are about functions but not fields.
public abstract class Product
{
public string title;
public string getTitle()
{
return title;
}
}
public class Videotape : Product
{
}
public class Book : Product
{
public string authorName;
}

Haskell is not an object-oriented language, so the concept of inheritance does not exist directly. There are numerous approaches toward similar things, and picking the right one would need more context.
One approach would be as follows.
You can look at inheritance in your example as achieving two things:
All subclasses of Product contain a field title
All subclasses of Product support a method getTitle that returns a string.
If we look at both these things as separate, The following solution suggests itself.
First, the product datatype:
data Product = Product { title :: String }
This creates a datatype Product, with a single constructor, also called Product, containing a single field, of type String, called title. title is automatically created as a function of type Product -> String.
Now let's create a typeclass for Product, describing the getTitle method. A typeclass is not the same thing as a class from C#/OOP, but is more similar to the concept of an interface.
class Product' a where
getTitle :: a -> String
This typeclass declares a single method, getTitle, that takes an a, where a is an instance of Product', and returns a String.
Next, we'll define an instance of Product' for Product'.
instance Product' Product where
getTitle = title
This defines Product as an instance of Product' This enable sit to take the place of a where a Product' instance is expected. This means getTitle can be called on Product, so we have to define what that should do. In this case, getTitle should simply do the same as title, i.e. return the title field.
Now let's define the "subclasses":
data Videotape = Videotape { vtProduct :: Product }
data Book = Book { bProduct :: Product, authorName :: String }
We've created two datatypes. Videotape just contains a field of type Product. Book also adds a field of it's own, authorName. (The Product fields have to have unique names. Haskell turns each one into a function, and you can't have two functions with the same name in the same module).
Now let's define instances for these types:
instance Product' Videotape where
getTitle vt = getTitle (vtProduct vt)
instance Product' Book where
getTitle b = getTitle (bProduct b)
You can now call getTitle on an object of either type and get a String corresponding to it's title.
I'm sure there's a lot of terminology and concepts here that are unfamiliar to you, but if you read up about them, you'll likely come to understand how Haskell does many things differently, and broaden your approach to designing and wrting software.
You may find these resources useful:
OOP vs type classes from the Haskell Wiki
Does Haskell support object oriented programming? on SO
Happy Haskelling!

Related

Plural class implementing singular. Is there a name for this design pattern?

Say I have a Product interface with a single method price():
interface Product {
fun price(): Float
}
Now, I create a Products class that implements it:
class Products(private val products: List<Product>): Product {
fun price() : Float {
return products.fold(0f) { acc, fl -> acc + fl }
}
}
Maybe Product is not the best example, but I find this pattern useful when you need to aggregate many products' price in many places of your codebase. This way, that logic is encapsulated in Products class.
I wonder if there is a name for this pattern.
If I understand the code correctly, this looks like an example of the Composite design pattern.
It looks like you've implemented the composite logic using a fold, which is consistent with the observation that the Composite design pattern is isomorphic to monoids, and monoids accumulate. The specific monoid you've used there is the addition monoid.

How to structure object: OOP, composition

I have an object, let's call it a Request, that has associations to several other objects like:
Employee submitter;
Employee subjectsManager;
Employee pointOfContact;
And several value properties like strings, dates, and enums.
Now, I also need to keep track of another object, the subject, but this can be one of 3 different types of people. For simplicity let's just talk about 2 types: Employee and Consultant. Their data comes from different repositories and they have different sets of fields, some overlapping. So say an employee has a
String employeeName;
String employeeId;
String socialSecurityNumber;
Whereas a consultant has
String consultantName;
String socialSecurityNumber;
String phoneNumber;
One terrible idea is that the Request has both a Consultant and an Employee, and setSubject(Consultant) assigns one, setSubject(Employee) assigns the other. This sounds awful. One of my primary goals is to avoid "if the subject is this type then do this..." logic.
My thought is that perhaps an EmployeeRequest and a ConsultantRequest should extend Request, but I'm not sure how, say, setSubject would work. I would want it to be an abstract method in the base class but I don't know what the signature would be since I don't know what type the parameter would be.
So then it makes sense to go at it from an interface perspective. One important interface is that these Request objects will be passed to a single webservice that I don't own. I will have to map the object's fields in a somewhat complex manner that partially makes sense. For fields like name and SSN the mapping is straightforward, but many of the fields that don't line up across all types of people are dumped into a concatenated string AdditionalInfo field (wump wump). So they'll all have a getAdditionalInfo method, a getName, etc, and if there's any fields that don't line up they can do something special with that one.
So that makes me feel like the Request itself should not necessarily be subclassed but could contain a reference to an ISubjectable (or whatever) that implements the interface needed to get the values to send across the webservice. This sounds pretty decent and prevents a lot of "if the subject is an employee then do this..."
However, I would still at times need to access the additional fields that only a certain type of subject has, for example on a display or edit page, so that brings me right back to "if subject is instance of an employee then go to the edit employee page..." This may be unavoidable though and if so I'm ok with that.
Just for completeness I'll mention the "union of all possible fields" approach -- don't think I'd care to do that one either.
Is the interface approach the most sensible or am I going about it wrong? Thanks.
A generic solution comes to mind; that is, if the language you're using supports it:
class Request<T extends Subject> {
private T subject;
public void setSubject(T subject) {
this.subject = subject;
}
public T getSubject() {
return subject;
}
}
class EmployeeRequest extends Request<Employee> {
// ...
}
class ConsultantRequest extends Request<Consultant> {
// ...
}
You could similarly make the setSubject method abstract as you've described in your post, and then have separate implementations of it in your subclasses. Or you may not even need to subclass the Request class:
Request<Employee> employeeRequest = new Request<>();
employeeRequest.setSubject(/* ... */);
// ...
int employeeId = employeeRequest.getSubject().getEmployeeId();

OOP where to put orphan methods

Apologies if this has been answered elsewhere, my search didn't yield quite the answer I was looking for.
Hypothetically speaking, let us say I am building an application for a bookshop.
I have a class that handles all my database transactions. I also have a 'Book' class which extends the Database class, calling the Database constructor from it's own constructor, removing the need to instantiate the Database class first:
class Book extends Database {
__construct($book_id){
parent::__construct();
$this->databaseGet("SELECT * FROM..."); // method in Database class
etc...
}
}
I can pass a reference id to the 'Book' class constructor and create an object containing information pulled from the database about that book along with several methods relevant to a given book.
But I also want to list all the books in the database. My question is, where do I put this method and other methods that simply don't have a context such as 'Book'?
I could create a single "GetStuff" or 'Bookshop' class that extends the Database class, which would contain all these single-use methods. But that requires it to be loaded all the time as these orphan methods would be used all over the program.
I could create lots of classes that house a single method but that would require instantiating the class to an object in order to call the method, seems like overkill.
They aren't general utilities, they have a place in the business model. Just where should I put these orphan methods?
If I understand it, you're asking where should code go that relates to a specific type but doesn't implement a behaviour of the type itself. There is no single answer. According to the overall design of the system, it could be part of the type - Smalltalk classes have 'class fields' and 'instance fields', and there is nothing wrong with that - or it could end up anywhere it makes sense. If it relates to something external to the type itself - that is, it's not merely a matter of not being the behaviour of an instance, but a matter of being an interaction with something extraneous - it may make sense to put it outside. For instance, you may have Book, BookDatabase, BookForm, BookWebService, etc. There's no harm in some of those classes having few members, you never know when you'll want to add some more.
Book is a book, Books is collection of books.
Database is one thing you could use to persist a lot of books so you don't have to type them all in again.
It could be an xml file, an excel spreadsheet, even a webservice.
So write Book and Books, then write something like
BookDatabase extends database with methods like
Books GetBooks();
and
void SaveBook(Book argBook);
The real trick is to make Book and Books work no matter what / how they are stored.
There's lot more to learn around that, but first thing to do is start again and not make your data objects dependant on a particular "database".
Seems your design is seriously flawed. You have to separate three concerns:
Your Domain Layer (DM): In this case, Book belongs to it.
Data Access Layer (DAL): Handles database storage. Domain Layer does not know about this layer at all.
Service Layer (SL): handles use cases. A use case may involve multiple object from Domain, as well as calls to DAL to save or retrieve data. Methods in service layer perform a unit of work.
A simplified example:
// Model Object
class Book {
title;
author:
isbn;
constructor(title, author, isbn) {// ...}
// other methods ...
}
// DAL class
class BookDataMapper {
// constructors ...
save(Book book) {}
Book getById(id) {
String query = get from book table where book_id = id;
execute query;
parse the result;
Book book = new Book(parsed result);
return book;
}
Book getByTitle(title) {}
...
getAll(){} // returns all books
}
//Service class
class BookService {
BookDataMapper bookMapper;
buyBook(title) {
// check user account
// check if book is available
Book book = bookMapper.getBytitle(title);
if book available
charge customer
send the book to ship etc.
}
}

Inheritance vs enum properties in the domain model

I had a discussion at work regarding "Inheritance in domain model is complicating developers life". I'm an OO programmer so I started to look for arguments that having inheritance in domain model will ease the developer life actually instead of having switches all over the place.
What I would like to see is this :
class Animal {
}
class Cat : Animal {
}
class Dog : Animal {
}
What the other colleague is saying is :
public enum AnimalType {
Unknown,
Cat,
Dog
}
public class Animal {
public AnimalType Type { get; set; }
}
How do I convince him (links are WELCOME ) that a class hierarchy would be better than having a enum property for this kind of situations?
Thanks!
Here is how I reason about it:
Only use inheritance if the role/type will never change.
e.g.
using inheritance for things like:
Fireman <- Employee <- Person is wrong.
as soon as Freddy the fireman changes job or becomes unemployed, you have to kill him and recreate a new object of the new type with all of the old relations attached to it.
So the naive solution to the above problem would be to give a JobTitle enum property to the person class.
This can be enough in some scenarios, e.g. if you don't need very complex behaviors associated with the role/type.
The more correct way would be to give the person class a list of roles.
Each role represents e.g an employment with a time span.
e.g.
freddy.Roles.Add(new Employement( employmentDate, jobTitle ));
or if that is overkill:
freddy.CurrentEmployment = new Employement( employmentDate, jobTitle );
This way , Freddy can become a developer w/o we having to kill him first.
However, all my ramblings still haven't answered if you should use an enum or type hierarchy for the jobtitle.
In pure in mem OO I'd say that it's more correct to use inheritance for the jobtitles here.
But if you are doing O/R mapping you might end up with a bit overcomplex data model behind the scenes if the mapper tries to map each sub type to a new table.
So in such cases, I often go for the enum approach if there is no real/complex behavior associated with the types.
I can live with a "if type == JobTitles.Fireman ..." if the usage is limited and it makes things easer or less complex.
e.g. the Entity Framework 4 designer for .NET can only map each sub type to a new table. and you might get an ugly model or alot of joins when you query your database w/o any real benefit.
However I do use inheritance if the type/role is static.
e.g. for Products.
you might have CD <- Product and Book <- Product.
Inheritance wins here because in this case you most likely have different state associated with the types.
CD might have a number of tracks property while a book might have number of pages property.
So in short, it depends ;-)
Also, at the end of the day you will most likely end up with a lot of switch statements either way.
Let's say you want to edit a "Product" , even if you use inheritance, you will probably have code like this:
if (product is Book)
Response.Redicted("~/EditBook.aspx?id" + product.id);
Because encoding the edit book url in the entity class would be plain ugly since it would force your business entites to know about your site structure etc.
Having an enum is like throwing a party for all those Open/Closed Principle is for suckers people.
It invites you to check if an animal is of a certain type and then apply custom logic for each type. And that can render horrible code, which makes it hard to continue building on your system.
Why?
Doing "if this type, do this, else do that" prevents good code.
Any time you introduce a new type, all those ifs get invalid if the new type is not handled. In larger systems, it's hard to find all those ifs, which will lead to bugs eventually.
A much better approach is to use small, well-defined feature interfaces (Interface segregation principle).
Then you will only have an if but no 'else' since all concretes can implement a specific feature.
Compare
if (animal is ICanFly flyer)
flyer.Sail();
to
// A bird and a fly are fundamentally different implementations
// but both can fly.
if (animal is Bird b)
b.Sail();
else if (animal is Fly f)
b.Sail();
See? the former one needs to be checked once while the latter has to be checked for every animal that can fly.
Enums are good when:
The set of values is fixed and never or very rarely changes.
You want to be able to represent a union of values (i.e. combining flags).
You don't need to attach other state to each value. (Java doesn't have this limitation.)
If you could solve your problem with a number, an enum is likely a good fit and more type safe. If you need any more flexibility than the above, then enums are likely not the right answer. Using polymorphic classes, you can:
Statically ensure that all type-specific behavior is handled. For example, if you need all animals to be able to Bark(), making Animal classes with an abstract Bark() method will let the compiler check for you that each subclass implements it. If you use an enum and a big switch, it won't ensure that you've handled every case.
You can add new cases (types of animals in your example). This can be done across source files, and even across package boundaries. With an enum, once you've declared it, it's frozen. Open-ended extension is one of the primary strengths of OOP.
It's important to note that your colleague's example is not in direct opposition to yours. If he wants an animal's type to be an exposed property (which is useful for some things), you can still do that without using an enum, using the type object pattern:
public abstract class AnimalType {
public static AnimalType Unknown { get; private set; }
public static AnimalType Cat { get; private set; }
public static AnimalType Dog { get; private set; }
static AnimalType() {
Unknown = new AnimalType("Unknown");
Cat = new AnimalType("Cat");
Dog = new AnimalType("Dog");
}
}
public class Animal {
public AnimalType Type { get; set; }
}
This gives you the convenience of an enum: you can do AnimalType.Cat and you can get the type of an animal. But it also gives you the flexibility of classes: you can add fields to AnimalType to store additional data with each type, add virtual methods, etc. More importantly, you can define new animal types by just creating new instances of AnimalType.
I'd urge you to reconsider: in an anemic domain model (per the comments above), cats don't behave differently than dogs, so there's no polymorphism. An animal's type really is just an attribute. It's hard to see what inheritance buys you there.
Most importantly OOPS means modeling reality. Inheritance gives you the opportunity to say Cat is an animal. Animal should not know if its a cat now shout it and then decide that it is suppose to Meow and not Bark, Encapsulation gets defeated there. Less code as now you do not have to do If else as you said.
Both solutions are right.
You should look which techniques applies better to you problem.
If your program uses few different objects, and doesn't add new classes, its better to stay with enumerations.
But if you program uses a lot of different objects (different classes), and may add new classes, in the future, better try the inheritance way.

Type conversion when iterating over a collection of super-type. Alternatives?

This is quite a common problem I run into. Let's hear your solutions. I'm going to use an Employee-managing application as an example:-
We've got some entity classes, some of which implement a particular interface.
public interface IEmployee { ... }
public interface IRecievesBonus { int Amount { get; } }
public class Manager : IEmployee, IRecievesBonus { ... }
public class Grunt : IEmployee /* This company sucks! */ { ... }
We've got a collection of Employees that we can iterate over. We need to grab all the objects that implement IRecievesBonus and pay the bonus.
The naive implementation goes something along the lines of:-
foreach(Employee employee in employees)
{
IRecievesBonus bonusReciever = employee as IRecievesBonus;
if(bonusReciever != null)
{
PayBonus(bonusReciever);
}
}
or alternately in C#:-
foreach(IRecievesBonus bonusReciever in employees.OfType<IRecievesBonus>())
{
PayBonus(bonusReciever);
}
We cannot modify the IEmployee interface to include details of the child type as we don't want to pollute the super-type with details that only the sub-type cares about.
We do not have an existing collection of only the subtype.
We cannot use the Visitor pattern because the element types are not stable. Also, we might have a type which implements both IRecievesBonus and IDrinksTea. Its Accept method would contain an ambiguous call to visitor.Visit(this).
Often we're forced down this route because we can't modify the super-type, nor the collection e.g. in .NET we may need to find all the Buttons on this Form via the child Controls collection. We may need to do something to the child types that depends on some aspect of the child type (e.g. the bonus amount in the example above).
Strikes me as odd that there isn't an "accepted" way to do this, given how often it comes up.
1) Is the type conversion worth avoiding?
2) Are there any alternatives I haven't thought of?
EDIT
Péter Török suggests composing Employee and pushing the type conversion further down the object tree:-
public interface IEmployee
{
public IList<IEmployeeProperty> Properties { get; }
}
public interface IEmployeeProperty { ... }
public class DrinksTeaProperty : IEmployeeProperty
{
int Sugars { get; set; }
bool Milk { get; set; }
}
foreach (IEmployee employee in employees)
{
foreach (IEmployeeProperty property in employee.Propeties)
{
// Handle duplicate properties if you need to.
// Since this is just an example, we'll just
// let the greedy ones have two cups of tea.
DrinksTeaProperty tea = property as DrinksTeaProperty;
if (tea != null)
{
MakeTea(tea.Sugers, tea.Milk);
}
}
}
In this example it's definitely worth pushing these traits out of the Employee type - particularly because some managers might drink tea and some might not - but we still have the same underlying problem of the type conversion.
Is it the case that it's "ok" so long as we do it at the right level? Or are we just moving the problem around?
The holy grail would be a variant on the Visitor pattern where:-
You can add element members without modifying all the visitors
Visitors should only visit types they're interested in visiting
The visitor can visit the member based on an interface type
Elements might implement multiple interfaces which are visited by different visitors
Doesn't involve casting or reflection
but I appreciate that's probably unrealistic.
I would definitely try to resolve this with composition instead of inheritance, by associating the needed properties/traits to Employee, instead of subclassing it.
I can give an example partly in Java, I think it's close enough to your language (C#) to be useful.
public enum EmployeeProperty {
RECEIVES_BONUS,
DRINKS_TEA,
...
}
public class Employee {
Set<EmployeeProperty> properties;
// methods to add/remove/query properties
...
}
And the modified loop would look like this:
foreach(Employee employee in employees) {
if (employee.getProperties().contains(EmployeeProperty.RECEIVES_BONUS)) {
PayBonus(employee);
}
}
This solution is much more flexible than subclassing:
it can trivially handle any combination of employee properties, while with subclassing you would experience a combinatorial explosion of subclasses as the number of properties grow,
it trivially allows you to change Employee properties runtime, while with subclassing this would require changing the concrete class of your object!
In Java, enums can have properties or (even virtual) methods themselves - I don't know whether this is possible in C#, but in the worst case, if you need more complex properties, you can implement them with a class hierarchy. (Even in this case, you are not back to square one, since you have an extra level of indirection which gives you the flexibility described above.)
Update
You are right that in the most general case (discussed in the last sentence above) the type conversion problem is not resolved, just pushed one level down on the object graph.
In general, I don't know a really satisfying solution to this problem. The typical way to handle it is using polymorphism: pull up the common interface and manipulate the objects via that, thus eliminating the need for downcasts. However, in cases when the objects in question do not have a common interface, what to do? It may help to realize that in these cases the design does not reflect reality well: practically, we created a marker interface solely to enable us to put a bunch of distinct objects into a common collection, but there is no semantical relationship between the objects.
So I believe in these cases the awkwardness of downcasts is a signal that there may be a deeper problem with our design.
You could implement a custom iterator that only iterates over the IRecievesBonus types.