设计原则:
一 开闭原则 (OCP OpenClosed Principle)
一个软件实体应当对扩展开放,对修改关闭
通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,使变化中的软件系统有一定的适应性和灵活性
已有的软件模块,特别是最重要的抽象层模块不能再修改,这就使变化中的软件系统有一定的稳定性和延续性
里氏代换原则: 任何基类可以出现的地方,子类一定可以出现
一般违反里氏代换原则也违反开闭原则 反过来不成立
依赖倒转原则: 要依赖于抽象,不要依赖于实现
合成/聚合复用原则: 尽量使用合成/聚合,而不是继承关系达到复用的目的
迪米特法则: 一个软件实体应当与尽可能少的其他实体发生相互作用
接口隔离原则: 为客户端提供尽可能小的单独的借口,而不要提供大的总接口
抽象类: 不可以实例化, 用来继承
二 里氏代换原则 (LSP Liskov Substrtution Principle)
一个软件实体如果使用的是一个基类的话,那么一定适合于其子类,而且它根本不能察觉出基类对象和子类对象的区别
三 依赖倒转原则 (DIP Dependence Inversion Principle)
依赖于抽象 不依赖于具体
三种耦合关系:
零耦合
具体耦合 由一个类对另一个类的直接引用造成
抽象耦合 一个具体类和一个抽象类之间 使两个必须发生关系的类之间寸有最大的灵活性
抽象不应当依赖细节 细节依赖于抽象
接口编程 不要针对实现编程
四 接口隔离原则 (ISP Interface Segregation Principle)
使用多个专门的接口比使用单一的总接口要好
五 合成/聚合复用原则 (CARP Composite/Aggregate Reuse Principle)
在一个新的对象里面使用一些已有的对象,使之成为新对象的一部门;新的对象通过向这些对象的委派达到复用已有功能的目的
合成/聚合复用
优点:
新对象存取成分对象的唯一方法是通过成分对象的接口
黑箱复用,因为成分对象的内部细节是新对象所看不见的
复用支持包装
复用所需的依赖较少
每一个新的类可以将焦点集中在一个任务上
这种复用可以在运行时间内动态进行,新对象可以动态的引用与成分对象类型相同的对象
缺点:
较多的对象需要管理
继承复用的优点:
新的实现较为容易,因为超类的大部分功能可以通过继承关系自动进入子类
修改或扩展继承而来的实现较为容易
缺点:
破坏包装,因为继承将超类的实现细节暴露个子类.由于超类的内部细节常常对子类透明的,叫透明的复用,“白箱“复用.
如果超类的实现发生改变,那么子类 实现也不得不发生改变
从超类继承而来的实现是静态的,不可能在运行时间内发生改变,没有足够的灵活性
六 迪米特法则 (LOD Law of Demeter)
一个对象应当对其他对象有尽可能少的了解
创建型模式 : 管理并隔离对象实例的构造过程
是对类的实例化过程的抽象化。一些系统在创建对象时,需要动态的决定怎样创建对象,创建哪些对象,以及如何组合和表示这些对象。创建模式描述了怎么构造和封装这些这些动态的决定.
类的创建模式: 使用继承关系,把类的创建延迟到子类,从而封装了客户端将得到哪些具体类的信息,并且隐藏了这些类的实例是如何创建和防在一起的
对象的创建模式: 把对象的创建过程动态的委派给另一个对象,从而动态的决定客户端将得到哪些具体类的实例,以及这些类的实例是如何被创建和组合在一起的
简介:
为了隔离客户程序与具体类型实例化的依赖关系,通过将实例化职责委托他方对象的办法,保证客户程序获得期望具体类型实例的同时不必发生直接的引用
一 工厂模式 Factory Method
public interface IProduct { }
public class ConcreteProductA : IProduct { }
public class ConcreteProductB : IProduct { }
public enum Category
{
A,B
}
public static class ProductFactort
{
public static IProduct Create(Category category)
{
switch (category)
{
case Category.A:
return new ConcreteProductA();
case Category.B:
return new ConcreteProductB();
default:
throw new NotSupportedException();
}
}
}
Test: IProduct product = ProductFactort.Create(Category.B);
工厂方法:
public interface IProduct { string Name { get;} }
public class ProductA : IProduct { public string Name { get { return "A"; } } }
public class ProductB : IProduct { public string Name { get { return "B"; } } }
public interface IFactory { IProduct Create();}
public class FactoryA : IFactory
{
public IProduct Create()
{
return new ProductA();
}
}
public class FactoryB : IFactory
{
public IProduct Create()
{
return new ProductB();
}
}
二 单件模式 Singleton
public class Singleton
{
private static Singleton instance;
protected Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
}
多线程下:
public class Singleton
{
private static volatile Singleton instance = null;
protected Singleton() { }
public static Singleton Instance()
{
if (instance == null)
lock(typeof(Singleton))
if (instance == null)
instance = new Singleton();
return instance;
}
}
简单的:
public class Singleton
{
private Singleton() { }
public static readonly Singleton Instance = new Singleton();
}
三 抽象工厂 Abstract Factory
public interface IProductA { }
public interface IProductB { }
public interface IAbstractFactory
{
IProductA CreateProductA();
IProductB CreateProductB();
}
public class ProductA1 : IProductA { }
public class ProductA2X : IProductA { }
public class ProductA2Y : IProductA { }
public class ProductB1 : IProductB { }
public class ProductB2 : IProductB { }
public class ConcreteFactory1 : IAbstractFactory
{
public virtual IProductA CreateProductA() { return new ProductA1(); }
public virtual IProductB CreateProductB() { return new ProductB1(); }
}
public class ConcreteFactory2 : IAbstractFactory
{
public virtual IProductA CreateProductA() { return new ProductA2Y(); }
public virtual IProductB CreateProductB() { return new ProductB2(); }
}
Test:
IAbstractFactory factory = new ConcreteFactory2();
IProductA productA = factory.CreateProductA();
IProductB productB = factory.CreateProductB();
四 创建者模式 Builder
生产非同源产品:
public class House
{
public void AddWindowAndDoor() { }
public void AddWallAndFloor() { }
public void AddCeiling() { }
}
public class Car
{
public void AddWheel() { }
public void AddEngine() { }
public void AddBody() { }
}
public interface IBuilder
{
void BuildPart1();
void BuildPart2();
void BuildPart3();
}
public class CarBuilder : IBuilder
{
private Car car;
public void BuildPart1() { car.AddEngine(); }
public void BuildPart2() { car.AddWheel(); }
public void BuildPart3() { car.AddBody(); }
public Car GetResult() { return car; }
}
public class HouseBuilder : IBuilder
{
private House house;
public void BuildPart1() { house.AddWallAndFloor(); }
public void BuildPart2() { house.AddWindowAndDoor(); }
public void BuildPart3() { house.AddCeiling(); }
public House GetResult() { return house; }
}
public class Director
{
public void Construct(IBuilder builder)
{
builder.BuildPart1();
builder.BuildPart2();
builder.BuildPart3();
}
}
生产同源产品:
public interface Iproduct { string Name { get;set;} }
public class ConcreteProduct : Iproduct
{
protected string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
public interface IBuilder
{
void BuildPart();
Iproduct BuildUp();
}
public class ConcreteBuilderA : IBuilder
{
private Iproduct product = new ConcreteProduct();
public void BuildPart() { product.Name = "A"; }
public Iproduct BuildUp() { return product; }
}
public class Director
{
public void Construct(IBuilder builder) { builder.BuildPart(); }
}
五 原型模式 Prototype
public interface IPrototype
{
IPrototype Clone();
string Name { get;set;}
}
public class ConcretePrototype : IPrototype
{
public IPrototype Clone()
{
return (IPrototype)this.MemberwiseClone();
}
private string name;
public string Name
{
get { return this.name; }
set { this.name = value; }
}
}
结构型模式 :针对变化组织灵活的对象体系
简介: 通过灵活的体系组织不同的对象,并在此基础上完成更为复杂的类型,而参与组合的各类型之间始终保持尽量松散的结构关系
将类和读系结合在一起形成更大的结构
类的结构模式: 使用继承把类,接口等组合在一起,以形成更大的结构。当一个类从父类继承并实现某接口时,这个新的类就把父类的结构和接口的结构结合起来。类的结构模式是静态的
对象的结构模式:对象的结构模式描述怎样把各种不同类型的对象组合在一起,以实现新的功能的方法。对象的结构模式是动态的
六 适配器模式 Adapter
public interface ITarget
{
void Request();
}
public class Adaptee
{
public void SpecifiedRequest() { }
}
//类
public class Adapter1 : Adaptee, ITarget
{
public void Request()
{
base.SpecifiedRequest();
}
}
//对象
public class Adapter2 : ITarget
{
private Adaptee adaptee;
public void Request()
{
adaptee.SpecifiedRequest();
}
}
七 桥模式 Bridge
public interface IImpl
{
void OperationImpl();
}
public interface IAbstraction
{
IImpl Implementor { get;set;}
void Operation();
}
public class ConcreteImplementatorA : IImpl { public void OperationImpl() { } }
public class ConcreteImplementatorB : IImpl { public void OperationImpl() { } }
public class RefinedAbstraction : IAbstraction
{
private IImpl implementor;
public IImpl Implementor
{
get { return this.implementor; }
set { this.implementor = value; }
}
public void Operation()
{
implementor.OperationImpl();
}
}
八 组合模式 Composite
public abstract class Component
{
protected IList<Component> children;
protected string name;
public virtual string Name
{
get { return this.name; }
set { this.name = value; }
}
public virtual void Add(Component child) { children.Add(child); }
public virtual void Remove(Component child) { children.Remove(child); }
public virtual Component this[int index] { get { return children[index]; } }
public virtual IEnumerable<string> GetNameList()
{
yield return name;
if ((children != null) && (children.Count > 0))
{
foreach(Component child in children)
{
foreach(string item in child.GetNameList())
{
yield return item;
}
}
}
}
}
public class Leaf : Component
{
public override void Add(Component child)
{
throw new NotSupportedException();
}
public override void Remove(Component child)
{
throw new NotSupportedException();
}
public override Component this[int index]
{
get
{
throw new NotSupportedException();
}
}
}
public class Composite : Component
{
public Composite() { base.children = new List<Component>(); }
}
public class ComponentFactory
{
public Component Create<T>(string name) where T : Component, new()
{
T instance = new T();
instance.Name = name;
return instance;
}
public Component Create<T>(Component parent, string name) where T : Component, new()
{
if (parent == null) throw new ArgumentNullException("parent");
if (!(parent is Composite)) throw new Exception("non-somposite type");
Component instance = Create<T>(name);
parent.Add(instance);
return instance;
}
}
Test:
ComponentFactory factory = new ComponentFactory();
Component corporate = factory.Create<Composite>("corporate");
factory.Create<Leaf>(corporate,"a");
factory.Create<Leaf>(corporate,"b");
IList<string> names = new List<string>(corporate.GetNameList());
九 装饰模式 Decorator
public interface IText
{
string Content { get;}
}
public interface IDecorator : IText { }
public abstract class DecoratorBase : IDecorator
{
protected IText target;
public DecoratorBase(IText target) { this.target = target; }
public abstract string Content { get;}
}
public class BoldDecorator : DecoratorBase
{
public BoldDecorator(IText target) : base(target) { }
public override string Content
{
get { return ChangeToBoldFont(target.Content); }
}
public string ChangeToBoldFont(string content)
{
return content;
}
}
public class TextObject : IText
{
public string Content { get { return "hello"; } }
}
Text:
IText text = new TextObject();
text = new BoldDecorator(text);
十 外观模式 Façade
public class DataFacade
{
private const string dbName = "AdventureWorks";
private static DbProviderFactory factory;
private static string connectionString;
static DataFacade()
{
ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[dbName];
factory = DbProviderFactories.GetFactory(settings.ProviderName);
connectionString = settings.ConnectionString;
}
private static DbConnection CreateConnection()
{
DbConnection connection = factory.CreateConnection();
connection.ConnectionString = DataFacade.connectionString;
return connection;
}
public DataSet ExecuteQuery(string sql)
{
if (string.IsNullOrEmpty(sql)) throw new ArgumentNullException("sql");
using (DbConnection connection = CreateConnection())
{
DbCommand command = connection.CreateCommand();
command.CommandText = sql;
command.CommandType = CommandType.Text;
DbDataAdapter adapter = factory.CreateDataAdapter();
adapter.SelectCommand = command;
DataSet result = new DataSet();
adapter.Fill(result);
return result;
}
}
}
Test:
DataFacade facade = new DataFacade();
DataSet result = facade.ExecuteQuery("SELECT TOP 10 CurrencyCode, Name FROM Sales.Currency");
十一 享元模式 Flyweight
public abstract class FoodBase
{
private IList<string> tastes = new List<string>();
private string name;
public FoodBase(string name) { this.name = name; }
public FoodBase AddTaste(string taste)
{
tastes.Add(taste);
return this;
}
public virtual string Name { get { return this.name; } }
}
public class Capsicum : FoodBase
{
public Capsicum() : base("Capsicum") { base.AddTaste("Hot"); }
public string MostPopularInCuisine { get { return "川菜"; } }
}
public class FoodFactory
{
private IDictionary<string, FoodBase> dictionary = new Dictionary<string, FoodBase>();
public FoodBase Create(string name)
{
FoodBase result;
if (dictionary.TryGetValue(name, out result))
return result;
switch (name)
{
case "Capsicum":
result = new Capsicum();
break;
}
dictionary.Add(result.Name,result);
return result;
}
}
十二 代理模式 Proxy
public interface ISubject
{
string Request();
}
public class RealSubject : ISubject
{
public string Resquest() { return "from real subject"; }
private static ISubject singleton = new RealSubject();
private RealSubject() { }
public static ISubject Singleton { get { return singleton; } }
}
public class Proxy : ISubject
{
public string Request() { return RealSubject.Singleton.Request(); }
}
三. 行为型模式 : 算法,控制流和通信关系的对象化处理
简介:关注于应用运行过程中算法的提供和通信关系的梳理
对在不同的对象之间划分责任和算法的抽象化。不仅关于类和对象的,而且是关于他们之间的相互作用的
类的行为模式 : 使用继承关系在几个类之间分配行为.
对象的行为模式 : 读系的行为模式使用对象的聚合来分配行为
十三 职责链模式 Chain of Responsibility
public class Request
{
private double price;
private PurchaseType type;
public Request(double price, PurchaseType type)
{
this.price = price; this.type = type;
}
public double Price { get { return price; } set { price = value; } }
public PurchaseType Type { get { return type; } set { type = value; } }
}
public interface IHandler
{
void HandleRequest(Request request);
IHandler Successor { get; set;}
PurchaseType Type { get; set;}
}
public abstract class HandlerBase : IHandler
{
protected IHandler successor;
protected PurchaseType type;
public HandlerBase(PurchaseType type, IHandler successor)
{
this.type = type;
this.successor = successor;
}
public HandlerBase(PurchaseType type) : this(type, null) { }
public IHandler Successor { get { return successor; } set { successor = value; } }
public PurchaseType Type { get { return type; } set { type = value; } }
public abstract void Process(Request request);
public virtual void HandleRequest(Request request)
{
if (request == null) return;
if (request.Type == Type)
Process(request);
else
if (Successor != null)
successor.HandleRequest(request);
}
}
public class InternalHandler : HandlerBase
{
public InternalHandler() : base(PurchaseType.Internal) { }
public override void Process(Request request) { request.Price *= 0.6; }
}
public class MailHandler : HandlerBase
{
public MailHandler() : base(PurchaseType.Mail) { }
public override void Process(Request request) { request.Price *= 1.3; }
}
public class DiscountHandler : HandlerBase
{
public DiscountHandler() : base(PurchaseType.Discount) { }
public override void Process(Request request) { request.Price *= 0.9; }
}
public class RegularHandler : HandlerBase
{
public RegularHandler() : base(PurchaseType.Regular) { }
public override void Process(Request request) { }
}
Test:
IHandler handler1 = new InternalHandler();
IHandler handler2 = new DiscountHandler();
IHandler handler3 = new MailHandler();
IHandler handler4 = new RegularHandler();
handler1.Successor = handler3;
handler3.Successor = handler2;
handler2.Successor = handler4;
IHandler head = handler1;
Request request = new Request(20, PurchaseType.Mail);
head.HandleRequest(request);
handler1.Successor = handler1.Successor.Successor;
request = new Request(20, PurchaseType.Discount);
head.HandleRequest(new Request(20, PurchaseType.Discount));
十四 模板方法模式 Template Method
public interface IAbstract
{
int Quantity { get;}
double Total { get;}
double Average { get;}
}
public abstract class AbstractBase : IAbstract
{
public abstract int Quantity { get;}
public abstract double Total { get;}
public virtual double Average { get { return Total / Quantity; } }
}
public class ArrayData : AbstractBase
{
protected double[] data = new double[3] { 1.1,2.2,3.3};
public override int Quantity
{
get { return data.Length; }
}
public override double Total
{
get
{
double count = 0;
for (int i = 0; i < data.Length; i++)
count += data[i];
return count;
}
}
}
十五 解释器模式 Interpreter
public class Context
{
public int Value;
public char Operator;
}
public interface IExpression
{
void Evaluate(Context context);
}
public class Operator : IExpression
{
private char op;
public Operator(char op) { this.op = op; }
public virtual void Evaluate(Context context) { context.Operator = op; }
}
public class Operand : IExpression
{
int num;
public Operand(int num) { this.num = num; }
public virtual void Evaluate(Context c)
{
switch(c.Operator)
{
case '/0': c.Value = num; break;
case '+': c.Value += num; break;
case '-': c.Value -= num; break;
}
}
}
public class Calcuator
{
public int Calculate(string expression)
{
Context context = new Context();
IList<IExpression> tree = new List<IExpression>();
char[] elements = expression.ToCharArray();
foreach(char c in elements)
{
if ((c == '+') || (c == '-'))
{
tree.Add(new Operator(c));
}
else
{
tree.Add(new Operand((int)(c-48)));
}
}
foreach (IExpression exp in tree)
exp.Evaluate(context); return context.Value;
}
}
十六 命令模式Command
public class Receiver
{
private string name = string.Empty;
public string Name { get { return name; } }
private string address = string.Empty;
public string Address { get { return address; } }
public void SetName() { name = "name"; }
public void SetAddress() { address = "address"; }
}
public interface ICommand
{
void Execute();
Receiver Receiver { set;}
}
public abstract class CommandBase : ICommand
{
protected Receiver receiver;
public Receiver Receiver { set { receiver = value; } }
public abstract void Execute();
}
public class SetNameCommand : CommandBase
{
public override void Execute() { receiver.SetName(); }
}
public class SetAddressCommand : CommandBase
{
public override void Execute() { receiver.SetAddress(); }
}
public class Invoker
{
private IList<ICommand> commands = new List<ICommand>();
public void AddCommand(ICommand command) { commands.Add(command); }
public void Run()
{
foreach (ICommand command in commands)
command.Execute();
}
}
Test:
public void Test()
{
Receiver receiver = new Receiver();
ICommand command1 = new SetNameCommand();
ICommand command2 = new SetAddressCommand();
command1.Receiver = receiver;
command2.Receiver = receiver;
Invoker invoker = new Invoker();
invoker.AddCommand(command1);
invoker.AddCommand(command2);
invoker.Run();
}
十七 迭代器模式Iterator
public interface IIterator
{
string Next();
}
public interface IAggregate
{
string[] Messages { get;}
void Add(string message);
IIterator CreaetIterator();
}
public class Aggregate : IAggregate
{
public const int Max = 5;
private string[] messages = new string[Max];
public string[] Messages { get { return messages; } }
private int capacity = 0;
public int Capacity { get { return capacity; } }
public void Add(string message)
{
if (capacity == Max) throw new IndexOutOfRangeException();
messages[capacity++] = message;
}
public IIterator CreaetIterator(){return new Iterator(this);}
}
public class Iterator : IIterator
{
private Aggregate aggregate;
private int index;
public Iterator(Aggregate aggregate)
{
this.aggregate = aggregate;
index = 0;
}
public string Next()
{
if (index == aggregate.Capacity) throw new IndexOutOfRangeException();
return aggregate.Messages[index++];
}
}
Test:
public void Test()
{
IAggregate target = new Aggregate();
target.Add("A");
target.Add("B");
IIterator iterator = target.CreaetIterator();
try
{
iterator.Next();
}
catch (Exception exception)
{
}
}
十八 中介者模式Mediator
public class Mediator<T> : IMediator<T>
{
protected IColleague<T> provider = null;
protected IList<IColleague<T>> consumers = null;
public virtual void Change()
{
if ((provider != null) && (consumers != null))
foreach (IColleague<T> colleague in consumers)
colleague.Data = provider.Data;
}
public virtual void Introduce(IColleague<T> provider, IList<IColleague<T>> consumers)
{
this.provider = provider;
this.consumers = consumers;
}
public virtual void Introduce(IColleague<T> provider, IColleague<T> consumer)
{
IList<IColleague<T>> consumers = new List<IColleague<T>>();
consumers.Add(consumer);
this.provider = provider;
this.consumers = consumers;
}
public virtual void Introduce(IColleague<T> provider, params IColleague<T>[] consumers)
{
if (consumers.Length > 0)
{
IList<IColleague<T>> array = new List<IColleague<T>>(consumers);
this.consumers = array;
}
this.provider = provider;
}
}
public interface IColleague<T>
{
T Data { get; set;}
IMediator<T> Mediator { get; set;}
}
public abstract class ColleagueBase<T> : IColleague<T>
{
protected T data;
protected IMediator<T> mediator;
public virtual T Data
{
get { return data; }
set { data = value; }
}
public virtual IMediator<T> Mediator
{
get { return mediator; }
set { mediator = value; }
}
}
public interface IMediator<T>
{
void Change();
void Introduce(IColleague<T> provider, IList<IColleague<T>> consumers);
void Introduce(IColleague<T> provider, IColleague<T> consumer);
void Introduce(IColleague<T> provider, params IColleague<T>[] consumers);
}
十九 备忘录模式Memento
public interface IState { }
public interface IMemento<T> where T : IState
{
T State { get; set;}
}
public abstract class MementoBase<T> : IMemento<T>
where T : IState
{
protected T state;
public virtual T State
{
get { return state; }
set { state = value; }
}
}
public interface IOriginator<T, M>
where T : IState
where M : IMemento<T>, new()
{
IMemento<T> Memento { get;}
}
public abstract class OriginatorBase<T, M>
where T : IState
where M : IMemento<T>, new()
{
protected T state;
public virtual IMemento<T> Memento
{
get
{
M m = new M();
m.State = this.state;
return m;
}
set
{
if (value == null) throw new ArgumentNullException();
this.state = value.State;
}
}
}
public struct Position : IState
{
public int X;
public int Y;
}
public class Memento : MementoBase<Position> { }
public class Originator : OriginatorBase<Position, Memento>
{
public void UpdateX(int x) { base.state.X = x; }
public void DecreaseX() { base.state.X--; }
public void IncreaseY() { base.state.Y++; }
public Position Current { get { return base.state; } }
}
二十 观察者模式 Observer
public interface IObserver<T>
{
void Update(SubjectBase<T> subject);
}
public abstract class SubjectBase<T>
{
protected IList<IObserver<T>> observers = new List<IObserver<T>>();
protected T state;
public virtual T State{get{return state;}}
public static SubjectBase<T> operator +(SubjectBase<T> subject, IObserver<T> observer)
{
subject.observers.Add(observer);
return subject;
}
public static SubjectBase<T> operator -(SubjectBase<T> subject, IObserver<T> observer)
{
subject.observers.Remove(observer);
return subject;
}
public virtual void Notify()
{
foreach (IObserver<T> observer in observers)
observer.Update(this);
}
public virtual void Update(T state)
{
this.state = state;
Notify();
}
}
public class SubjectA<T> : SubjectBase<T> { }
public class SubjectB<T> : SubjectBase<T> { }
public class Observer<T> : IObserver<T>
{
public T State;
public void Update(SubjectBase<T> subject)
{
this.State = subject.State;
}
}
二十一 状态模式 State
public interface IState
{
void Open();
void Close();
void Query();
}
public abstract class ContextBase
{
private IState state;
public virtual IState State
{
get { return state; }
set { state = value; }
}
public virtual void Open() { state.Open(); }
public virtual void Close() { state.Close(); }
public virtual void Query() { state.Query(); }
}
二十二 策略模式 Strategy
public interface IStrategy
{
int PickUp(int[] data);
}
public interface IContext
{
IStrategy Strategy { get; set;}
int GetData(int[] data);
}
二十三 访问者模式 Visitor
public interface IEmployee
{
string Name { get; set;}
double Income { get; set;}
int VacationDays { get; set;}
void Accept(IVisitor visitor);
}
public interface IVisitor
{
void VisitEmployee(IEmployee employee);
void VisitManager(Manager manager);
}
public class Employee : IEmployee
{
private string name;
private double income;
private int vacationDays;
public Employee(string name, double income, int vacationDays)
{
this.name = name;
this.income = income;
this.vacationDays = vacationDays;
}
public string Name
{
get{return name;}
set{name = value;}
}
public double Income
{
get{return income;}
set{income = value;}
}
public int VacationDays
{
get{return vacationDays;}
set{vacationDays = value;}
}
public virtual void Accept(IVisitor visitor)
{
visitor.VisitEmployee(this);
}
}
public class Manager : Employee
{
private string department;
public string Department { get { return department; } }
public Manager(string name, double income, int vacationDays, string department)
: base(name, income, vacationDays)
{
this.department = department;
}
public override void Accept(IVisitor visitor)
{
visitor.VisitManager(this);
}
}
public class EmployeeCollection : List<IEmployee>
{
public virtual void Accept(IVisitor visitor)
{
foreach (IEmployee employee in this)
employee.Accept(visitor);
}
}