What does this c# syntax is for? [duplicate] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I was studying the Decorator Pattern as documented in GOF.
Please, help me understand the Decorator Pattern. Could someone give a use-case example of where this is useful in the real world?

Decorator pattern achieves a single objective of dynamically adding
responsibilities to any object.
Consider a case of a pizza shop. In the pizza shop they will sell few pizza varieties and they will also provide toppings in the menu. Now imagine a situation wherein if the pizza shop has to provide prices for each combination of pizza and topping. Even if there are four basic pizzas and 8 different toppings, the application would go crazy maintaining all these concrete combination of pizzas and toppings.
Here comes the decorator pattern.
As per the decorator pattern, you will implement toppings as decorators and pizzas will be decorated by those toppings' decorators. Practically each customer would want toppings of his desire and final bill-amount will be composed of the base pizzas and additionally ordered toppings. Each topping decorator would know about the pizzas that it is decorating and it's price. GetPrice() method of Topping object would return cumulative price of both pizza and the topping.
EDIT
Here's a code-example of explanation above.
public abstract class BasePizza
{
protected double myPrice;
public virtual double GetPrice()
{
return this.myPrice;
}
}
public abstract class ToppingsDecorator : BasePizza
{
protected BasePizza pizza;
public ToppingsDecorator(BasePizza pizzaToDecorate)
{
this.pizza = pizzaToDecorate;
}
public override double GetPrice()
{
return (this.pizza.GetPrice() + this.myPrice);
}
}
class Program
{
[STAThread]
static void Main()
{
//Client-code
Margherita pizza = new Margherita();
Console.WriteLine("Plain Margherita: " + pizza.GetPrice().ToString());
ExtraCheeseTopping moreCheese = new ExtraCheeseTopping(pizza);
ExtraCheeseTopping someMoreCheese = new ExtraCheeseTopping(moreCheese);
Console.WriteLine("Plain Margherita with double extra cheese: " + someMoreCheese.GetPrice().ToString());
MushroomTopping moreMushroom = new MushroomTopping(someMoreCheese);
Console.WriteLine("Plain Margherita with double extra cheese with mushroom: " + moreMushroom.GetPrice().ToString());
JalapenoTopping moreJalapeno = new JalapenoTopping(moreMushroom);
Console.WriteLine("Plain Margherita with double extra cheese with mushroom with Jalapeno: " + moreJalapeno.GetPrice().ToString());
Console.ReadLine();
}
}
public class Margherita : BasePizza
{
public Margherita()
{
this.myPrice = 6.99;
}
}
public class Gourmet : BasePizza
{
public Gourmet()
{
this.myPrice = 7.49;
}
}
public class ExtraCheeseTopping : ToppingsDecorator
{
public ExtraCheeseTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 0.99;
}
}
public class MushroomTopping : ToppingsDecorator
{
public MushroomTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 1.49;
}
}
public class JalapenoTopping : ToppingsDecorator
{
public JalapenoTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 1.49;
}
}

This is a simple example of adding new behavior to an existing object dynamically, or the Decorator pattern. Due to the nature of dynamic languages such as Javascript, this pattern becomes part of the language itself.
// Person object that we will be decorating with logging capability
var person = {
name: "Foo",
city: "Bar"
};
// Function that serves as a decorator and dynamically adds the log method to a given object
function MakeLoggable(object) {
object.log = function(property) {
console.log(this[property]);
}
}
// Person is given the dynamic responsibility here
MakeLoggable(person);
// Using the newly added functionality
person.log('name');

It's worth noting that the Java i/o model is based on the decorator pattern. The layering of this reader on top of that reader on top of...is a really real world example of decorator.

Example - Scenario- Let's say you are writing an encryption module. This encryption can encrypt the clear file using DES - Data encryption standard. Similarly, in a system you can have the encryption as AES - Advance encryption standard. Also, you can have the combination of encryption - First DES, then AES. Or you can have first AES, then DES.
Discussion- How will you cater this situation? You cannot keep creating the object of such combinations - for example - AES and DES - total of 4 combinations. Thus, you need to have 4 individual objects This will become complex as the encryption type will increase.
Solution - Keep building up the stack - combinations depending on the need - at run time.
Another advantage of this stack approach is that you can unwind it easily.
Here is the solution - in C++.
Firstly, you need a base class - a fundamental unit of the stack. You can think as the base of the stack. In this example, it is clear file. Let's follow always polymorphism. Make first an interface class of this fundamental unit. This way,you can implement it as you wish. Also, you don't need to have think of dependency while including this fundamental unit.
Here is the interface class -
class IclearData
{
public:
virtual std::string getData() = 0;
virtual ~IclearData() = 0;
};
IclearData::~IclearData()
{
std::cout<<"Destructor called of IclearData"<<std::endl;
}
Now, implement this interface class -
class clearData:public IclearData
{
private:
std::string m_data;
clearData();
void setData(std::string data)
{
m_data = data;
}
public:
std::string getData()
{
return m_data;
}
clearData(std::string data)
{
setData(data);
}
~clearData()
{
std::cout<<"Destructor of clear Data Invoked"<<std::endl;
}
};
Now, let's make a decorator abstract class - that can be extended to create any kind of flavours - here the flavour is the encryption type. This decorator abstract class is related to the base class. Thus, the decorator "is a" kind of interface class. Thus, you need to use inheritance.
class encryptionDecorator: public IclearData
{
protected:
IclearData *p_mclearData;
encryptionDecorator()
{
std::cout<<"Encryption Decorator Abstract class called"<<std::endl;
}
public:
std::string getData()
{
return p_mclearData->getData();
}
encryptionDecorator(IclearData *clearData)
{
p_mclearData = clearData;
}
virtual std::string showDecryptedData() = 0;
virtual ~encryptionDecorator() = 0;
};
encryptionDecorator::~encryptionDecorator()
{
std::cout<<"Encryption Decorator Destructor called"<<std::endl;
}
Now, let's make a concrete decorator class -
Encryption type - AES -
const std::string aesEncrypt = "AES Encrypted ";
class aes: public encryptionDecorator
{
private:
std::string m_aesData;
aes();
public:
aes(IclearData *pClearData): m_aesData(aesEncrypt)
{
p_mclearData = pClearData;
m_aesData.append(p_mclearData->getData());
}
std::string getData()
{
return m_aesData;
}
std::string showDecryptedData(void)
{
m_aesData.erase(0,m_aesData.length());
return m_aesData;
}
};
Now, let's say the decorator type is DES -
const std::string desEncrypt = "DES Encrypted ";
class des: public encryptionDecorator
{
private:
std::string m_desData;
des();
public:
des(IclearData *pClearData): m_desData(desEncrypt)
{
p_mclearData = pClearData;
m_desData.append(p_mclearData->getData());
}
std::string getData(void)
{
return m_desData;
}
std::string showDecryptedData(void)
{
m_desData.erase(0,desEncrypt.length());
return m_desData;
}
};
Let's make a client code to use this decorator class -
int main()
{
IclearData *pData = new clearData("HELLO_CLEAR_DATA");
std::cout<<pData->getData()<<std::endl;
encryptionDecorator *pAesData = new aes(pData);
std::cout<<pAesData->getData()<<std::endl;
encryptionDecorator *pDesData = new des(pAesData);
std::cout<<pDesData->getData()<<std::endl;
/** unwind the decorator stack ***/
std::cout<<pDesData->showDecryptedData()<<std::endl;
delete pDesData;
delete pAesData;
delete pData;
return 0;
}
You will see the following results -
HELLO_CLEAR_DATA
Encryption Decorator Abstract class called
AES Encrypted HELLO_CLEAR_DATA
Encryption Decorator Abstract class called
DES Encrypted AES Encrypted HELLO_CLEAR_DATA
AES Encrypted HELLO_CLEAR_DATA
Encryption Decorator Destructor called
Destructor called of IclearData
Encryption Decorator Destructor called
Destructor called of IclearData
Destructor of clear Data Invoked
Destructor called of IclearData
Here is the UML diagram - Class representation of it. In case, you want to skip the code and focus on the design aspect.

