✅ The verified answer to this question is available below. Our community-reviewed solutions help you understand the material better.
Який поведінковий патерн використано
class Program
{
static void Main(string[] args)
{
var books = new List<Book> {
new Book("The Stand", "Stephen King", CoverType.Paperback, 35000),
new Book("The Hobbit", "J.R.R. Tolkien", CoverType.Paperback, 25000),
new Book("The Name of the Wind", "Patrick Rothfuss", CoverType.Digital, 7500),
new Book("To Kill a Mockingbird", "Harper Lee", CoverType.Hard, 65000),
new Book("1984", "George Orwell", CoverType.Paperback, 22500) ,
new Book("Jane Eyre", "Charlotte Brontë", CoverType.Hard, 82750)
};
var digitalCoverSpec = new Specification<Book>(book => book.CoverType == CoverType.Digital);
var hardCoverSpec = new Specification<Book>(book => book.CoverType == CoverType.Hard);
var paperbackCoverSpec = new Specification<Book>(book => book.CoverType == CoverType.Paperback);
var extremeBudgetSpec = new Specification<Book>(book => book.PublicationCost >= 75000);
var highBudgetSpec = new Specification<Book>(book => book.PublicationCost >= 50000 && book.PublicationCost < 75000);
var mediumBudgetSpec = new Specification<Book>(book => book.PublicationCost >= 25000 && book.PublicationCost < 50000);
var lowBudgetSpec = new Specification<Book>(book => book.PublicationCost < 25000);
var defaultSpec = new Specification<Book>(book => true);
var publicationProcess = new PublicationProcess();
var ceo = new Employee<Book>("Alice", Position.CEO, publicationProcess.PublishBook);
var president = new Employee<Book>("Bob", Position.President, publicationProcess.PublishBook);
var cfo = new Employee<Book>("Christine", Position.CFO, publicationProcess.PublishBook);
var director = new Employee<Book>("Dave", Position.DirectorOfPublishing, publicationProcess.PublishBook);
var defaultEmployee = new Employee<Book>("INVALID", Position.Default, publicationProcess.FailedPublication);
director.SetSpecification(digitalCoverSpec.And<Book>(lowBudgetSpec));
cfo.SetSpecification(digitalCoverSpec.Or<Book>(paperbackCoverSpec).And<Book>(mediumBudgetSpec.Or<Book>(highBudgetSpec)));
president.SetSpecification(mediumBudgetSpec.Or<Book>(highBudgetSpec));
ceo.SetSpecification(extremeBudgetSpec);
defaultEmployee.SetSpecification(defaultSpec);
director.SetSuccessor(cfo);
cfo.SetSuccessor(president);
president.SetSuccessor(ceo);
ceo.SetSuccessor(defaultEmployee);
books.ForEach(book => director.PublishBook(book));
}
}
public class PublicationProcess
{
public void PublishBook(Book book)
{
book.Publish();
}
public void FailedPublication(Book book)
{
}
}
public enum CoverType
{
Digital,
Hard,
Paperback
}
public interface IPublishable
{
string Author { get; set; }
CoverType CoverType { get; }
decimal PublicationCost { get; set; }
void Publish();
string Title { get; set; }
}
public class Book : IPublishable
{
public string Author { get; set; }
public CoverType CoverType { get; set; }
public decimal PublicationCost { get; set; }
public string Title { get; set; }
public Book(string title, string author, CoverType coverType, decimal publicationCost)
{
this.Author = author;
this.PublicationCost = publicationCost;
this.CoverType = coverType;
this.Title = title;
}
public void Publish()
{
}
public override string ToString()
{
return $"{CoverType} cover '{Title}' by {Author} for {PublicationCost:C2}";
}
}
public interface ISpecification<in T>
{
bool IsSatisfiedBy(T expression);
}
public class Specification<T> : ISpecification<T>
{
private readonly Func<T, bool> _expression;
public Specification(Func<T, bool> expression)
{
this._expression = expression;
}
public bool IsSatisfiedBy(T expression)
{
return this._expression(expression);
}
}
public static class SpecificationExtensions
{
public static Specification<T> And<T>(this ISpecification<T> a, ISpecification<T> b)
{
if (a != null && b != null)
{
return new Specification<T>(expression => a.IsSatisfiedBy(expression) && b.IsSatisfiedBy(expression));
}
return null;
}
public static Specification<T> Or<T>(this ISpecification<T> a, ISpecification<T> b)
{
if (a != null && b != null)
{
return new Specification<T>(expression => a.IsSatisfiedBy(expression) || b.IsSatisfiedBy(expression));
}
return null;
}
public static Specification<T> Not<T>(this ISpecification<T> a)
{
// Check .
return a != null ? new Specification<T>(expression => !a.IsSatisfiedBy(expression)) : null;
}
}
public enum Position
{
CEO,
President,
CFO,
DirectorOfPublishing,
Default
}
public interface IEmployee<T>
{
void PublishBook(T book);
void SetSpecification(ISpecification<T> specification);
void SetSuccessor(IEmployee<T> employee);
}
public class Employee<T> : IEmployee<T> where T : IPublishable
{
private IEmployee<T> _successor;
private readonly string _name;
private ISpecification<T> _specification;
private readonly Action<T> _publicationAction;
private readonly Position _position;
public Employee(string name, Position position, Action<T> publicationAction)
{
_name = name;
_position = position;
_publicationAction = publicationAction;
}
public bool CanApprove(T book)
{
if (_specification != null && book != null)
{
return _specification.IsSatisfiedBy(book);
}
return false;
}
public void PublishBook(T book)
{
if (CanApprove(book))
{
if (_position != Position.Default)
{
}
_publicationAction.Invoke(book);
Logging.LineSeparator();
}
else
{
_successor?.PublishBook(book);
}
}
public void SetSpecification(ISpecification<T> specification)
{
_specification = specification;
}
public void SetSuccessor(IEmployee<T> employee)
{
_successor = employee;
}
}