'm trying to design a system where a class would be defined in a project, be referenced in another and have new functionalities in the latter. Is there a pattern for this?
Context: I have a game that has items in a common project. Both the server and client reference this same project so I can have the item StaffItem in both the server and client, making it easier to serialize and deserialize between the two. The problem is, I can't redefine the StaffItem class in the client, since it will change the server's perspective of this class. I'm trying to find a nice way to add, for instance, the rendering to the client-side view of the class (added code for textures and all that).
I'm almost at the point of giving up and simply putting the rendering code in the common project, and stubbing it for the server. Any pointers (hehe) would be appreciated.
Instead of transferring the actual objects over the wire, you could introduce a DTO class for serializing and deserializing. This decouples the actual implementations on both sides.
If I understand your question right, there are two options you may consider. First one is to use smth similar with decorator pattern:
class StaffItem : IStaffItem {
public int MyProp {get;set;}
public void MyAction() {}
}
class ClientStaffItem : IStaffItem {
private StaffItem _staffItem;
public ClientStaffItem(StaffItem staffItem) {
_staffItem = staffItem;
}
public int MyProp {
get { return _staffItem.MyProp;}
set {_staffItem.MyProp; = value;}
}
public void MyAction() {
_staffItem.MyAction();
}
public void YouClientMethod() {}
}
The other one use inheritance, but determine which fields you need to serialize and how and use attributes or custom serialization settings to mark only properties you need.
Related
I am making a gallery tool that lets you browse and edit objects. I have a 'Library' class that manages the fetching and displaying of the gallery list. I also have an 'ActiveItem' asset that loads all the information of the selected object and deals with modifying it.
Now, there's some information that is stored in the 'library' class (for example the filepath) that I want to use in my activeitem.
I'm a bit confused as to how I can set this up efficiently.
I thought about embedding the activeitem class in the library class, but it gets a bit annoying to have to access all functions and properties of the activeitem through the library class (so instead of writing activeitem.Load() I would have to write lib.activeitem.Load() ). Activeitem already goes 4 levels deep and it's getting a bit much.
Are there other ways of setting this up? Can I store a reference of the library class instance inside the activeitem class, so that the activeitem class can fetch a property of the library instance?
Edit: added some code snippets
This are the class definitions:
class Library
{
...
public string LibDirectory;
...
}
class ActiveAsset
{
...
public SaveAsset()
{
//this method needs to know the LibDirectory property of the libraryclass
}
}
On initiating my winform, I initiate both classes:
Library lib = new Library();
ActiveAsset activeAsset = new ActiveAsset();
Given the concerns in the question comments, if you want ActiveAsset to be able to read information from Library you could change ActiveAsset's constructor to take in Library and store it internally as a private var.
class ActiveAsset
{
private Library _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
If you are worried about design and coupling you could make in interface for Library and then make the constructor use that instead of the Library class
interface ILibrary {
string LibDir { get; set; }
}
class Library : ILibrary {
}
class ActiveAsset
{
private ILibrary _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
As for performance and creating deep levels of nested classes I don't think you will have to worry so much about it, chances are you will hit data save/retrieve performance issues before anything like too many classes. That kind of performance design is only really important when you try to make you code work on small platforms where memory is limited like rasberryPi and such.
I would suggest creating a wrapper class which holds both the Library and the ActiveItem instances. Thus you can have more generalised methods like:
GetAllItems() - gets all items from the library
ActivateItem(Item item) - activates the item provided (stores the given item to a variable in the wrapper class)
etc. Think of that wrapper class as the manager of your application. You would only like to work with that manager regardless of what's beneath it.
I'm a relative newbie to C#, although I am a competent programmer, and I confess that I am totally confused as to whether or not it is a good idea to write custom collection classes. So many people seem to say "don't", yet there is a whole set of base classes for it in C#.
Here is my specific case. I have a timetable application. As part of that, I have a service class, and the service class contains collections of things service-y, such as route links. A route link is itself a custom class:
public class Service
{
public RouteLinks RL; // A collection of RouteLink types
...
}
public class RouteLink
{
public string FirstStopRef;
public string LastStopRef;
public Tracks RouteTrack; // Another collection, this time of Track types
}
So far I have looked at using Dictionary as the type for RouteLinks, because I need to be able to reference them. This is fine in principle. However, the process of adding a RouteLink to the RouteLinks collection involves checking to see whether it is already there, or whether it extends and existing route link, or... And for that, I need a custom Add function.
So why is is such bad practice to create custom collection classes? Why shouldn't I just inherit CollectionBase or DictionaryBase?
I should perhaps add that I am transferring this code from VBA [please don't shoot me :)] and there I HAD to implement custom collections.
Instead of having RouteLinks be a collection type, an easy solution would be to just define another class, let's say RouteLinksRepository. This class will contain a List<RouteLink> and the AddRoute(RouteLink) functionality as well as any other custom logic for interacting with this collection of RouteLink objects. Your service class will then just contain an instance of this repository class.
public class Service
{
public RouteLinksRepository RL; // A collection of RouteLink types
// ...
}
public class RouteLinksRepository
{
public List<RouteLink> RouteLinks;
public bool AddRoute(RouteLink linkToAdd)
{
//Custom logic on whether or not to add link
}
//Your other logic for the class
}
public class RouteLink
{
public string FirstStopRef;
public string LastStopRef;
public Tracks RouteTrack; // Another collection, this time of Track types
}
If the only need is to check on double entries, a HashSet will do (implement a GetHash and Equals). However I guess you are trying to save a route. A route has a order, which means you have a order and List<> garantees the order. Make the collection objects private to hide the implementation.
public class Service
{
private List<RouteLink> RL; // A collection of RouteLink types
...
}
public class RouteLink
{
public string FirstStopRef;
public string LastStopRef;
private List<Track> Tracks; // Another collection, this time of Track types
}
I'm refactoring a class that represents the data in some XML. Currently, the class loads the XML itself and property implementations parse the XML every time. I'd like to factor out the XML logic and use a factory to create these objects. But there are several 'optional' properties and I'm struggling to find an elegant way to handle this.
Let's say the XML looks like this:
<data>
<foo>a</foo>
<bar>b</bar>
</data>
Assume both foo and bar are optional. The class implementation looks something like this:
interface IOptionalFoo
{
public bool HasFoo();
public string Foo { get; }
}
// Assume IOptionalBar is similar
public class Data : IOptionalFoo, IOptionalBar
{
// ...
}
(Don't ask me why there's a mix of methods and properties for it. I didn't design that interface and it's not changing.)
So I've got a factory and it looks something like this:
class DataFactory
{
public static Data Create(string xml)
{
var dataXml = new DataXml(xml);
if (dataXml.HasFoo())
{
// ???
}
// Create and return the object based on the data that was gathered
}
}
This is where I can't seem to settle on an elegant solution. I've done some searching and found some solutions I don't like. Suppose I leave out all of the optional properties from the constructor:
I can implement Foo and Bar as read/write on Data. This satisfies the interface but I don't like it from a design standpoint. The properties are meant to be immutable and this fudges that.
I could provide SetFoo() and SetBar() methods in Data. This is just putting lipstick on the last method.
I could use the internal access specifier; for the most part I don't believe this class is being used outside of its assembly so again it's just a different way to do the first technique.
The only other solution I can think of involves adding some methods to the data class:
class Data : IOptionalFoo, IOptionalBar
{
public static Data WithFoo(Data input, string foo)
{
input.Foo = foo;
return input;
}
}
If I do that, the setter on Foo can be private and that makes me happier. But I don't really like littering the data object with a lot of creation methods, either. There's a LOT of optional properties. I've thought about making some kind of DataInitialization object with a get/set API of nullable versions for each property, but so many of the properties are optional it'd end up more like the object I am refactoring becomes a facade over a read/write version. Maybe that's the best solution: an internal read/write version of the class.
Have I enumerated the options? Do I need to quit being so picky and settle on one of the techniques above? Or is there some other solution I haven't thought of?
You can think of such keywords as virtual/castle dynamic proxy/reflection/T4 scripts - each one can solve the problem on a slightly different angle.
On another note, this seems perfectably reasonable, unless I misunderstood you:
private void CopyFrom(DataXml dataXml) // in Data class
{
if (dataXml.HasFoo()) Foo = dataXml.Foo;
//etc
}
What I did:
I created a new class that represented a read/write interface for all of the properties. Now the constructor of the Data class takes an instance of that type via the constructor and wraps the read/write properties with read-only versions. It was a little tedious, but wasn't as bad as I thought.
Previous Post removed; Updated:
So I have a unique issue, which is possibly fairly common though. Properties are quite possibly are most commonly used code; as it requires our data to keep a constant value storage. So I thought how could I implement this; then I thought about how easy Generics can make life. Unfortunately we can't just use a Property in a Generic without some heavy legwork. So here was my solution / problem; as I'm not sure it is the best method- That is why I was seeking review from my peers.
Keep in mind the application will be massive; this is a very simple example.
Abstract:
Presentation Layer: The interface will have a series of fields; or even data to go across the wire through a web-service to our database.
// Interface:
public interface IHolder<T>
{
void objDetail(List<T> obj);
}
So my initial thought was an interface that will allow me to Generically handle each one of my objects.
// User Interface:
public class UI : IHolder
{
void objDetail(List<object> obj)
{
// Create an Instance
List<object> l = new List<object>();
// Add UI Fields:
l.Add(Guid.NewGuid());
l.Add(txtFirst.Text);
l.Add(txtLast.Text);
// l to our obj
obj = l;
return;
}
}
Now I have an interface; which has been used by our UI to put information in. Now; this is where the root of my curiosity has been thrown into the mixture.
// Create an Object Class
public class Customer : IHolder
{
// Member Variable:
private Guid _Id;
private String _First;
private String _Last;
public Guid Id
{
get { return _Id; }
set { _Id = value; }
}
public String First
{
get { return _First; }
set { _First = value; }
}
public String Last
{
get { return _Last; }
set { _Last = value; }
}
public virtual objDetail(List<Customer> obj)
{
// Enumerate through List; and assign to Properties.
}
}
Now this is where I thought it would be cool; if I could use Polymorphism to use the same interface; but Override it to do the method differently. So the Interface utilizes a Generic; with the ability to Morph to our given Object Class.
Now our Object Classes; can move toward our Entity interface which will handle basic Crud Operation.
I know this example isn't the best for my intention; as you really don't need to use Polymorphism. But, this is the overall idea / goal...
Interface to Store Presentation Layer UI Field Value
Implement the Properties to a Desired Class
Create a Wrapper Around my Class; which can be Polymorphed.
Morphed to a Generic for Crud Operation
Am I on the right path; is this taboo? Should I not do this? My application needs to hold each instance; but I need the flexibility to adapt very quickly without breaking every single instance in the process. That was how I thought I could solve the issue. Any thoughts? Suggestions? Am I missing a concept here? Or am I over-thinking? Did I miss the boat and implement my idea completely wrong? That is where I'm lost...
After pondering on this scenario a bit, I thought what would provide that flexibility while still ensuring the code is optimized for modification and business. I'm not sure this is the right solution, but it appears to work. Not only does it work, it works nicely. It appears to be fairly robust.
When is this approach useful? Well, when you intend to decouple your User Interface from your Logic. I'll gradually build each aspect so you can see the entire structure.
public interface IObjContainer<T>
{
void container(List<T> object);
}
This particular structure will be important. As it will store all of the desired content into it.
So to start you would create a Form with a series of Fields.
Personal Information
Address Information
Payment Information
Order Information
So as you can see all of these can be separate Database Tables, but belong to a similar Entity Model you are manipulating. This is quite common.
So a Segregation Of Concern will start to show slightly, the fields will be manipulated and passed through an Interface.
public interface IPersonalInformation
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
So essentially the Interface is passing its variable, to the Interface. So you would culminate an interface to handle that entire form or individual interfaces that you wish to call so that they remain reusable.
So now you have a series of Interfaces, or a single once. But it contains all these variables to use. So you would now create a class:
public class CustomerProperties: IPersonalInformation, IOrderInformation
{
// Implement each Interface Property
}
Now you've created a container that will hold all of your values. What is nifty about this container is you can reuse the same values for another class in your application or choose different ones. But it will logically separate the User Interface.
So essentially this is acting similar to a Repository.
Now you can take these values and perform the desired logic. What becomes wonderful now, is after you've performed your logic you pass the object into our Generic List. Then you simply implement that method in another class for your goal and iterate through your list.
The honesty is it appears to work well and decouple nicely. I feel that it was a lot of work to do something similar to a normal Repository and Unit Of Work, this answers the question but weather or not it is ideal for your project I would look into Repository, Unit Of Work, Segregation Of Concern, Inversion Of Control, and Dependency Injection. They may do this same approach cleaner.
Update:
I thought about it after I wrote this up, I noticed you could actually implement those property values into the Generic List structure bypassing a series of interfaces; but that would introduce consistency issues as you'd have to be aware of what data is being passed in each time, in order. It's possible, but may not be ideal.
I am working on a client/server game (C#.NET) where I do not want to trust the client to hold any of my server side application code, but want to share objects.
For example imagine you have a right hand weapon slot and a backpack that can carry additional items. Now there's a lot of server side code that will control which items can go in which slots and when you swing your right hand what happens. I don't want to put this code in my client for various reasons, but I am finding often times that if I generate a client side class and server side class for each of these that I see a lot of duplication in data and some duplication in methods. I also have to convert 1 class into the other.
Another example is For Items in the game. Item's have 'Use' abilities (like Use a key, or Use a torch) and properties like Name and Weight. So When I create the Item Class I would prefer to make 1 class like this:
Public Class Item
{
int Weight;
string Name;
void Use() { //Do something interesting but not public to the client }
}
Eventually copies of this object are serialized and sent to the client or server from each other as changes are made. If a Partial Class could span projects that would be very promising (to bad they don't). I don't think sub-classing feels right here (like ServerItem : Item) considering Serialization/Deserialization. I will play around some with Extension methods and see what implications there are for sub-classing but if anyone has any ideas or if I'm just missing something obvious please let me know.
You really want to separate Data from Behaviour, and have just lightweight share-able data classes, and then (on the server) have server-centric classes that use data to determine behaviour. (try looking at a few design patters - maybe 'Decorator')
One lightweight example of what you may want is:
// lightweight data class thats shared
public class Item
{
public int Weight { get; set; }
public string Name { get; set; }
}
// decorator pattern class that adds behaviour
public class ServerItem
{
private Item item;
public ServerItem(Item item)
{
this.item = item;
}
public void Use()
{
// do something with item;
}
}
ServerItem currentServerItem = new ServerItem(currentItem);