Decorator pattern helps you to change or configure a functionality of your object by chaining with other similar subclasses of this object.
Best example would be InputStream and OutputStream classes in java.io package
File file=new File("target","test.txt");
FileOutputStream fos=new FileOutputStream(file);
BufferedOutputStream bos=new BufferedOutputStream(fos);
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.write(5);
oos.writeBoolean(true);
oos.writeBytes("decorator pattern was here.");
//... then close the streams of course.

What is Decorator Design Pattern in Java.
The formal definition of the Decorator pattern from the GoF book (Design Patterns: Elements of Reusable Object-Oriented Software, 1995, Pearson Education, Inc. Publishing as Pearson Addison Wesley) says you can,
"Attach additional responsibilities to an object dynamically. Decorators
provide a flexible alternative to subclassing for extending functionality."
Let's say we have a Pizza and we want to decorate it with toppings such as Chicken Masala, Onion and Mozzarella Cheese. Let's see how to implement it in Java ...
Program to demonstrate how to implement Decorator Design Pattern in Java.
See more at: http://www.hubberspot.com/2013/06/decorator-design-pattern-in-java.html#sthash.zKj0xLrR.dpuf
Pizza.java:
<!-- language-all: lang-html -->
package com.hubberspot.designpattern.structural.decorator;
public class Pizza {
public Pizza() {
}
public String description(){
return "Pizza";
}
}
package com.hubberspot.designpattern.structural.decorator;
public abstract class PizzaToppings extends Pizza {
public abstract String description();
}
package com.hubberspot.designpattern.structural.decorator;
public class ChickenMasala extends PizzaToppings {
private Pizza pizza;
public ChickenMasala(Pizza pizza) {
this.pizza = pizza;
}
#Override
public String description() {
return pizza.description() + " with chicken masala, ";
}
}
package com.hubberspot.designpattern.structural.decorator;
public class MozzarellaCheese extends PizzaToppings {
private Pizza pizza;
public MozzarellaCheese(Pizza pizza) {
this.pizza = pizza;
}
#Override
public String description() {
return pizza.description() + "and mozzarella cheese.";
}
}
package com.hubberspot.designpattern.structural.decorator;
public class Onion extends PizzaToppings {
private Pizza pizza;
public Onion(Pizza pizza) {
this.pizza = pizza;
}
#Override
public String description() {
return pizza.description() + "onions, ";
}
}
package com.hubberspot.designpattern.structural.decorator;
public class TestDecorator {
public static void main(String[] args) {
Pizza pizza = new Pizza();
pizza = new ChickenMasala(pizza);
pizza = new Onion(pizza);
pizza = new MozzarellaCheese(pizza);
System.out.println("You're getting " + pizza.description());
}
}

The decorator pattern lets you dynamically add behavior to objects.
Let's take an example where you need to build an app that calculates the price of different kinds of burgers. You need to handle different variations of burgers, such as "large" or "with cheese", each of which has a price relative to the basic burger. E.g. add $10 for burger with cheese, add extra $15 for large burger, etc.
In this case you might be tempted to create subclasses to handle these. We might express this in Ruby as:
class Burger
def price
50
end
end
class BurgerWithCheese < Burger
def price
super + 15
end
end
In the above example, the BurgerWithCheese class inherits from Burger, and overrides the price method to add $15 to the price defined in the super class. You would also create a LargeBurger class and define the price relative to Burger. But you also need to define a new class for the combination of "large" and "with cheese".
Now what happens if we need to serve "burger with fries"? We already have 4 classes to handle those combinations, and we will need to add 4 more to handle all combination of the 3 properties - "large", "with cheese" and "with fries". We need 8 classes now. Add another property and we'll need 16. This will grow as 2^n.
Instead, let's try defining a BurgerDecorator that takes in a Burger object:
class BurgerDecorator
def initialize(burger)
self.burger = burger
end
end
class BurgerWithCheese < BurgerDecorator
def price
self.burger.price + 15
end
end
burger = Burger.new
cheese_burger = BurgerWithCheese.new(burger)
cheese_burger.price # => 65
In the above example, we've created a BurgerDecorator class, from which BurgerWithCheese class inherits. We can also represent the "large" variation by creating LargeBurger class. Now we could define a large burger with cheese at runtime as:
b = LargeBurger.new(cheese_burger)
b.price # => 50 + 15 + 20 = 85
Remember how using inheritance to add the "with fries" variation would involve adding 4 more subclasses? With decorators, we would just create one new class, BurgerWithFries, to handle the new variation and handle this at runtime. Each new property would need just more decorator to cover all the permutations.
PS. This is the short version of an article I wrote about using the Decorator Pattern in Ruby, which you can read if you wish to find out more detailed examples.

