Specification模式的一个不错的示例代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SpecificationPattern.ProgramT
{
public class Mobile
{
public BrandName BrandName { get; set; }
public Type Type { get; set; }
public int Cost;
public string GetDescription()
{
return "The mobile is of brand : " + this.BrandName + " and of type : " + this.Type;
}
public Mobile(BrandName brandName, Type type, int cost = 0)
{
this.BrandName = brandName;
this.Type = type;
this.Cost = cost;
}
}
public enum BrandName
{
Samsung,
Apple,
Htc
}
public enum Type
{
Basic,
Smart
}
public interface ISpecification<T>
{
bool IsSatisfiedBy(T o);
ISpecification<T> And(ISpecification<T> specification);
ISpecification<T> Or(ISpecification<T> specification);
ISpecification<T> Not(ISpecification<T> specification);
}
public abstract class CompositeSpecification<T> : ISpecification<T>
{
public abstract bool IsSatisfiedBy(T o);
public ISpecification<T> And(ISpecification<T> specification)
{
return new AndSpecification<T>(this, specification);
}
public ISpecification<T> Or(ISpecification<T> specification)
{
return new OrSpecification<T>(this, specification);
}
public ISpecification<T> Not(ISpecification<T> specification)
{
return new NotSpecification<T>(specification);
}
}
public class AndSpecification<T> : CompositeSpecification<T>
{
ISpecification<T> leftSpecification;
ISpecification<T> rightSpecification;
public AndSpecification(ISpecification<T> left, ISpecification<T> right)
{
this.leftSpecification = left;
this.rightSpecification = right;
}
public override bool IsSatisfiedBy(T o)
{
return this.leftSpecification.IsSatisfiedBy(o)
&& this.rightSpecification.IsSatisfiedBy(o);
}
}
public class OrSpecification<T> : CompositeSpecification<T>
{
ISpecification<T> leftSpecification;
ISpecification<T> rightSpecification;
public OrSpecification(ISpecification<T> left, ISpecification<T> right)
{
this.leftSpecification = left;
this.rightSpecification = right;
}
public override bool IsSatisfiedBy(T o)
{
return this.leftSpecification.IsSatisfiedBy(o)
|| this.rightSpecification.IsSatisfiedBy(o);
}
}
public class NotSpecification<T> : CompositeSpecification<T>
{
ISpecification<T> specification;
public NotSpecification(ISpecification<T> spec)
{
this.specification = spec;
}
public override bool IsSatisfiedBy(T o)
{
return !this.specification.IsSatisfiedBy(o);
}
}
public class ExpressionSpecification<T> : CompositeSpecification<T>
{
private Func<T, bool> expression;
public ExpressionSpecification(Func<T, bool> expression)
{
if (expression == null)
throw new ArgumentNullException();
else
this.expression = expression;
}
public override bool IsSatisfiedBy(T o)
{
return this.expression(o);
}
}
public class PremiumSpecification<T> : CompositeSpecification<T>
{
private int cost;
public PremiumSpecification(int cost)
{
this.cost = cost;
}
public override bool IsSatisfiedBy(T o)
{
return (o as Mobile).Cost >= this.cost;
}
}
class ProgramT
{
static void Main(string[] args)
{
List<Mobile> mobiles = new List<Mobile> {
new Mobile(BrandName.Samsung, Type.Smart, 700),
new Mobile(BrandName.Apple, Type.Smart, 800),
new Mobile(BrandName.Htc, Type.Basic),
new Mobile(BrandName.Samsung, Type.Basic) };
ISpecification<Mobile> samsungExpSpec =
new ExpressionSpecification<Mobile>(o => o.BrandName == BrandName.Samsung);
ISpecification<Mobile> htcExpSpec =
new ExpressionSpecification<Mobile>(o => o.BrandName == BrandName.Htc);
ISpecification<Mobile> SamsungAndHtcSpec = samsungExpSpec.And(htcExpSpec);
ISpecification<Mobile> SamsungHtcExpSpec =
samsungExpSpec.Or(htcExpSpec);
ISpecification<Mobile> NoSamsungExpSpec = new ExpressionSpecification<Mobile>(o => o.BrandName != BrandName.Samsung);
ISpecification<Mobile> brandExpSpec = new ExpressionSpecification<Mobile>(o => o.Type == Type.Smart);
ISpecification<Mobile> premiumSpecification = new PremiumSpecification<Mobile>(600);
ISpecification<Mobile> complexSpec = (samsungExpSpec.Or(htcExpSpec)).And(brandExpSpec);
ISpecification<Mobile> linqNonLinqExpSpec = NoSamsungExpSpec.And(premiumSpecification);
//Some fun
Console.WriteLine("\n***Samsung mobiles*****\n");
var result = mobiles.FindAll(o => samsungExpSpec.IsSatisfiedBy(o));
result.ForEach(o => Console.WriteLine(o.GetDescription()));
Console.WriteLine("\n*****Htc mobiles********\n");
result = mobiles.FindAll(o => htcExpSpec.IsSatisfiedBy(o));
result.ForEach(o => Console.WriteLine(o.GetDescription()));
Console.WriteLine("\n****Htc and samsung mobiles*******\n");
result = mobiles.FindAll(o => SamsungHtcExpSpec.IsSatisfiedBy(o));
result.ForEach(o => Console.WriteLine(o.GetDescription()));
Console.WriteLine("\n****Not samsung*******\n");
result = mobiles.FindAll(o => NoSamsungExpSpec.IsSatisfiedBy(o));
result.ForEach(o => Console.WriteLine(o.GetDescription()));
Console.WriteLine("\n****Htc and samsung mobiles (only smart)*******\n");
result = mobiles.FindAll(o => complexSpec.IsSatisfiedBy(o));
result.ForEach(o => Console.WriteLine(o.GetDescription()));
//More fun
Console.WriteLine("\n****All premium mobile phones*******\n");
result = mobiles.FindAll(o => premiumSpecification.IsSatisfiedBy(o));
result.ForEach(o => Console.WriteLine(o.GetDescription()));
Console.WriteLine("\n****All premium mobile phones except samsung*******\n");
result = mobiles.FindAll(o => linqNonLinqExpSpec.IsSatisfiedBy(o));
result.ForEach(o => Console.WriteLine(o.GetDescription()));
Console.ReadLine();
}
}
}
Specification模式的一个不错的示例代码的更多相关文章
- 相邻div实现一个跟着另一个自适应高度示例代码
方法一: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> < ...
- 用vuex写了一个购物车H5页面的示例代码
用vuex写了一个购物车H5页面的示例代码:https://www.jb51.net/article/152008.htm 通过购物车的一个案列,把vuex学习了一篇. vuex概念浅谈 Vuex 是 ...
- 非常不错的一个JS分页效果代码
这里分享一个不错的js分页代码. 代码中cpage是页面计数,应为全局变量,可以随处调用它: totalpage是总页数. 与asp分页代码很类似,也是先取得记录总数,然后实现分页,基本的分页思路与原 ...
- 3.NetDh框架之缓存操作类和二次开发模式简单设计(附源码和示例代码)
前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...
- 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题
调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...
- 一个非常标准的Java连接Oracle数据库的示例代码
最基本的Oracle数据库连接代码(只针对Oracle11g): 1.右键项目->构建路径->配置构建路径,选择第三项“库”,然后点击“添加外部Jar”,选择“D:\Oracle\app\ ...
- java 添加一个线程、创建响应的用户界面 。 演示示例代码
javajava 添加一个线程.创建响应的用户界面 . 演示示例代码 来自thinking in java 4 21章 部分的代码 夹21.2.11 thinking in java 4免费下载: ...
- 一个非常标准的连接Mysql数据库的示例代码
一.About Mysql 1.Mysql 优点 体积小.速度快.开放源码.免费 一般中小型网站的开发都选择 MySQL ,最流行的关系型数据库 LAMP / LNMP Linux作为操作系统 Apa ...
- 一个 11 行 Python 代码实现的神经网络
一个 11 行 Python 代码实现的神经网络 2015/12/02 · 实践项目 · 15 评论· 神经网络 分享到:18 本文由 伯乐在线 - 耶鲁怕冷 翻译,Namco 校稿.未经许可,禁止转 ...
随机推荐
- 【无源汇有上下界可行流】ACdream1211-Reactor Cooling
[题意] 给出一些边流量的上界和下界,问能否循环流通. [思路] 黄学长讲得很清楚,直接贴过来: 上界用ci表示,下界用bi表示. 下界是必须流满的,那么对于每一条边,去掉下界后,其自由流为ci– b ...
- 实验四 Android程序设计-5
点击button按钮,进入下一活动,"the third activity"
- [HDU4729]An Easy Problem for Elfness
[HDU4729]An Easy Problem for Elfness 题目大意: 给你一棵\(n(n\le10^5)\)个点的树,树上每条边都有容量. \(m(m\le10^5)\)次询问,每次询 ...
- 交换x,y的三种方式
1 值传递: #include<iostream> using namespace std; int main(){ void change(int ,int); int x=2,y=3; ...
- fedora19/opensuse13.1 配置openvpn client
Date: 20140207Auth: Jin 1.install # yum -y install openvpn #zypper install openvpn 2.copy user key # ...
- 【spring cloud】spring cloud中启动eureka集群时候,发生端口已经绑定的报错The Tomcat connector configured to listen on port 8000 failed to start. The port may already be in use or the connector may be misconfigured.
在分别设置 进行微服务eureka集群启动时候,执行命令行启动jar包时候,报错前面一个端口8000已经被使用,而我这里启动的配置文件中端口号是8001,怎么会导致端口冲突呢?? 但是报错我的端口冲突 ...
- etcd,Docker问题汇总
单节点etcd publish error 正在愉快的进行jenkins流程,突然发现etcd连接不上去了.重新reboot后发现日志publish error Oct :: k8s-master e ...
- OCP试题解析之053-17 CONFIGURE CONTROLFILE AUTOBACKUP ON
17.You configure AUTOBACKUP to ON in an RMAN session. When will RMAN back up the control file? (Choo ...
- Spring与Quartz的整合
Quartz Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制.Quartz允许开发人员根据时间间隔来调度作业.它实现了作业和触发器的多 ...
- utf8汉字编码16进制对照(转载)
utf8汉字编码16进制对照 GB Unicode UTF-8 Chinese CharacterCode code# Code (coded in UTF-8)D2BB 4E00 E4 B8 80 ...