I have an entity named "Task". For this entity I can create multiply entities, called "Comment". I want also to have a method named "CreateComment". According to the Domain Driven Design, the entity "Comment" can not exist without creating an instance of "Task" class. And my question is: where this method should be placed: in the Task class or in the Comment class? should it be like Comment.CreateComment or Task.CreateComment. If I put this method to the Task class, would it be the Single responsibility principle violation?
I believe that the method should be be on the Task entity. But that being said the method should not be Create but rather Add as I do not believe it is a responsibility of the Task object to create a comment. Instead I'd use something like this, which is an overkill but mostly because I like a progress fluent interface and the object builder pattern :)
Task class, pretty self explanatory
public class Task
{
private readonly IList<Comment> Comments = new List<Comment>();
public void AddComment(ICommentBuilderFinalization commentBuilder)
{
Comments.Add(commentBuilder.MakeComment());
}
}
Comment class, pretty self explanatory once again
public class Comment
{
public string Text { get; set; }
public string PostedBy { get; set; }
public DateTime PostedAt { get; set; }
}
The object builder and progressive fluent interfaces
// First progressive interface
public interface ICommentBuilder
{
ICommentBuilderPostBy PostWasMadeNow();
ICommentBuilderPostBy PostWasMadeSpecificallyAt(DateTime postedAt);
}
// Second progressive interface
public interface ICommentBuilderPostBy
{
ICommentBuilderPostMessage By(string postedBy);
}
// Third progressive interfacve
public interface ICommentBuilderPostMessage
{
ICommentBuilderFinalization About(string message);
}
// Final
public interface ICommentBuilderFinalization
{
Comment MakeComment();
}
// implementation of the various interfaces
public class CommentBuilder : ICommentBuilder, ICommentBuilderPostBy, ICommentBuilderPostMessage, ICommentBuilderFinalization
{
private Comment InnerComment = new Comment();
public Comment MakeComment()
{
return InnerComment;
}
public ICommentBuilderFinalization About(string message)
{
InnerComment.Text = message;
return this;
}
public ICommentBuilderPostMessage By(string postedBy)
{
InnerComment.PostedBy = postedBy;
return this;
}
public ICommentBuilderPostBy PostWasMadeNow()
{
InnerComment.PostedAt = DateTime.Now;
return this;
}
public ICommentBuilderPostBy PostWasMadeSpecificallyAt(DateTime postedAt)
{
InnerComment.PostedAt = postedAt;
return this;
}
}
Putting it all together
var task = new Task();
var commentBuilder = new CommentBuilder().PostWasMadeNow().By("Some User").About("Some Comment");
task.AddComment(commentBuilder);
Ok, so as I mentioned earlier this example is way over engineered for most situations. But it should give you an idea as to what you can do to stay true to the Single Responsibility Principle.
According to GRASP, principles
class B should be responsible for creating instances of class A if one, or preferably more, of the following apply:
Instances of B contain or compositely aggregate instances of A
Instances of B record instances of A
Instances of B closely use instances of A
Instances of B have the initializing information for instances of A and pass it on creation.
From your description it sounds like at least 3 of those points are pertinent. Therefore I would say that Task is responsible for creating Comment.
Related
I'm deserializing some JSON responses and putting them into one of two primary classes depending on if a single object is returned or if a list of objects is returned. I'm currently using
public class MultiResponse
{
public List<DeserializedResult> Result { get; set; }
}
public class SingleResponse
{
public DeserializedResult Result { get; set; }
}
public class DeserializedResult
{
public string Id { get; set; }
public string AccountName { get; set; }
}
to contain the response(s). However I know it's not the best way, especially since I'm having to use a dynamic return in the calling class to deal with the two types of responses possible. I think an abstract class (or interface?) is a better way to do this, but I don't know how to implement it. Am I on the right track & if so, how do I construct the abstract class and do the inheritance?
Create a design based on multi responses - i.e. holding / returning a list even if when there is only one object. It eliminates the design "hint" that there is a special case somehow. And The resulting code will be more consistent and robust.
The focus should be on the object itself - what you do with it after re-hydration. Not on the trivial happenstance that I have one object or more than one. That distinction is no different that "4 objects or not 4 objects."
Abstracting the container to a single class necessarily makes working with the objects the focus, the emphasis of your design.
edit
Think of it this way. Single or multiple deserialized objects is a consequence of how many objects there were to deserialize. It is an implementation detail not germane to the (deserialized) objects actual use. Encapsulate implementation details, that is, hide them from the client code. Give clients classes and methods that express functionality in "business domain" terms.
end edit
Edit
... I'm having to use a dynamic return in the calling class to deal with the two types of responses possible. I think an abstract class (or interface?) is a better way to do this, but I don't know how to implement it.
Main points:
ClientApi transforms the deserialized object to the desired class.
Two API's!
constructors called by the de-hydrating object
Hide the default constructor to ensure valid object instantiation
GetDeHydratedJsonThingy called by the "using" client.
Deserializer and "using" client are decoupled thanks to the ClientApi class.
De-hydration works with DeserializedResults objects
"Using" client only cares about MultipleResponse objects
"using" client deals with only one return type.
P.S. After I wrote this I realized only one "Response" class is needed, now that ClientApi class encapsulates the object instantiations. Commented out code is original.
P.P.S. My method and parameter names are really lousy. Use names that have meaning in the problem domain. i.e. user's terminology.
.
public class ClientApi {
protected MultiResponse MoreThanOne { get; set; }
// protected SingleResponse OnlyOne { get; set; }
protected ClientApi ( );
public ClientApi (List<DeserializedResult> theList) {
if (theList == null) throw ArgumentNullException("error message here");
// add overloaded constructors to MultiResponse class.
MoreThanOne = new MultiResponse (theList);
// OnlyOne = null;
}
public ClientApi (DeserializedResult onlyOne)
if (onlyOne == null) throw ArgumentNullException("error message here");
MoreThanOne = new MultiResponse(onlyOne);
// OnlyOne = onlyOne;
}
///<summary>
/// Always returns an object. The list may be empty,
/// but never null
///</summary>
public MultiResponse GetDeHydratedJsonThingy() {
MultiResponse HereYaGo = new MultiResponse();
// if (MoreThanOne !=null) HereYaGo.AddRange(MoreThanOne);
// if (OnlyOne != null) HereYaGo.Add(OnlyOne);
HereYaGo.AddRange(MoreThanOne.Result);
return HereYaGo;
}
}
end Edit
You can try the following with a generic base abstract class
public abstract class Response<T> {
public T Result { get; set; }
}
The concrete implementations would inherit from the common base response.
public class Response : Response<object> {
public object Result { get; set; }
}
public class MultiResponse : Response<List<DeserializedResult>> {
public List<DeserializedResult> Result { get; set; }
}
public class SingleResponse : Response<DeserializedResult> {
public DeserializedResult Result { get; set; }
}
Say I have a class Book:
public class Book{
public string Title {get; set;}
}
I want every book to have a Read function that returns a string and accepts a page number - but the internals will be different for every book (poor example, I know). How do I define the signature of a function that must be implemented by instances of this class?
Something like this:
public class Book{ // need to make this abstract?
public string Title {get; set;}
public abstract string Read(int pageNum);
}
// I want to define instances that define their own behavior...
public static Book It => new Book(){ // can't create instance of abstract...
Title = "It",
Read... // what do I do here?
}
My main concerns are:
Keeping things as simple as possible. Implementing interfaces under abstract classes works, but it gives me n*2 things to worry about as I add more instances.
I will need to add a large number of these custom functions - passing Funcs through constructors seems unwieldy.
In practice - this is used to define a Tenant. The Tenants are defined in-memory, and have many static properties like domain, name, adminEmail, etc. Those are tenant-specific properties... but now I am trying to implement tenant-specific behaviors - like GetBooks or FilterUsers. I would like to keep implementation as simple as humanly possible. Right now I have "If TenantA, do this, else if tenantB, do this..." sprinkled throughout my code. I'm trying to consolidate all tenant-specific logic and detail in one place - on instances of the Tenant class.
Further examples of Tenant specific behavior - you have a SaaS forum software. On the homepage of Forum A, you GetCoverPhoto by reading from a static file. On the homepage of Forum B, you GetCoverPhoto by reading from a blog homepage. Currently, I say "If Forum A, do this, else If Forum B, do this". This is the type of tenant-specific behavior that I want to define on the Tenant object, instead of in code. I don't want any tenant-specific code in my core logic.
Is there a simple feature/pattern in the C# language that will achieve this?
What NineBerry said is very valid.
There is one other way of accomplishing what you might want. If you want to dynamicly inject the read method implementation into a Book. This can be seen as strategy pattern. And can be done as interfaces like in many languages, but in simplest form in C# it can be done by delegates. Example:
public class Book{
Func<int, string> readFunc;
public Book(Func<int, string> readFunc)
{
this.readFunc = readFunc;
}
public string Title {get; set;}
public string Read(int pageNum) { return readFunc(pageNum); }
}
Then use it as:
public static Book It => new Book(){
Title = "It",
Read = (pageNum) => ... // Do actual reading in delegate
}
EDIT: With more detail on requirements (but still not everything is obvious) I would do something like this:
public class Tenant
{
// core things go here
public Extensions Extensions { get; }
}
public class Extensions : IEnumerable<IExtension>
{
private IList<IExtension> list = new List<IExtension();
private Tenant { get; set; }
public Extensions(Tenant tenant)
{
Tenant = tenant;
}
public void Add(IExtension extension)
{
extension.Tenant = Tenant;
list.Add(extension);
}
}
public interface IExtension
{
Tenant { get; set; }
// shared interface of extensions if any can be abstracted
}
public interface ICoverPhotoExtension : IExtension
{
Photo GetCoverPhoto();
}
public class FileCoverPhotoExtension : ICoverPhotoExtension
{
public Tenant { get; set; }
Photo GetCoverPhoto() { } // gets photo from file
}
public class BlogCoverPhotoExtension : ICoverPhotoExtension
{
public Tenant { get; set; }
Photo GetCoverPhoto() { } // gets photo from blog
}
usage:
Tenant tenant; // initialized somehow
var coverPhotoExtension = tenant.Extensions.FirstOrDefault<ICoverPhotoExtension>();
Photo photo = coverPhotoExtension?.GetCoverPhoto();
public Interface IBook{
string Title {get; set;}
func<int,string> ReadPage
}
Use containment over inheritance. In the interface example above there is a function in every book that implements IBook that will return a string for that page.
public class MyBook : IBook{
public Title : {get;set;} = "MyBook";
public func<int,string> ReadPage =(pagenumber)=>{
return GetText(pagenumber);
}
public string GetText(int pageNumber){
//read the page text by number here.
}
}
I would make GetText an extension method similar to this, so each book doesn't need to implement GetText itself.
public static class XBook{
public static string GetText(this IBook book, int pageNumber){
///do the work here and returng string
}
}
To use the Extension method concept:
using XBook;
public class MyBook : IBook{
public Title : {get;set;} = "MyBook";
public func<int,string> ReadPage =(pagenumber)=>{
return this.GetText(pagenumber);
}
}
There are more ways to do this... for now, give it a try.
Having different instances of a class implement functions differently is not possible. Instead, you inherit a new class where you implement the separate behaviour.
public abstract class Book
{
public string Title {get; set;}
public abstract string Read(int pageNum);
}
public class ITBook : Book
{
public override string Read(int pageNum)
{
// Code here
}
}
Then use the class like this:
public static Book It => new ITBook()
{
Title = "It",
}
You could use a property of a delegate type in the Book class to use different functions in different instances of the Book class, but these functions would not have access to the other properties and methods of the instance they would be used by.
I just started to learn Decorator Design Pattern, unfortunately i had to go through various refrences to understand the Decorator pattern in a better manner which led me in great confusion. so, as far as my understanding is concern, i believe this is a decorator pattern
interface IComponent
{
void Operation();
}
class Component : IComponent
{
public void Operation()
{
Console.WriteLine("I am walking ");
}
}
class DecoratorA : IComponent
{
IComponent component;
public DecoratorA(IComponent c)
{
component = c;
}
public void Operation()
{
component.Operation();
Console.WriteLine("in the rain");
}
}
class DecoratorB : IComponent
{
IComponent component;
public DecoratorB(IComponent c)
{
component = c;
}
public void Operation()
{
component.Operation();
Console.WriteLine("with an umbrella");
}
}
class Client
{
static void Main()
{
IComponent component = new Component();
component.Operation();
DecoratorA decoratorA = new DecoratorA(new Component());
component.Operation();
DecoratorB decoratorB = new DecoratorB(new Component());
component.Operation();
Console.Read();
}
}
But can the below code also be Decorator Pattern?
class Photo
{
public void Draw()
{
Console.WriteLine("draw a photo");
}
}
class BorderedPhoto : Photo
{
public void drawBorder()
{
Console.WriteLine("draw a border photo");
}
}
class FramePhoto : BorderedPhoto
{
public void frame()
{
Console.WriteLine("frame the photo");
}
}
class Client
{
static void Main()
{
Photo p = new Photo();
p.Draw();
BorderedPhoto b = new BorderedPhoto();
b.Draw();
b.drawBorder();
FramePhoto f = new FramePhoto();
f.Draw();
f.drawBorder();
f.frame();
}
}
My Understanding
From the second example given by me, we can call all the three methods, but from the first example i wont be able to get access to all the three methods by creating a single object.
It should be a comment, but I have too many words.
For example, you have an object and interface, like Repository : IRepository.
public interface IRepository
{
void SaveStuff();
}
public class Repository : IRepository
{
public void SaveStuff()
{
// save stuff
}
}
and client, which probably was written by someone else
class RepoClient
{
public void DoSomething(IRepository repo)
{
//...
repo.SaveStuff();
}
}
And once you decided, that ALL calls to repository should be logged. But you have a problem: the Repository class is from an external library and you don't want to change that code. So you need to extend the Repository's behavior that you use. You write RepositoryLogDecorator : IRepository, and inside on each method do the logging, like
public class RepositoryLogDecorator : IRepository
{
public IRepository _inner;
public RepositoryLogDecorator(IRepository inner)
{
_inner = inner;
}
public void SaveStuff()
{
// log enter to method
try
{
_inner.SaveStuff();
}
catch(Exception ex)
{
// log exception
}
// log exit to method
}
}
So, before you could use client as
var client = new RepoClient();
client.DoSomething(new Repository());
but now you can use
var client = new RepoClient();
client.DoSomething(new RepositoryLogDecorator(new Repository()));
Note, that this is a very simple example. In real projects, where object created primary with DI container, you will be able to use decorator by changing some config.
So, decorator is used to extend functionality of object without changing object or client.
Another benefit of decorator: your decorator does not depend on Repository implementation. Only depends from an interface IRepository. Why this is an advantage? If somehow you decide to write you own implementation of IRepository
public class MyAwesomeRepository : IRepository
{
public void SaveStuff()
{
// save stuff, but AWESOME!
}
}
you will be able to automatically decorate this with decorator, which already exist
var client = new RepoClient();
client.DoSomethig(new RepositoryLogDecorator(new MyAwesomeRepository()));
Want to see example from real software? (just as sample, code is ugly, I know) => go here
There is this PatternCraft series on Youtube that explains Design Patterns with Starcraft, you should check the video about Decorators here.
In the video above the author gives an example with a Marine and WeaponUpgrade.
In the game you will have a Marine and then you can upgrade its weapon:
marine = new WeaponUpgrade(marine);
Note that you still have a marine there, it is not a new unit, it is the same unit with things that modifies its attributes.
public class MarineWeaponUpgrade : IMarine
{
private IMarine marine;
public MarineWeaponUpgrade(IMarine marine)
{
this.marine = marine;
}
public int Damage
{
get { return this.marine.Damage + 1; } // here
set { this.marine.Damage = value; }
}
}
You do that by creating a class that implements the same interface as your unit and access your unit properties to modify values.
There is a Kata on CodeWars challenging you to complete the Weapon and Armor decorators for a marine.
Per GOF page Decorator desing pattern:
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
In your second example you are using inheritance to extend behaviour of a class, I believe this is technically not a Decorator design pattern.
The decorator pattern allows you to add a specific behavior to an individual object of a given type without affecting other instances of that same type.
In your second example, which is normal inheritance, all instances of the class inherit the modified behavior.
The second example is not a decorate pattern, since an essential ingredient to decorator pattern is that the object accepts one of its kind and possibly enhance it.
An instances of this in the first example is
public DecoratorA(IComponent c)
{
component = c;
}
Also, the goal of the decorator pattern is to create "one" object, then decorate it by passing it through different filters or decorators.
Hence the line
DecoratorA decoratorA = new DecoratorA(new Component());
Should be
DecoratorA decoratorA = new DecoratorA(component );
is it possible to call properties after methods?
Example:
public static class Test
{
public static string Show { get; set; }
public static void Get(string s)
{
Show = s;
}
}
and call like this:
Test.Get("HI").Show;
Update 2: A fluent interface
If you are implementing a fluent interface, I would suggest renaming your methods as such:
public class Test
{
public string Show { get; set; }
public Test ConfigureShow(string show)
{
Show = show;
return this;
}
}
Your method is much more readable now and clearly defines the intent of the method:
var test = new Test()
.ConfigureShow("HI");
Make the rest of the methods in your class follow the same pattern and chain your methods on new lines for improved readability.
Update 1: What is your intent?
Is there a particular reason that you are trying to do this? There are several issues with your class:
Your methods should make sense - you should not have a method called Get which takes a parameter and then modifies the object. Generally Get methods imply that you are simply fetching something from the object.
Why are you passing in a parameter to the method, only to fetch it again?
Are you trying to implement a Fluent interface?
What is wrong with:
var show = "HI";
var test = new Test();
test.Show = show;
//You already have your text in the variable show, so why do you want to access it again?
Original answer to OP's question
public class Test
{
public string Show { get; set; }
public Test Get(string s)
{
Show = s;
return this;
}
}
I've searched for similar questions/problems on here and can't seem to find a solution that fits.
I currently have a class that it's constructor has one parameter which in turn calls a method which does not have any parameters but instantiates two objects. In the method, DoWork(), the requirements have changed, so I will need to handle other classes/objects, e.g. Building, Vehicle, etc. I am seeking advice on what would one recommend to take in these other objects, e.g. interfaces, generics, etc?
public class Project
{
public Person Person { get; set; } // will need to handle other classes as well
public String Task { get; set; }
// ctor
public Project(string task)
{
Task = task;
DoWork(); // should I handle this method here?
}
// current method
private void DoWork()
{
var work = new Work(this.Task);
Person = new Person(); // this instance of Person could be other objects as noted
Person.Job = work.Assignment;
Person.Site = work.Site;
...
If your classes Person, Building, Vehicle etc. shares some behavior, and the DoWork method only uses this behavior, polymorphism (either abstract class or interface) would be the best solution.
public MyData Data { get; set; }
void DoWork() {
Data.DoStuff();
}
In the case it wouldn't work, you can overload your DoWork method to do different stuff based on the instance, but this would require getting the instance as a parameter.
void DoWork(Person p) {
...
}
void DoWork(Building b) {
...
}
Otherwise, you can either use generics or polymorph on the Object class (and in both cases, deal with unwanted/unexpected types).
if (obj is Person)
...
else if (obj is Building)
...
else
throw new Exception();
If you want to retain the current structure and simply use a generic type instead of always creating a Person, a very straightforward refactoring looks something like this.
Create an abstract base class for the resource (a person, building, vehicle) required for a project.
public abstract class Resource
{
public virtual Assignment Job { get; set; }
public virtual Site Site { get; set; }
}
Create your concrete classes.
public class Person : Resource
{
public Person()
{
}
}
public class Building : Resource
{
public Building()
{
}
}
Now you can make your Project class accept a generic type T instead of Person. In this example, T must be some derived class of Resource and must support a parameterless constructor.
public class Project<T> where T : Resource, new()
{
public T Resource { get; set; } // will need to handle other classes as well
public String Task { get; set; }
// ctor
public Project(String task)
{
Task = task;
}
// current method
public void DoWork()
{
var work = new Work(this.Task);
Resource resource = new T(); // this instance of Person could be other objects as noted
resource.Job = work.Assignment;
resource.Site = work.Site;
// ...
}
}
You create your projects and do work like this.
Project<Person> personProject = new Project<Person>("MyTask");
personProject.DoWork();
Project<Building> buildingProject = new Project<Building>("MyBuildingTask");
buildingProject.DoWork();
You should not call DoWork from the constructor as shown in your code sample. Create the instance first, then call the method.