Decorator:
Add behaviour to object at run time. Inheritance is the key to achieve this functionality, which is both advantage and disadvantage of this pattern.
It enhances the behaviour of interface.
Decorator can be viewed as a degenerate Composite with only one component. However, a Decorator adds additional responsibilities - it isn't intended for object aggregation.
The Decorator class declares a composition relationship to the LCD (Lowest Class Denominator) interface, and this data member is initialized in its constructor.
Decorator is designed to let you add responsibilities to objects without sub-classing
Refer to sourcemaking article for more details.
Decorator (Abstract) : it is an abstract class/interface, which implements the component interface. It contains Component interface. In absence of this class, you need many sub-classes of ConcreteDecorators for different combinations. Composition of component reduces un-necessary sub-classes.
JDK example:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("a.txt")));
while(bis.available()>0)
{
char c = (char)bis.read();
System.out.println("Char: "+c);;
}
Have a look at below SE question for UML diagram and code examples.
Decorator Pattern for IO
Useful articles:
journaldev
wikipedia
Real word example of Decorator pattern: VendingMachineDecorator has been explained #
When to Use the Decorator Pattern?
Beverage beverage = new SugarDecorator(new LemonDecorator(new Tea("Assam Tea")));
beverage.decorateBeverage();
beverage = new SugarDecorator(new LemonDecorator(new Coffee("Cappuccino")));
beverage.decorateBeverage();
In above example, Tea or Coffee ( Beverage) has been decorated by Sugar and Lemon.

Some time back I had refactored a codebase into using Decorator pattern, so I will try to explain the use case.
Lets assume we have a set of services and based on whether the user has acquired licence of particular service, we need to start the service.
All the services have a common interface
interface Service {
String serviceId();
void init() throws Exception;
void start() throws Exception;
void stop() throws Exception;
}
Pre Refactoring
abstract class ServiceSupport implements Service {
public ServiceSupport(String serviceId, LicenseManager licenseManager) {
// assign instance variables
}
#Override
public void init() throws Exception {
if (!licenseManager.isLicenseValid(serviceId)) {
throw new Exception("License not valid for service");
}
// Service initialization logic
}
}
If you observe carefully, ServiceSupport is dependent on LicenseManager. But why should it be dependent on LicenseManager? What if we needed background service which doesn't need to check license information. In the current situation we will have to somehow train LicenseManager to return true for background services.
This approach didn't seem well to me. According to me license check and other logic were orthogonal to each other.
So Decorator Pattern comes to the rescue and here starts refactoring with TDD.
Post Refactoring
class LicensedService implements Service {
private Service service;
public LicensedService(LicenseManager licenseManager, Service service) {
this.service = service;
}
#Override
public void init() {
if (!licenseManager.isLicenseValid(service.serviceId())) {
throw new Exception("License is invalid for service " + service.serviceId());
}
// Delegate init to decorated service
service.init();
}
// override other methods according to requirement
}
// Not concerned with licensing any more :)
abstract class ServiceSupport implements Service {
public ServiceSupport(String serviceId) {
// assign variables
}
#Override
public void init() {
// Service initialization logic
}
}
// The services which need license protection can be decorated with a Licensed service
Service aLicensedService = new LicensedService(new Service1("Service1"), licenseManager);
// Services which don't need license can be created without one and there is no need to pass license related information
Service aBackgroundService = new BackgroundService1("BG-1");
Takeaways
Cohesion of code got better
Unit testing became easier, as don't have to mock licensing when testing ServiceSupport
Don't need to bypass licensing by any special checks for background services
Proper division of responsibilities

Let's take example of PubG. Assault rifles works best with 4x zoom and while we are on it, we would also need compensator and suppressor. It will reduce recoil and reduce firing sound as well as echo. We will need to implement this feature where we will allow players to buy their favourite gun and their accessories. Players can buy the gun or some of the accessory or all of the accessory and they would be charged accordingly.
Let's see how decorator pattern is applied here:
Suppose someone wants to buy SCAR-L with all three accessories mentioned above.
Take an object of SCAR-L
Decorate (or add) the SCAR-L with 4x zoom object
Decorate the SCAR-L with suppressor object
Decorate the SCAR-L with compressor object
Call the cost method and let each object delegate to add on the cost
using cost method of accessories
This will lead to a class diagram like this:
Now, we can have classes like this:
public abstract class Gun {
private Double cost;
public Double getCost() {
return cost;
}
}
public abstract class GunAccessories extends Gun { }
public class Scarl extends Gun {
public Scarl() {
cost = 100;
}
}
public class Suppressor extends GunAccessories {
Gun gun;
public Suppressor(Gun gun) {
cost = 5;
this.gun = gun;
}
public double getCost(){
return cost + gun.getCost();
}
}
public class GunShop{
public static void main(String args[]){
Gun scarl = new Scarl();
scarl = new Supressor(scarl);
System.out.println("Price is "+scarl.getCost());
}
}
We can similarly add other accessories too and decorate our Gun.
Reference:
https://nulpointerexception.com/2019/05/05/a-beginner-guide-to-decorator-pattern/

Decorators are just a compositional alternative to subclassing.
The common example from the original book on this topic, that everyone mentions, is with a text processing application.
Lets say you write a paragraph. You highlight it yellow. You italicize one sentence. You bolden half of the italicized sentence, and half of the next sentence too. You increase the font size of one of the italicized & bold letters. You change the font style of half the highlighted portion, some of it running over into the italicized portion, some not...
So I'm going to ask you how you'd implement that functionality. You start out with a class for a simple, undecorated letter. What do you do next?
I'm going to assume you would not use subclassing. You would need such a complex, convoluted hierarchy of multiple inheritance to achieve all the combinations I described and more, that subclassing and multiple inheritance just would be absurd. And I think that needs no explanation.
What you'd probably suggest is just packing all these properties into your letter object. Properties to define the font style, the size, the highlighting, bold, italicized, the list goes on. Every kind of property you could add to a letter object, you've got a property in your letter class for it.
So what are the problems with this property based approach?
now your class is bloated, it takes up a giant amount of memory. It has all these unnecessary properties associated with it, most that it will never use. Most letters are just... letters. Not decorated.
The data of your letter class is being used in a way that is completely exposed, your class is just a glorified struct. You have a bunch of getters and setters for all these properties. Outside code accesses those setters and modifies the graphical appearance of your object. There's tight coupling between your object and the outside code.
Everything is packed into one place, it's not modular. It's just going to be a bloated, interconnected bundle of code. That's going to be true in the outside code that handles your letter object as well, too.
Fundamentally it's a question of object oriented design, proper encapsulation and separation of concerns.
Now, let's just take it for granted we wanted to use better OO design principles. We want to use encapsulation, we want to maintain loose coupling between the outside code and our letter class. We wanted to minimize our letter objects memory footprint. How...? We can't use subclassing...
So we use decorators, which are a compositional approach to object oriented design - it's sort of the opposite of a top-down, subclassing approach. You wrap these letter objects with more functionality at runtime, building on top of them.
So that's what the decorator pattern is - it's a compositional alternative to subclassing. In our example you add a decorator to the letter object that needs highlighting. You can combine any number of decorators in an arbitrary number of ways, and wrap them all around a given letter. The decorator interface is always transparent, so you still treat these letters the same from the outside.
Any time you need to augment functionality in a way that's arbitrary and recombinable, consider this approach. Multiple inheritance runs into all kinds of problems, it just isn't scalable.

