Understanding the relationship between Liskov and OCP - liskov-substitution-principle

I am solidifying my understanding of the relationship between Liskov Substitutional Principal and Open Close Principal. If anybody could confirm my deductions and answer my questions below that would be great.
I have the following classes. As you can see, B is derived from A and it is overriding the DisplayMessage function in order to alter the behavior.
public class A
{
private readonly string _message;
public A(string message)
{
_message = message;
}
public virtual void DisplayMessage()
{
Console.WriteLine(_message);
}
}
public class B : A
{
public B(string message) : base(message){}
public override void DisplayMessage()
{
Console.WriteLine("I'm overwriting the expected behavior of A::DisplayMessage() and violating LSP >:-D");
}
}
Now in my bootstrap program, ShowClassTypeis expecting an object of Type A which should helpfully write out what class Type it is. However B is violating LSP so when it's DisplayMessage function is called it prints a completely unexpected message and essentially interferes with the intended purpose of ShowClassType.
class Program
{
static void Main(string[] args)
{
A a = new A("I am A");
B b = new B("I am B");
DoStuff(b);
Console.ReadLine();
}
private static void ShowClassType(A model)
{
Console.WriteLine("What Class are you??");
model.DisplayMessage();
}
}
So my question is, am I right to conclude that ShowClassType is now violating the Open Close Principal because now that Type B can come in and change the expected function of that method, it is no longer closed for modification (ie. to ensure it maintains it's expected behaviour you would have to alter it so that it first checks to make sure we are only working with an original A object)?
Or, inversely is this just a good example to show that ShowClassType is closed for modification and that by passing in a derived type (albeit a LSP violating one) we have extended what it is meant to do?
Lastly, is it bad practice to create virtual functions on Base classes if the base class is not abstract? By doing so, are we not just inviting derived classes to violate the Liskov Substitution principal?
Cheers

I'd say it's not ShowClassType that is violating the Open/Closed Principle.
It's only class B that is violating the Liskov Substitution Principle. A is Open for extension, but closed for modification.
From Wikipedia,
an entity can allow its behaviour to be modified without altering its source code.
It's obvious that the source code of A is not modified. Nor are private members of A being used (which would also be a violation of the Open/Closed principle in my book). B strictly uses the public interface of A, so although the Open/Closed principle is obeyed the Liskov Substitution Principle is violated.
The last question is worth a discussion in and of itself. A related question on SO is here.

I think it is not violate not LSP and not OCP in THIS context of using.
For my opinion, ShowClassType not violation OCP:
1. Function can not break OCP, only class architecture can do this.
2. You can add new behaviours to derived classes from A - so it do not break OCP
What about LSP? Your reason - user not expected get this message? But he got some message! If function overriding returns some message i think is ok in THIS context of your code.
If function, that add two numbers is overrides, and 1+1 returns 678 it not expectable for me and is bad. BUT, if for scientist of Physics from Mars planet it can be good answer.
DO NOT ANALYSE PROBLEM WITHOUT ALL CONTEXT!!! You must get whole picture of problem. And, of course

Related

Which design pattern violation does this bug do and what to call it?

There is a singleton service class ItemsDataSource: IItemsDataSource injected into many other classes (business domain classes)
These business domain classes are many and run asynchronously calling methods on that ItemsDataSource service.
public interface IItemsDataSource
{
Task<IEnumerable<string>> GetItemsAsync();
void SetSourceConfiguration(JToken src);
}
public class ItemsDataSource : IItemsDataSource
{
private JToken m_configuration;
public Task<IEnumerable<string>> GetItemsAsync()
{
// Use m_configuration to some items
}
public void SetSourceConfiguration(JToken config)
{
m_configuration = src;
}
}
When multiple classes that are using this service are running asynchronously (let's say on 2 threads T1 and T2), this is sometimes happening:
T1 calls SetSourceConfiguration(config1) then starts running GetItemsAsync() asynchronously.
T2 calls SetSourceConfiguration(config2) (m_configuration is now assigned with config2) before T1 is done running GetItemsAsync(). For that T1 uses config2 instead of config1 and unexpected behavior happens.
The questions:
1- The optimal fix I think is removing SetSourceConfiguration and passing the JToken config directly as parameter into GetItemsAsync, or locking the code in the business classes, or is there another better solution ?
2- Which design pattern violation caused this bug ? So It could be avoided in the first place.
3- What is the "technical" term for this bug ? Methods with Side Effects, Design pattern violation, etc. ?
1- The optimal fix I think is removing SetSourceConfiguration and
passing the JToken config directly as parameter into GetItemsAsync, or
locking the code in the business classes, or is there another better
solution ?
If your service ItemsDataSource is not singleton service, you can remove SetSourceConfiguration and passing the JToken config directly as parameter into GetItemsAsync. However, it is singleton service, so the way to go, imho, is using lock of critical section.
The code would look like this, if you are using C#.
private readonly object myLock = new object();
public void Foo()
{
lock (myLock )
{
// critical section of code here
}
}
Read more about lock here
2- Which design pattern violation caused this bug ? So It could be
avoided in the first place.
It is not pattern. It is race condition. A race condition occurs when two or more threads can access shared data and they try to change it at the same time.
3- What is the "technical" term for this bug ? Methods with Side
Effects, Design pattern violation, etc. ?
It is race condition.

Exception reason/message. Am I reinventing the wheel here?

I want some kind of mechanism to have more information about a caught exception. (Specifically exceptions I throw myself to abort transactions) I've looked around and pretty much the only thing I could find was "Use the info log". This to me does not seem like a good idea. For one it is cumbersome to access and find the last message. And it is limited in size so at some point the new messages won't even show up.
So my idea is the following: Create a class NuException and pass an instance of that through all methods store an instance in the class where the work methods are located. When I need to throw an exception I call a method on it similar to Global::error() but this one takes an identifier and a message.
Once I reach my catch block I can access those from my object the class that contains the work methods similarly to how CLRExceptions work.
class NuException
{
"public" str identifier;
"public" str message;
public Exception error(str _id, str _msg)
{
//set fields
return Exception::Error;
}
}
class Worker
{
"public" NuException exception;
void foo()
{
throw this.exception.error("Foo", "Record Foo already exists");
}
void bar()
{
this.foo();
}
}
void Job()
{
Worker w = new Worker();
try
{
w.bar(ex);
}
catch (Exception::Error)
{
info(w.exception().message());
}
}
It works but isn't there a better way? Surely someone must have come up with a solution to work around this shortcoming in AX?
Short answer: yes.
While your "brilliant" scheme "works", it gets boring pretty fast, as you now must transport your NuException object deep down 20 level from the listener (job) to the thrower (foo). Your bar method and other middle men has no interest or knowledge about your exception scheme but must pass it on anyway.
This is no longer the case after the update.
There are several ways to go.
Use an observer pattern like the Event broker or in AX 2012 and newer use delegates.
Stick to the infolog system and you use an InfoAction class to peggy bag your information to be used later. It can be used to display a stack trace or other interesting information.
Use a dedicated table for logging.
The third way may seem impractical, as any errors will undo the insert in the log. This is the default behavior but can be circumvented.
MyLogTable log;
Connection con = new UserConnection();
con.ttsBegin();
log.setConnection(con);
... // Set your fields
log.insert();
con.ttsCommit();
Your way to go depends on circumstances you do not mention.

Solution for asynchronous notification upon future completion in GridGain needed

We are evaluating Grid Gain 6.5.5 at the moment as a potential solution for distribution of compute jobs over a grid.
The problem we are facing at the moment is a lack of a suitable asynchronous notification mechanism that will notify the sender asynchronously upon job completion (or future completion).
The prototype architecture is relatively simple and the core issue is presented in the pseudo code below (the full code cannot be published due to an NDA). *** Important - the code represents only the "problem", the possible solution in question is described in the text at the bottom together with the question.
//will be used as an entry point to the grid for each client that will submit jobs to the grid
public class GridClient{
//client node for submission that will be reused
private static Grid gNode = GridGain.start("config xml file goes here");
//provides the functionality of submitting multiple jobs to the grid for calculation
public int sendJobs2Grid(GridJob[] jobs){
Collection<GridCallable<GridJobOutput>> calls = new ArrayList<>();
for (final GridJob job : jobs) {
calls.add(new GridCallable<GridJobOutput>() {
#Override public GridJobOutput call() throws Exception {
GridJobOutput result = job.process();
return result;
}
});
}
GridFuture<Collection<GridJobOutput>> fut = this.gNode.compute().call(calls);
fut.listenAsync(new GridInClosure<GridFuture<Collection<GridJobOutput>>>(){
#Override public void apply(GridFuture<Collection<GridJobOutput>> jobsOutputCollection) {
Collection<GridJobOutput> jobsOutput;
try {
jobsOutput = jobsOutputCollection.get();
for(GridJobOutput currResult: jobsOutput){
//do something with the current job output BUT CANNOT call jobFinished(GridJobOutput out) method
//of sendJobs2Grid class here
}
} catch (GridException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
return calls.size();
}
//This function should be invoked asynchronously when the GridFuture is
//will invoke some processing/aggregation of the result for each submitted job
public void jobFinished(GridJobOutput out) {}
}
}
//represents a job type that is to be submitted to the grid
public class GridJob{
public GridJobOutput process(){}
}
Description:
The idea is that a GridClient instance will be used to in order to submit a list/array of jobs to the grid, notify the sender how many jobs were submitted and when the jobs are finished (asynchronously) is will perform some processing of the results. For the results processing part the "GridClient.jobFinished(GridJobOutput out)" method should be invoked.
Now getting to question at hand, we are aware of the GridInClosure interface that can be used with "GridFuture.listenAsync(GridInClosure> lsnr)"
in order to register a future listener.
The problem (if my understanding is correct) is that it is a good and pretty straightforward solution in case the result of the future is to be "processed" by code that is within the scope of the given GridInClosure. In our case we need to use the "GridClient.jobFinished(GridJobOutput out)" which is out of the scope.
Due to the fact that GridInClosure has a single argument R and it has to be of the same type as of GridFuture result it seems impossible to use this approach in a straightforward manner.
If I got it right till now then in order to use "GridFuture.listenAsync(..)" aproach the following has to be done:
GridClient will have to implement an interface granting access to the "jobFinished(..)" method let's name it GridJobFinishedListener.
GridJob will have to be "wrapped" in new class in order to have an additional property of GridJobFinishedListener type.
GridJobOutput will have to be "wrapped" in new class in order to have an addtional property of GridJobFinishedListener type.
When the GridJob will be done in addition to the "standard" result GridJobOutput will contain the corresponding GridJobFinishedListener reference.
Given the above modifications now GridInClosure can be used now and in the apply(GridJobOutput) method it will be possible to call the GridClient.jobFinished(GridJobOutput out) method through the GridJobFinishedListener interface.
So if till now I got it all right it seems a bit clumsy work around so I hope I have missed something and there is a much better way to handle this relatively simple case of asynchronous call back.
Looking forward to any helpful feedback, thanks a lot in advance.
Your code looks correct and I don't see any problems in calling jobFinished method from the future listener closure. You declared it as an anonymous class which always has a reference to the external class (GridClient in your case), therefore you have access to all variables and methods of GridClient instance.

Page Objects - level of abstraction for methods

I searched around on the internet a bit but thought I might get some insight by just posting on stackoverflow and seeing if there were any opinions out there.
I'm wondering if anyone has an opinion of which is preferred between these two ways of setting up a page object:
public class LoginPage extends PageObject{
public void typeEmail(String email){
driver.findElement(EMAIL_SELECTOR).sendKeys(email);
}
public void typePassword(String pw){
driver.findElement(PASSWORD_SELECTOR).sendKeys(email);
}
public void submit(){
driver.findElement(SUBMIT_SELECTOR).click();
}
}
...and...
public class LoginPage extends PageObjects{
public void login(String email, String password){
driver.findElement(EMAIL_SELECTOR).sendKeys(email);
driver.findElement(PASSWORD_SELECTOR).sendKeys(email);
driver.findElement(SUBMIT_SELECTOR).click();
}
}
Originally, I thought the second way would be better since if the login flow changes for some reason (this is unlikely with a login, but you could theorize this happening for other types of forms), you could update the login() method and this change would affect all the tests which required login.
However, if you want to verify error conditions or more things before submit(), the second solution isn't flexible enough.
Any insights would be welcome.
Page object definition : "A PageObject need not represent an entire page. It may represent a section that appears many times within a site or page, such as site navigation."
The keys points of a PageObject :
- The public methods represent the services that the page offers
- Try not to expose the internals of the page
- Generally don't make assertions
- Methods return other PageObjects
- Need not represent an entire page
- Different results for the same action are modelled as different methods
SOURCE
Your two settings aren't PageObject but there is some similarities.
Personally I prefer to use another level of abstraction like:
public void typeEmail(String email){
fillField(EMAIL_SELECTOR, email);
}
And an implementation in your SeleniumWrapper class
public void fillField(WebElement selector, String text){
driver.findElement(selector).sendKeys(text);
}
This makes code more good-looking
This is not directly related to PageObjects, but still this is a way to prettify your code if you dont use BDD, or keyword-driven approach

strongly typed sessions in asp.net

Pardon me if this question has already been asked. HttpContext.Current.Session["key"] returns an object and we would have to cast it to that particular Type before we could use it. I was looking at various implementations of typed sessions
http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx
http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx
http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx
and I felt that we needed to add some more code (correct me if I was wrong) to the SessionManager if we wanted to add a new Type of object into session, either as a method or as a separate wrapper. I thought we could use generics
public static class SessionManager<T> where T:class
{
public void SetSession(string key,object objToStore)
{
HttpContext.Current.Session[key] = objToStore;
}
public T GetSession(string key)
{
return HttpContext.Current.Session[key] as T;
}
}
Is there any inherent advantage in
using
SessionManager<ClassType>.GetSession("sessionString")
than using
HttpContext.Current.Session["sessionString"] as ClassType
I was also thinking it would be nice
to have something like
SessionManager["sessionString"] = objToStoreInSession,
but found that a static class cannot have an indexer. Is there any other way to achieve this ?
My thought was create a SessionObject which would store the Type and the object, then add this object to Session (using a SessionManager), with the key. When retrieving, cast all objects to SessionObject ,get the type (say t) and the Object (say obj) and cast obj as t and return it.
public class SessionObject { public Type type {get;set;} public Object obj{get;set;} }
this would not work as well (as the return signature would be the same, but the return types will be different).
Is there any other elegant way of saving/retrieving objects in session in a more type safe way
For a very clean, maintainable, and slick way of dealing with Session, look at this post. You'll be surprised how simple it can be.
A downside of the technique is that consuming code needs to be aware of what keys to use for storage and retrieval. This can be error prone, as the key needs to be exactly correct, or else you risk storing in the wrong place, or getting a null value back.
I actually use the strong-typed variation, since I know what I need to have in the session, and can thus set up the wrapping class to suit. I've rather have the extra code in the session class, and not have to worry about the key strings anywhere else.
You can simply use a singleton pattern for your session object. That way you can model your entire session from a single composite structure object. This post refers to what I'm talking about and discusses the Session object as a weakly typed object: http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html
Actually, if you were looking to type objects, place the type at the method level like:
public T GetValue<T>(string sessionKey)
{
}
Class level is more if you have the same object in session, but session can expand to multiple types. I don't know that I would worry about controlling the session; I would just let it do what it's done for a while, and simply provide a means to extract and save information in a more strongly-typed fashion (at least to the consumer).
Yes, indexes wouldn't work; you could create it as an instance instead, and make it static by:
public class SessionManager
{
private static SessionManager _instance = null;
public static SessionManager Create()
{
if (_instance != null)
return _instance;
//Should use a lock when creating the instance
//create object for _instance
return _instance;
}
public object this[string key] { get { .. } }
}
And so this is the static factory implementation, but it also maintains a single point of contact via a static reference to the session manager class internally. Each method in sessionmanager could wrap the existing ASP.NET session, or use your own internal storage.
I posted a solution on the StackOverflow question is it a good idea to create an enum for the key names of session values?
I think it is really slick and contains very little code to make it happen. It needs .NET 4.5 to be the slickest, but is still possible with older versions.
It allows:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
to work exactly like:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;

Resources