There is a example on Wikipedia about decorating a window with scrollbar:
http://en.wikipedia.org/wiki/Decorator_pattern
Here is another very 'real world' example of "Team member, team lead and manager", which illustrates that decorator pattern is irreplaceable with simple inheritance:
https://zishanbilal.wordpress.com/2011/04/28/design-patterns-by-examples-decorator-pattern/

Decorator pattern achieves a single objective of dynamically adding responsibilities to any object.
Java I/O Model is based on decorator pattern.

Decorator Design Pattern:
This pattern helps to modify the characteristics of an object at runtime. It provides different flavours to an object and gives flexibility to choose what ingredients we want to use in that flavour.
Real Life Example:
Lets say you have a main cabin seat in a flight. Now you are allowed to choose multiple amenities with the seat. Each amenity has its own cost associated with it. Now if a user chooses Wifi and premium food, he/she will be charged for seat + wifi + premium food.
In this case decorator design pattern can really help us. Visit the above link to understand more about decorator pattern and implementation of one real life example.

Related

How can factory's have access to other factory's products in abstract factory pattern

In this example for the NYPizzaIngredientFactory, they can only make pizza with ThinCrustDough. How can i make a pizza that could use another factory's ingredients like ThickCrustDough from ChicagoPizzaIngredientFactory. I want to try stay away from builder and stick with abstract factory patterns and factory methods.
Your NYPizzaStore would have to use the ChicagoPizzaIngredientFactory if you want it to be able to use ThickCrustDough.
If you think about the practicality of this, however, it probably doesn't make sense to have them ship you the ingredients from Chicago.
In my mind, you have two options:
Have another factory located in NY that can produce thick dough (e.g. NYThickPizzaIngredientFactory). This is because your interface has a single createDough method that takes no arguments so you can't tell it what type of dough to make. It can only make one.
Alter your interface so that the createDough method accepts arguments that can tell the factory what type of dough to create. This is the one I would recommend.
The type of arguments can also be based on the particular factory. For instance:
//TDoughArts tells you what type of arguments the factory needs in order to make dough.
public interface IPizzaIngredientFactory<TDoughArgs> where TDoughArgs : IDoughArgs
{
//....
IDough CreateDough(TDoughArgs doughArgs);
//....
}
public interface IDoughArgs
{
}
public class NYPizzaDoughArgs : IDoughArgs
{
public enum DoughTypes
{
Thin = 0,
Thick = 1
}
public DoughTypes DoughType { get; set; }
}
public class NYPizzaIngredientFactory : IPizzaIngredientFactory<NYPizzaDoughArgs>
{
//....
public IDough CreateDough(NYPizzaDoughArgs doughArgs)
{
//Make the right dough based on args here
if(doughArgs.DoughType == DoughTypes.Thin)
//...
}
//....
}
I whipped this out in a few minutes so check for consistency, but I think you will get the idea.
You don't have to use generics. You can simply stick with the IDoughArgs interface if you don't want more specificity.
Usage:
var factory = new NYPizzaIngredientFactory();
var args = new NYPizzaDoughArgs();
args.DoughType = NYPizzaDoughArgs.DoughTypes.Thick;
var dough = factory.createDough(args);
The first problem I see is this:
public interface IDoughArgs
{
}
public class NYPizzaDoughArgs : IDoughArgs
{
public enum DoughTypes
{
Thin = 0,
Thick = 1
}
public DoughTypes DoughType { get; set; }
}
IDoughArgs has no members. The class that implements it, NYPizzaDoughArgs, has properties which are not implementations of IDoughArgs. That renders the IDoughArgs interface meaningless.
Additionally, look at this class declaration:
public class NYPizzaIngredientFactory : IPizzaIngredientFactory<NYPizzaDoughArgs>
What class is going to "know" the generic argument and know to create this class as opposed to some other generic implementation? It's going to get confusing when you get to that part. You'll need some sort of factory to create your factory.
Then, if you decide that ingredient factories vary by more than just the type of dough, and you need more generic arguments, it's going to get really messy.
And, what happens if, in addition to having options such as thickness that are specific to just one dough type, you need options that are specific to just one thickness? Perhaps thick dough is only an option if you've selected New York or Chicago style (not European) and stuffed crust is only an option if you've selected a thick crust. That's going to get really difficult to describe with interfaces. It sounds more like data.
Here's a stab at another way to implement this:
public enum PizzaStyle
{
NewYork = 1,
Chicago = 2,
Greek = 4
}
public enum CrustType
{
Thick = 1024,
Thin = 2048,
HandTossed = 4096
}
public enum CrustOption
{
Stuffed = 32768
}
public enum PizzaDoughOption
{
NewYorkThin = PizzaStyle.NewYork + CrustType.Thin,
NewYorkHandTossed = PizzaStyle.NewYork + CrustType.HandTossed,
NewYorkThick = PizzaStyle.NewYork + CrustType.Thick,
NewYorkThickStuffed = NewYorkThick + CrustOption.Stuffed,
ChicagoThin = PizzaStyle.Chicago + CrustType.Thin,
ChicagoHandTossed = PizzaStyle.Chicago + CrustType.HandTossed,
ChicagoThick = PizzaStyle.Chicago + CrustType.Thick,
ChicagoThickStuffed = ChicagoThick + CrustOption.Stuffed,
Greek = PizzaStyle.Greek // only comes one way?
}
There are other ways to represent this same data. Even if there were fifty values in the PizzaDoughOption enumeration, it's probably still easier that way, building a definitive, readable list of valid options, as opposed to trying to represent that in code with a bunch of branches. (If you want to unit test that, you'll end up coding every single combination anyway in unit tests.)
And there are several ways you could use this data. You could present just a big list of options. You could allow users to select from the various options and, as you go, determine whether it matches a valid combination. Or they could select any option and you could narrow the list of options according to which include the desired option. (You want a stuffed crust? Ok, that's either New York thick crust or Chicago thick crust.)
Now, if you need a factory to create dough according to type, you could do this:
public interface IDoughFactory
{
Dough GetDough(PizzaDoughOption doughOption);
}
The implementation might look something like this. To be honest I might use a "factory factory" here, but for now since there are only three types I'll keep it simpler.
public class DoughFactory : IDoughFactory
{
// Each of these also implement IDoughFactory
private readonly NewYorkDoughFactory _newYorkDoughFactory;
private readonly ChicagoDoughFactory _chicagoDoughFactory;
private readonly GreekDoughFactory _greekDoughFactory;
public DoughFactory(
NewYorkDoughFactory newYorkDoughFactory,
ChicagoDoughFactory chicagoDoughFactory,
GreekDoughFactory greekDoughFactory)
{
_newYorkDoughFactory = newYorkDoughFactory;
_chicagoDoughFactory = chicagoDoughFactory;
_greekDoughFactory = greekDoughFactory;
}
public Dough GetDough(PizzaDoughOption doughOption)
{
if (MatchesPizzaStyle(doughOption, PizzaStyle.NewYork))
return _newYorkDoughFactory.GetDough(doughOption);
if (MatchesPizzaStyle(doughOption, PizzaStyle.Chicago))
return _chicagoDoughFactory.GetDough(doughOption);
if (MatchesPizzaStyle(doughOption, PizzaStyle.Greek))
return _greekDoughFactory.GetDough(doughOption);
// Throw an exception or return a default dough type. I'd throw the exception.
}
private bool MatchesPizzaStyle(PizzaDoughOption doughOption, PizzaStyle pizzaStyle)
{
return ((int) doughOptions & (int) pizzaStyle) == (int) pizzaStyle;
}
}
Now your more concrete dough factories (New York, Chicago, Greek) all receive the same PizzaDoughOption. If they care whether thin or thick has been selected, they can handle it. If that option doesn't exist they can ignore it. Even if something has gone wrong in an outer class and somehow someone has invoked GreekDoughFactory with the StuffedCrust option, it won't fail. It just ignores it.
What would be the possible point to all of this?
First, the class creating a pizza has no knowledge of the intricacies of creating the right dough type. It just depends on a dough factory, passes a parameter, and gets the right dough. That's simple and testable.
Second, you don't have to call new anywhere. You can employ dependency injection all the way down. That way the class that depends on the abstract IDoughFactory doesn't know anything about what dependencies DoughFactory has.
Likewise, maybe the concrete dough factories have dependencies of their own and they differ significantly from one to the next. As long as those are getting resolved from the container and injected into DoughFactory, that's fine, and DoughFactory won't know anything about their dependencies.
All of the dependencies are wired up in your DI container, but the classes themselves are small, simple, and testable, depending on abstractions and not coupled to implementations of anything.
Someone might look and this and think it's a little more complicated. What's critical is that not only does it keep individual classes decoupled, but it leaves a path forward for future change. The design of your classes, which shouldn't have to change too much, won't closely mirror the details of specific types of pizzas, which can and should change. You don't want to have to re-architect your pizza application because of a new kind of pizza.

How to implement a derived class and call it from a Button?

I am 57 years old. Other than using C# for analysing text data, my knowledge of C# is very limited. However, occasionally I try to learn some other aspects of C#. I also prefer to understand code created for windows applications rather than for console applications.
Could anyone please elaborate on the code given below which is taken from MSDN site with simple practical examples so that I can learn something from it. I think I need to create another class but how to implement it all and call it from a button in C#. Why do they say only derived classes can call 'AddGas'. Thanks in advance.
abstract class Motorcycle
{
// Anyone can call this.
public void StartEngine() {/* Method statements here */ }
// Only derived classes can call this.
protected void AddGas(int gallons) { /* Method statements here */ }
// Derived classes can override the base class implementation.
public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; }
// Derived classes must implement this.
public abstract double GetTopSpeed();
}
Let that you want to create a specific Motorcycle for instance a Yamaha that has another method that returns the color of the Motorcycle. Instead of creating all the method in Motorcycle from scratch for each motorcycle you want to create you could inherit from it as below:
public class Yamaha : Motorcycle
{
public string GetColor()
{
// ....
return "Red";
}
// When a method in class is marked as abstract,
// all the class that inherit should provide an implementation
// of this method. Otherwise you would get a compilation error.
public double GetTopSpeed()
{
return 200;
}
// When a method is marked as virtual, we have two options for the derived classes.
// 1. Use the implementation provided int the base class.
// 2. Override this implementation, define a method like below and provide
// your implementation.
public override int Drive(int miles, int speed)
{
/* Method statements here */ return 2;
}
}
Furthermore, it's important to note here that you can't instantiate an abstract class (you can't create an object as new Motorcycle()).
Why do they say only derived classes can call 'AddGas' ?
Because AddGas is marked as protected. Reading about access modifiers in C# would make this and other related things more clear.
Abstract classes are just templates or guides for how to make something.
In your example, it's a guide for how to make a Motorcycle. You can't actually create a Motorcycle. You can't go into a dealership and ask for one Motorcycle please.
A Honda? Kawasaki? 150cc? 650cc? What?
Your guide tells you that:
It should be able to be started by someone (*public* void StartEngine())
Internally, should be able to add some petrol - sorry, British - (*protected* void AddPetrol(int litres))
It should be able to be driven by someone (*public* virtual int Drive(int miles, int speed))
It has a top speed that someone can read (*public* abstract double GetTopSpeed())
From this, we can see that anyone can start it, drive it, and get it's top speed.
We can also see that the bike itself can add some petrol to itself (it's an internal combustion engine, after all).
You decide on a Honda. Why? Because that's the first Make that comes to mind. So you ask for that one over there. The salesman tells you ah, that's a good starter one, no frills, no extras, it just works. It's a
public class HondaBasic : Motorcycle {
public override double GetTopSpeed()
{
return 60.0;
{
}
It's cute! You should take it out for a spin...
static void Main(string[] args)
{
// "Aww, it looks like something a child would ride!"
var bike = new HondaBasic();
bike.StartEngine();
// "Wow, is that in MPH or Km/h? Either way I could run faster than that!"
var top = bike.GetTopSpeed();
// "Well, lets take it for a spin, at least..."
bike.StartEngine();
var driven = bike.Drive(3, 30);
}
And so there you go, you took your Honda Basic out for a test drive, for 3 miles at 30 MPH.
I'm going to take liberties here and assume that Drive returns the time actually driven, because I figure time is what you get out when you give something a speed and distance.
Apparently you planned to go out for 3 miles at 30 MPH, and you apparently drove for... 1. Because that's what it said you did...
public virtual int Drive(int miles, int speed) { return 1; }
driven == 1 because the base class just returns 1 all the time! I doubt you managed 3 miles - at 30mph - in 1 minute?second? Not important.
I guess as there's nothing around to call AddGas, it probably ran out after only 1 minute?second?...
Well, that was awful. Why did they even make that model? Ok, what about that sweet thing in the corner? It's shiny! And looks as though it was actually build by people that knew... anything at all, to be honest.
public class KawasakiNinja : Motorcycle {
private int _gas;
public KawasakiNinja()
{
_gas = 100;
}
public override int Drive(int miles, int speed)
{
var timeWhateverValue = miles / speed;
_gas -= timeWhateverValue;
return timeWhateverValue;
}
public override double GetTopSpeed()
{
return 300;
}
protected override void AddGas(int gallons)
{
_gas += gallons;
}
public void FillErUp(int gallons)
{
AddGas(gallons);
}
}
Well ok then... This bike looks to actually be something more than a disposable camera with wheels. It can actually be filled up!
Sounds good! Let's take her for a spin!
static void Main(string[] args)
{
// "Mmm, shiny"
var bike = new KawasakiNinja();
// "Purrs like a kitten!"
bike.StartEngine();
// "How fast?!"
var top = bike.GetTopSpeed();
// "Sweet..."
var driven = bike.Drive(1, 300);
// "Holy cap it really can go 300! I bet it burns up fuel like there's no tomorrow, though! Let's pull over"
bike.FillErUp(50);
// "Enough to get back to the lot"
driven = bike.Drive(1, 40);
}
Quite adventurous of you - burning away a single mile at 300 mph! According to Kawasaki's (our) maths, you drove that in 0 minutes?seconds?
Aaaand it had a way to fill the tank (and, frankly, this model actually had a tank).
So, there's something moderately basic for you.
The abstract class itself just describes how to do things. It may or may not include any actual functionality;
It did specify the Drive method, and implemented it - albeit in a basic way
It specified a GetTopSpeed method, but did not implement it (abstract). That method needs to be implemented in anything made from the abstract class - compiler complains at you if you miss that out, so it's easy enough to not miss
Anything derived from the abstract classes have access to everything the abstract class can do, and, if it's virtual, can override it's implementation. Alternatively, it may actually need to provide an implementation of some kind; where the abstract base knows that it will need to be able to something, but not exactly know what or how.
In the above example, it doesn't make sense that a non-existent bike would have a top speed at all - but we know that any real bike in general will have one - so any real bikes need to provide it.

Bit of a brain teaser: Custom logic strings with C# classes

So, my basic set up is like so: I have items, which are restricted to different classes. These items have effects, which are also restricted to different classes. For example, I might have an item that may only be wielded by elves, while another item might be wielded by everyone, but gives specific bonuses/effects to elves.
Here's a Restriction class:
public class Restriction {
private int _base_id = 0;
private bool _qualify = true;
public Restriction() { }
// ... Base_ID and Qualify getters and setters here
public virtual bool Check(int c) {
if(_qualify) { return c == _base_id; }
else { return c != _base_id; }
}
A child of the Restriction class might be RaceRestriction, which only overrides the constructor:
public RaceRestriction(reference.races r, bool qual) {
Base_ID = (int)r; Qualify = qual;
}
reference.races r is an enum in a reference file. The idea here is that I can extend this "Restriction" syntax to any class that I define in the reference file -- so I can make Restrictions on race, class, stats, whatever I need.
So, this all culminates later, when I define (for example) an item, which has restrictions on who can equip it.
Below is a snippet from the Equipment class, where I define a piece of equipment for later use (hopefully it's readable as is):
public Equipment() {
...
_master_equipment_list[1] = new Equipment {
Name = "Sword",
Description = "It's just a sword for demonstration",
Stats = {
new Attribute {
Stat_Modifier = new KeyValuePair<reference.stats, int>(reference.stats.ATTACK, 5),
Restrictions = {
new RaceRestriction(reference.races.TROLL, false)
}
}
},
Restrictions = {
new ClassRestriction(reference.class.WARRIOR, true)
}
}
So the idea behind this is that using this system, I've defined a sword that can only be used by warriors (base warrior true restriction on the item), and it gives 5 attack to any trolls wielding it.
What I've cornered myself into is that this will only work for either logical AND or logical OR strings of thought. Say my item says "warriors can use this" and it says "elves can use this." Do I really mean "warriors or elves" or do I mean "warrior elves?"
That distinction, I think, is going to be necessary -- so I need to attach some logic to each restriction and make, essentially, I think, sets of restrictions that are tied to one another, that string with other sets of restrictions, etc., but I feel like that will get out of hand very fast.
Is there a better way I can do this?
Rather than defining specific restriction classes, I would design this by defining an interface called IRestrictable to be implemented by the Equipment classes. This interface would contain at least one method called CheckEligibility (or similar) which would return a bool. Your equipment class would then be free to use whatever logic expression it liked to come up with the answer, based on whatever inputs you wanted and whatever information the class had available at the time. You could have several methods on the interface if you need to check restrictions under different circumstances. You would be free to implement specific classes deriving from Equipment for specific types of equipment that had complicated rules.

what is the meaning of data hiding

One of the most important aspects of OOP is data hiding. Can somebody explain using a simple piece of code what data hiding is exactly and why we need it?
Data or Information Hiding is a design principal proposed by David Paranas.
It says that you should hide the
design decisions in one part of the
program that are likely to be changed
from other parts of the program, there
by protecting the other parts from
being affected by the changes in the
first part.
Encapsulation is programming language feature which enables data hiding.
However note that you can do data\information hiding even without encapsulation. For example using modules or functions in non Object Oriented programming languages. Thus encapsulation is not data hiding but only a means of achieving it.
While doing encapsulation if you ignore the underlying principal then you will not have a good design. For example consider this class -
public class ActionHistory
{
private string[] _actionHistory;
public string[] HistoryItems
{
get{return _actionHistory; }
set{ _actionHistory = value; }
}
}
This calls encapsulates an array. But it does not hide the design decision of using a string[] as an internal storage. If we want to change the internal storage later on it will affect the code using this class as well.
Better design would be -
public class ActionHistory
{
private string[] _actionHistory;
public IEnumerable<string> HistoryItems
{
get{return _actionHistory; }
}
}
I'm guessing by data hiding you mean something like encapsulation or having a variable within an object and only exposing it by get and modify methods, usually when you want to enforce some logic to do with setting a value?
public class Customer
{
private decimal _accountBalance;
public decimal GetBalance()
{
return _accountBalance;
}
public void AddCharge(decimal charge)
{
_accountBalance += charge;
if (_accountBalance < 0)
{
throw new ArgumentException(
"The charge cannot put the customer in credit");
}
}
}
I.e. in this example, I'm allowing the consuming class to get the balance of the Customer, but I'm not allowing them to set it directly. However I've exposed a method that allows me to modify the _accountBalance within the class instance by adding to it via a charge in an AddCharge method.
Here's an article you may find useful.
Information hiding (or more accurately encapsulation) is the practice of restricting direct access to your information on a class. We use getters/setters or more advanced constructs in C# called properties.
This lets us govern how the data is accessed, so we can sanitize inputs and format outputs later if it's required.
The idea is on any public interface, we cannot trust the calling body to do the right thing, so if you make sure it can ONLY do the right thing, you'll have less problems.
Example:
public class InformationHiding
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
/// This example ensures you can't have a negative age
/// as this would probably mess up logic somewhere in
/// this class.
private int _age;
public int Age
{
get { return _age; }
set { if (value < 0) { _age = 0; } else { _age = value; } }
}
}
Imagine that the users of your class are trying to come up with ways to make your class no longer fulfill its contract. For instance, your Banking object may have a contract that ensures that all Transactions are recorded in a log. Suppose mutation of the Bank's TransactionLog were publically accessible; now a consuming class could initiate suspect transactions and modify the log to remove the records.
This is an extreme example, but the basic principles remain the same. It's up to the class author to maintain the contractual obligations of the class and this means you either need to have weak contractual obligations (reducing the usefulness of your class) or you need to be very careful about how your state can be mutated.
What is data hiding?
Here's an example:
public class Vehicle
{
private bool isEngineStarted;
private void StartEngine()
{
// Code here.
this.isEngineStarted = true;
}
public void GoToLocation(Location location)
{
if (!this.isEngineStarted)
{
this.StartEngine();
}
// Code here: move to a new location.
}
}
As you see, the isEngineStarted field is private, ie. accessible from the class itself. In fact, when calling an object of type Vehicle, we do need to move the vehicle to a location, but don't need to know how this will be done. For example, it doesn't matter, for the caller object, if the engine is started or not: if it's not, it's to the Vehicle object to start it before moving to a location.
Why do we need this?
Mostly to make the code easier to read and to use. Classes may have dozens or hundreds of fields and properties that are used only by them. Exposing all those fields and properties to the outside world will be confusing.
Another reason is that it is easier to control a state of a private field/property. For example, in the sample code above, imagine StartEngine is performing some tasks, then assigning true to this.isEngineStarted. If isEngineStarted is public, another class would be able to set it to true, without performing tasks made by StartEngine. In this case, the value of isEngineStarted will be unreliable.
Data Hiding is defined as hiding a base class method in a derived class by naming the new class method the same name as the base class method.
class Person
{
public string AnswerGreeting()
{
return "Hi, I'm doing well. And you?";
}
}
class Employee : Person
{
new public string AnswerGreeting()
{
"Hi, and welcome to our resort.";
}
}
In this c# code, the new keyword prevents the compiler from giving a warning that the base class implementation of AnswerGreeting is being hidden by the implementation of a method with the same name in the derived class. Also known as "data hiding by inheritance".
By data hiding you are presumably referring to encapsulation. Encapsulation is defined by wikipedia as follows:
Encapsulation conceals the functional
details of a class from objects that
send messages to it.
To explain a bit further, when you design a class you can design public and private members. The class exposes its public members to other code in the program, but only the code written in the class can access the private members.
In this way a class exposes a public interface but can hide the implementation of that interface, which can include hiding how the data that the class holds is implemented.
Here is an example of a simple mathematical angle class that exposes values for both degrees and radians, but the actual storage format of the data is hidden and can be changed in the future without breaking the rest of the program.
public class Angle
{
private double _angleInDegrees;
public double Degrees
{
get
{
return _angleInDegrees;
}
set
{
_angleInDegrees = value;
}
}
public double Radians
{
get
{
return _angleInDegrees * PI / 180;
}
set
{
_angleInDegrees = value * 180 / PI;
}
}
}

Architecture for Game - To couple or not to couple?

I'm building a simple game which consists of Mobiles -- the in-game characters (Mobs). Each mob can perform certain functions. In order to give that functionality to the Mob, I've created a Behavior.
For example, let's say a mob needs to move around the game field, I would give it the MoveBehavior - this is added to an internal list of Behaviors for the mob class:
// Defined in the Mob class
List<Behavior> behaviors;
// Later on, add behavior...
movingMob.addBehavior(new MovingBehavior());
My question is this. Most behaviors will manipulate something about the mob. In the MoveBehavior example, it will change the mob's X,Y position in the world. However, each behavior needs specific information, such as "movementRate" -- where should movementRate be stored?
Should it be stored in the Mob class? Other Mobs may attempt to interact with it by slowing/speeding up the mob and it's easier to access at the mob level... but not all mobs have a movementRate so it would cause clutter.
Or should it be stored in the MoveBehavior class? This hides it away, making it a little harder for other mobs to interact with - but it doesn't clutter up a non-moving mob with extra and un-used properties (for example, a tower that doesn't move would never need to use the movementRate).
This is the classic "behavioral composition" problem. The trade-off is that the more independent the behaviors are, the more difficult it is for them to interact with each other.
From a game programming viewpoint, the simplest solution is a decide on a set of "core" or "engine" data, and put that in the main object, then have the behaviors be able to access and modify that data - potentially through a functional interface.
If you want behavior specific data, that's fine, but to avoid collisions in the names of variables, you may want to make the interface for accessing it include the behavior name. Like:
obj.getBehaviorValue("movement", "speed")
obj.setBehaviorValue("movement", "speed", 4)
That way two behaviors can both define their own variables called speed and not collide. This type of cross-behavior getters and setters would allow communication when it is required.
I'd suggest looking at a scripting language like Lua or Python for this..
You could borrow a pattern from WPF (attached properties). The WPF guys needed a way to sort of attach properties to controls at run time. (for example, if you put a control inside a grid, it would be nice for the control to have a Row property -- they pseudo did this with attached properties.
It works something like: (note this probably doesn't precisely match WPF's implementation, and I'm leaving out the dependency property registration, as you aren't using XAML)
public class MoveBehavior: Behavior
{
private static Dictionary<Mob, int> MovementRateProperty;
public static void SetMovementRate(Mob theMob, int theRate)
{
MovementRateProperty[theMob] = theRate;
}
public static int GetMovementRate(Mob theMob)
{
// note, you will need handling for cases where it doesn't exist, etc
return MovementRateProperty[theMob];
}
}
The thing here is that the Behavior owns the property, but you don't have to go spelunking to get it Here's some code that retrieves a mob's movement rate:
// retrieve the rate for a given mob
int rate = MoveBehavior.GetMovementRate(theMob);
// set the rate for a given mob
MoveBehavior.SetMovementRate(mob, 5);
If it is related to the behavior, and only makes sense in the context of that behavior, then it should be stored as part of it.
A movement rate only makes sense for something that can move. Which means it should be stored as part of the object that represents its ability to move, which seems to be your MoveBehavior.
If that makes it too hard to access, it sounds more like a problem with your design. Then the question is not "should I cheat, and place some of the variables inside the Mob class instead of the behavior it belongs to", but rather "how do I make it easier to interact with these individual behaviors".
I can think of several ways to implement this. The obvious is a simple member function on the Mob class which allows you to select individual behaviors, something like this:
class Mob {
private List<Behavior> behaviors;
public T Get<T>(); // try to find the requested behavior type, and return it if it exists
}
Others can then do something like this:
Mob m;
MovementBehavior b = m.Get<MovementBehavior();
if (b != null) {
b.SetMovementRate(1.20f);
}
You might also place some of this outside the Mob class, creating a helper function which modifies the movement rate if it exists, and does nothing otherwise:
static class MovementHelper {
public static SetMovementRate(Mob m, float movementrate){
MovementBehavior b = m.Get<MovementBehavior();
if (b != null) {
b.SetMovementRate(1.20f);
}
}
}
and then others could use it like this:
MovementHelper.SetMovementRate(m, 1.20f);
which would provide easy access to modifying the behavior, but without cluttering up the Mob class. (Of course, it'd be tempting to turn this into an extension method, but that might lead to too much assorted clutter in the Mob class' public interface. It may be preferable to make it clear that this is helper functionality that resides outside the Mob class itself)
Take a look at component systems/entity systems design:
http://www.devmaster.net/articles/oo-game-design/
By far the best I've seen till now.
Smart people say it's the only way to go with larger games, but it requires a shift in how you think about OOP.
So what are you trying to do?
What's the simplest way for you to store the movement rate data?
If it is only needed in the MoveBehavior class then it should be in there:
public class MoveBehavior {
public int MovementRate { get; set; }
}
If it is needed inherently by the Mob class then it will be easier exposed through the Mob class:
public class Mob {
public int MovementRate { get; set; }
}
public class MoveBehavior {
public MoveBehavior(Mob mob) { MobInEffect = mob; }
public Mob MobInEffect {get; set;}
// can access MovementRate through MovInEffect.MovementRate
}
So it all depends on what you're trying to achieve with this behavior logic. I'd recommend you push the design decision until you really need to do it one way or another. Concentrate on doing it simple first and refactor later. Usually more often than not, doing early design guesswork can lead to overcomplicated architecture.
A more pragmatic solution…
What I mean is that you implement whatever you wanted from movement the in the Mob class first:
public class Mob {
// Constructors and stuff here
public void Move(long ticks)
{
// do some voodoo magic with movement and MovementRate here
}
protected int MovementRate { get; set; }
}
And when that works, rip out that implementation to a MoveBehavior class if you really need to:
public class Mob {
// Constructors and stuff here
public MoveBehavior Moving { set; get; }
public void Move(long ticks)
{
Moving.Move(ticks, this);
}
}
public class MoveBehavior {
protected int MovementRate { get; set; }
public void Move(long ticks, Mob mob)
{
// logic moved over here now
}
}
After that if you really need to do more than one type of behavior but they share a common interface then create that interface by then and let the behaviors implement that.
Edit: The below answer only really makes sense if you're not instancing a new MovingBehavior for every mob, but just have a singleton MovingBehavior.
I'd say that the mob (ugh, I hate that word for game NPCs, but it's not your fault) should, when addBehavior() is called, get a BehaviorState object that's returned from addBehavior() and that it keeps around, and is keyed to the behavior added. Then provide an interface for MovingBehavior to easily retrieve its BehaviorState object from movingMob, and it stores whatever it needs to store there.
If i was designing something like this i would try out using interfaces to define which behaviors a mob has:
public interface IMovable
{
int MovementRate { get; set; }
void MoveTo(int x, int y);
}
public class Monster : Mob, IMovable
{
public int MovementRate { get; set; }
public void MoveTo(int x, int y)
{
// ...
}
}
This way you can check if a mob can move by doing something like this:
Monster m = new Monster();
if (m is IMovable)
{
m.MoveTo(someX, someY);
}
IMHO, the movement rate is associated with the movingBehavior rather than with a Mob itself, and as you said, it doesn't necessarily move. So the variable should be associated with the behavior, a change in the movementRate is a change to his Behavior, not to the mob himself.
You could also create a base Mob class, and derive a MovingMob one. But I guess, this doesn't really apply, once apparently you can have an arbitrary combination of different behaviors...
-- EDIT --
First, apparently you won't have the same type of behavior twice in the same Mob (like, no mob has two movementBehaviors at the same type), so a set is a better option in this case, as it avoids duplicates
You could have a method in each mob like
public Behavior GetBehavior(Type type)
{
foreach (var behavior in behaviorHashSet)
{
if ( behavior.GetType() == type)
return behavior;
}
return null;
}
Then you could do whatever you want with this behavior once you have a Mob. Also, you could change the GetHashCode() and Equals() method to ensure you have no duplicate, or make the GetBehavior method even faster (constant time)

Categories

Resources