Guided by practical examples this talk conveys the value of how code can become clearer when focusing on behavior, language, responsibility and the chosen model to implement. The clarity that ensues can lead to a more supple design allowing to implement - or assess the effort required to implement - future functionality faster.
Dart, le nouveau langage Web de Google présenté au public en octobre 2011 a pour objectif de proposer une alternative au JavaScript.
Bien que la version finale ne soit pas encore disponible (pour cela il faudra attendre cet été), Dart est utilisable dès aujourd'hui.
Au cours de cette présentation sont introduits les éléments suivants :
- comment Dart permet de développer des applications clientes aussi bien que serveurs,
- le langage,
- les outils permettant un développement industrialisé et une productivité accrue.
Dart, le nouveau langage Web de Google présenté au public en octobre 2011 a pour objectif de proposer une alternative au JavaScript.
Bien que la version finale ne soit pas encore disponible (pour cela il faudra attendre cet été), Dart est utilisable dès aujourd'hui.
Au cours de cette présentation sont introduits les éléments suivants :
- comment Dart permet de développer des applications clientes aussi bien que serveurs,
- le langage,
- les outils permettant un développement industrialisé et une productivité accrue.
Slides from my GeeCON 2014 Prague talk:
"Groovy is a dynamic language that provides different types of metaprogramming techniques. In this talk we’ll mainly see runtime metaprogramming. I’ll explain Groovy Meta-Object-Protocol (MOP), the metaclass, how to intercept method calls, how to deal with method missing and property missing, the use of mixins, traits and categories. All of these topics will be explained with examples in order to understand them.
Also, I’ll talk a little bit about compile-time metaprogramming with AST Transformations. AST Transformations provide a wonderful way of manipulating code at compile time via modifications of the Abstract Syntax Tree. We’ll see a basic but powerful example of what we can do with AST transformations."
The code is available at: https://github.com/lmivan/geecon2014-prague-metaprograming-with-groovy
Ralph Schindler (of Zend Framework) and Jon Wage (of Doctrine) presented these slides for a webinar hosted by zend.com (webinar available online).
Links are contained within the slides to the demo application that was also used during the webinar.
Spring Data is a high level SpringSource project whose purpose is to unify and ease the access to different kinds of persistence stores, both relational database systems and NoSQL data stores.
Quontra Solution offering advanced java online training with job placement assistance. We are having real time experienced java faculties which may help you and assist you all the time.
There are many chances to become a software programmer if you choose java technology
For free demo and any questions feel free to call us
Modul untuk Praktikum Pengolahan Database di Java dengan menggunakan konsep OOP Mata Pelajaran Pemrograman Internet dengan Java-JSP SMK Telkom Sandhy Putra Malang
Slides from my GeeCON 2014 Prague talk:
"Groovy is a dynamic language that provides different types of metaprogramming techniques. In this talk we’ll mainly see runtime metaprogramming. I’ll explain Groovy Meta-Object-Protocol (MOP), the metaclass, how to intercept method calls, how to deal with method missing and property missing, the use of mixins, traits and categories. All of these topics will be explained with examples in order to understand them.
Also, I’ll talk a little bit about compile-time metaprogramming with AST Transformations. AST Transformations provide a wonderful way of manipulating code at compile time via modifications of the Abstract Syntax Tree. We’ll see a basic but powerful example of what we can do with AST transformations."
The code is available at: https://github.com/lmivan/geecon2014-prague-metaprograming-with-groovy
Ralph Schindler (of Zend Framework) and Jon Wage (of Doctrine) presented these slides for a webinar hosted by zend.com (webinar available online).
Links are contained within the slides to the demo application that was also used during the webinar.
Spring Data is a high level SpringSource project whose purpose is to unify and ease the access to different kinds of persistence stores, both relational database systems and NoSQL data stores.
Quontra Solution offering advanced java online training with job placement assistance. We are having real time experienced java faculties which may help you and assist you all the time.
There are many chances to become a software programmer if you choose java technology
For free demo and any questions feel free to call us
Modul untuk Praktikum Pengolahan Database di Java dengan menggunakan konsep OOP Mata Pelajaran Pemrograman Internet dengan Java-JSP SMK Telkom Sandhy Putra Malang
This is a java lab assignment. I have added the first part java re.pdffeetshoemart
This is a java lab assignment. I have added the first part \"java retail class\" at the bottom. I am
unsure how to read the txt file into an array from the retail class. The stock txt file has been
added also.
A beginning framework and inventory list has been provided to you to use your Retail Item Class
as an array. Develop a program to accomplish the following menu items that can be selected by
the end user. Discussion of what each menu item should do is provided below the menu item.
Modify your object class file as desired. Please append initials to files created. Use Select-Case
for menu choices and methods to perform those choices. Please make a selection: 1. Open
Inventory File (This should ask the user for the file name, open the file and load the data into the
object array). 2. Display All (This should show a table of all items and data) 3. Display Reorder
Only (This should show only the stock number, Description and current quantity for items
requiring reorder) 4. Find Stock number (Allows the user to enter part of the description and
displays all matching stock numbers and descriptions matching that - case insensitive, such as
“cubs” or “cubs”) 5. Display Stock number (Allows user to enter stock number and displays
record of item) 6. Add Quantity (Asks for stock number and quantity for units, adds it to current,
displays record results) 7. Subtract Quantity (Asks for stock number and quantity, subtracts,
displays results including if reorder is needed.) 8. Change Price (Asks for stick number, changes
price to provided value, display results). 9. New Item (Allows adding a new item, updates count.
Display record results). 10. Save Inventory File (asks user for file name, save all inventory to
that file in a format that can be read back.)
public class RetailItem{
private String description;
private int unitsOnHand;
private double price;
private int restock;
public void setDescription(String userDescription){
description=userDescription;
}
public void setUnitsOnHand(int userUnitsOnHand){
unitsOnHand=userUnitsOnHand;
}
public void setPrice(double userPrice){
price=userPrice;
}
public String getDescription(){
return description;
}
public int getUnitsOnHand(){
return unitsOnHand;
}
public double getPrice(){
return price;
}
public double getTotal(){
int total = unitsOnHand=(int) price;
return total;
}
public boolean getRestock(){
return false;
}
public RetailItem(String descriptionGiven, int unitsOnHandGiven, double priceGiven, int
restockGiven){
description=descriptionGiven;
unitsOnHand=unitsOnHandGiven;
price=priceGiven;
restock=restockGiven;
}
}
Solution
public class RetailItem{
private int stocknumber;
private String description;
private int unitsOnHand;
private double price;
private int restock;
public void setDescription(String userDescription){
description=userDescription;
}
public int getStocknumber() {
return stocknumber;
}
public void setStocknumber(int stocknumber) {
this.stocknumber = stocknumber;
}
public void setUnitsOnHand(in.
The easy way to develop Java applications has always been the standard stack (Spring, JEE, SQL) that confirms the LAMP equivalent in Java-speak. This presentation compares this model with a real use case based on Guice, Jersey and AppEngine.
Utilocate offers a comprehensive solution for locate ticket management by automating and streamlining the entire process. By integrating with Geospatial Information Systems (GIS), it provides accurate mapping and visualization of utility locations, enhancing decision-making and reducing the risk of errors. The system's advanced data analytics tools help identify trends, predict potential issues, and optimize resource allocation, making the locate ticket management process smarter and more efficient. Additionally, automated ticket management ensures consistency and reduces human error, while real-time notifications keep all relevant personnel informed and ready to respond promptly.
The system's ability to streamline workflows and automate ticket routing significantly reduces the time taken to process each ticket, making the process faster and more efficient. Mobile access allows field technicians to update ticket information on the go, ensuring that the latest information is always available and accelerating the locate process. Overall, Utilocate not only enhances the efficiency and accuracy of locate ticket management but also improves safety by minimizing the risk of utility damage through precise and timely locates.
We describe the deployment and use of Globus Compute for remote computation. This content is aimed at researchers who wish to compute on remote resources using a unified programming interface, as well as system administrators who will deploy and operate Globus Compute services on their research computing infrastructure.
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
CyanicLab, an offshore custom software development company based in Sweden,India, Finland, is your go-to partner for startup development and innovative web design solutions. Our expert team specializes in crafting cutting-edge software tailored to meet the unique needs of startups and established enterprises alike. From conceptualization to execution, we offer comprehensive services including web and mobile app development, UI/UX design, and ongoing software maintenance. Ready to elevate your business? Contact CyanicLab today and let us propel your vision to success with our top-notch IT solutions.
Launch Your Streaming Platforms in MinutesRoshan Dwivedi
The claim of launching a streaming platform in minutes might be a bit of an exaggeration, but there are services that can significantly streamline the process. Here's a breakdown:
Pros of Speedy Streaming Platform Launch Services:
No coding required: These services often use drag-and-drop interfaces or pre-built templates, eliminating the need for programming knowledge.
Faster setup: Compared to building from scratch, these platforms can get you up and running much quicker.
All-in-one solutions: Many services offer features like content management systems (CMS), video players, and monetization tools, reducing the need for multiple integrations.
Things to Consider:
Limited customization: These platforms may offer less flexibility in design and functionality compared to custom-built solutions.
Scalability: As your audience grows, you might need to upgrade to a more robust platform or encounter limitations with the "quick launch" option.
Features: Carefully evaluate which features are included and if they meet your specific needs (e.g., live streaming, subscription options).
Examples of Services for Launching Streaming Platforms:
Muvi [muvi com]
Uscreen [usencreen tv]
Alternatives to Consider:
Existing Streaming platforms: Platforms like YouTube or Twitch might be suitable for basic streaming needs, though monetization options might be limited.
Custom Development: While more time-consuming, custom development offers the most control and flexibility for your platform.
Overall, launching a streaming platform in minutes might not be entirely realistic, but these services can significantly speed up the process compared to building from scratch. Carefully consider your needs and budget when choosing the best option for you.
Unleash Unlimited Potential with One-Time Purchase
BoxLang is more than just a language; it's a community. By choosing a Visionary License, you're not just investing in your success, you're actively contributing to the ongoing development and support of BoxLang.
In software engineering, the right architecture is essential for robust, scalable platforms. Wix has undergone a pivotal shift from event sourcing to a CRUD-based model for its microservices. This talk will chart the course of this pivotal journey.
Event sourcing, which records state changes as immutable events, provided robust auditing and "time travel" debugging for Wix Stores' microservices. Despite its benefits, the complexity it introduced in state management slowed development. Wix responded by adopting a simpler, unified CRUD model. This talk will explore the challenges of event sourcing and the advantages of Wix's new "CRUD on steroids" approach, which streamlines API integration and domain event management while preserving data integrity and system resilience.
Participants will gain valuable insights into Wix's strategies for ensuring atomicity in database updates and event production, as well as caching, materialization, and performance optimization techniques within a distributed system.
Join us to discover how Wix has mastered the art of balancing simplicity and extensibility, and learn how the re-adoption of the modest CRUD has turbocharged their development velocity, resilience, and scalability in a high-growth environment.
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Globus
The Earth System Grid Federation (ESGF) is a global network of data servers that archives and distributes the planet’s largest collection of Earth system model output for thousands of climate and environmental scientists worldwide. Many of these petabyte-scale data archives are located in proximity to large high-performance computing (HPC) or cloud computing resources, but the primary workflow for data users consists of transferring data, and applying computations on a different system. As a part of the ESGF 2.0 US project (funded by the United States Department of Energy Office of Science), we developed pre-defined data workflows, which can be run on-demand, capable of applying many data reduction and data analysis to the large ESGF data archives, transferring only the resultant analysis (ex. visualizations, smaller data files). In this talk, we will showcase a few of these workflows, highlighting how Globus Flows can be used for petabyte-scale climate analysis.
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteGoogle
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
👉👉 Click Here To Get More Info 👇👇
https://sumonreview.com/ai-pilot-review/
AI Pilot Review: Key Features
✅Deploy AI expert bots in Any Niche With Just A Click
✅With one keyword, generate complete funnels, websites, landing pages, and more.
✅More than 85 AI features are included in the AI pilot.
✅No setup or configuration; use your voice (like Siri) to do whatever you want.
✅You Can Use AI Pilot To Create your version of AI Pilot And Charge People For It…
✅ZERO Manual Work With AI Pilot. Never write, Design, Or Code Again.
✅ZERO Limits On Features Or Usages
✅Use Our AI-powered Traffic To Get Hundreds Of Customers
✅No Complicated Setup: Get Up And Running In 2 Minutes
✅99.99% Up-Time Guaranteed
✅30 Days Money-Back Guarantee
✅ZERO Upfront Cost
See My Other Reviews Article:
(1) TubeTrivia AI Review: https://sumonreview.com/tubetrivia-ai-review
(2) SocioWave Review: https://sumonreview.com/sociowave-review
(3) AI Partner & Profit Review: https://sumonreview.com/ai-partner-profit-review
(4) AI Ebook Suite Review: https://sumonreview.com/ai-ebook-suite-review
Top 7 Unique WhatsApp API Benefits | Saudi ArabiaYara Milbes
Discover the transformative power of the WhatsApp API in our latest SlideShare presentation, "Top 7 Unique WhatsApp API Benefits." In today's fast-paced digital era, effective communication is crucial for both personal and professional success. Whether you're a small business looking to enhance customer interactions or an individual seeking seamless communication with loved ones, the WhatsApp API offers robust capabilities that can significantly elevate your experience.
In this presentation, we delve into the top 7 distinctive benefits of the WhatsApp API, provided by the leading WhatsApp API service provider in Saudi Arabia. Learn how to streamline customer support, automate notifications, leverage rich media messaging, run scalable marketing campaigns, integrate secure payments, synchronize with CRM systems, and ensure enhanced security and privacy.
How to Position Your Globus Data Portal for Success Ten Good PracticesGlobus
Science gateways allow science and engineering communities to access shared data, software, computing services, and instruments. Science gateways have gained a lot of traction in the last twenty years, as evidenced by projects such as the Science Gateways Community Institute (SGCI) and the Center of Excellence on Science Gateways (SGX3) in the US, The Australian Research Data Commons (ARDC) and its platforms in Australia, and the projects around Virtual Research Environments in Europe. A few mature frameworks have evolved with their different strengths and foci and have been taken up by a larger community such as the Globus Data Portal, Hubzero, Tapis, and Galaxy. However, even when gateways are built on successful frameworks, they continue to face the challenges of ongoing maintenance costs and how to meet the ever-expanding needs of the community they serve with enhanced features. It is not uncommon that gateways with compelling use cases are nonetheless unable to get past the prototype phase and become a full production service, or if they do, they don't survive more than a couple of years. While there is no guaranteed pathway to success, it seems likely that for any gateway there is a need for a strong community and/or solid funding streams to create and sustain its success. With over twenty years of examples to draw from, this presentation goes into detail for ten factors common to successful and enduring gateways that effectively serve as best practices for any new or developing gateway.
Globus Connect Server Deep Dive - GlobusWorld 2024Globus
We explore the Globus Connect Server (GCS) architecture and experiment with advanced configuration options and use cases. This content is targeted at system administrators who are familiar with GCS and currently operate—or are planning to operate—broader deployments at their institution.
How Recreation Management Software Can Streamline Your Operations.pptxwottaspaceseo
Recreation management software streamlines operations by automating key tasks such as scheduling, registration, and payment processing, reducing manual workload and errors. It provides centralized management of facilities, classes, and events, ensuring efficient resource allocation and facility usage. The software offers user-friendly online portals for easy access to bookings and program information, enhancing customer experience. Real-time reporting and data analytics deliver insights into attendance and preferences, aiding in strategic decision-making. Additionally, effective communication tools keep participants and staff informed with timely updates. Overall, recreation management software enhances efficiency, improves service delivery, and boosts customer satisfaction.
Enhancing Research Orchestration Capabilities at ORNL.pdfGlobus
Cross-facility research orchestration comes with ever-changing constraints regarding the availability and suitability of various compute and data resources. In short, a flexible data and processing fabric is needed to enable the dynamic redirection of data and compute tasks throughout the lifecycle of an experiment. In this talk, we illustrate how we easily leveraged Globus services to instrument the ACE research testbed at the Oak Ridge Leadership Computing Facility with flexible data and task orchestration capabilities.
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...Juraj Vysvader
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I didn't get rich from it but it did have 63K downloads (powered possible tens of thousands of websites).
Developing Distributed High-performance Computing Capabilities of an Open Sci...Globus
COVID-19 had an unprecedented impact on scientific collaboration. The pandemic and its broad response from the scientific community has forged new relationships among public health practitioners, mathematical modelers, and scientific computing specialists, while revealing critical gaps in exploiting advanced computing systems to support urgent decision making. Informed by our team’s work in applying high-performance computing in support of public health decision makers during the COVID-19 pandemic, we present how Globus technologies are enabling the development of an open science platform for robust epidemic analysis, with the goal of collaborative, secure, distributed, on-demand, and fast time-to-solution analyses to support public health.
Understanding Globus Data Transfers with NetSageGlobus
NetSage is an open privacy-aware network measurement, analysis, and visualization service designed to help end-users visualize and reason about large data transfers. NetSage traditionally has used a combination of passive measurements, including SNMP and flow data, as well as active measurements, mainly perfSONAR, to provide longitudinal network performance data visualization. It has been deployed by dozens of networks world wide, and is supported domestically by the Engagement and Performance Operations Center (EPOC), NSF #2328479. We have recently expanded the NetSage data sources to include logs for Globus data transfers, following the same privacy-preserving approach as for Flow data. Using the logs for the Texas Advanced Computing Center (TACC) as an example, this talk will walk through several different example use cases that NetSage can answer, including: Who is using Globus to share data with my institution, and what kind of performance are they able to achieve? How many transfers has Globus supported for us? Which sites are we sharing the most data with, and how is that changing over time? How is my site using Globus to move data internally, and what kind of performance do we see for those transfers? What percentage of data transfers at my institution used Globus, and how did the overall data transfer performance compare to the Globus users?
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Design in the small
1.
2.
3.
4. public class Group {
public Guid Id { get; set; }
public string Name { get; set; }
public string Objective { get; set; }
public GroupType Type { get; set; }
//...
}
//Usage
var @group = new Group {
Id = message.GroupId,
Name = message.Name,
Objective = message.Objective,
Type = GroupType.Private
};
5. public class Group {
public Group(
Guid id,
string name,
string objective,
GroupType type)
{
//...
}
}
//Usage
var @group = new Group(
message.GroupId,
message.Name,
message.Objective,
GroupType.Private
);
6. public class PrivateGroup {
private PrivateGroup(/* ... */)
{
/* ... */
}
public static PrivateGroup Start(
GroupId id,
GroupName name,
GroupObjective objective)
{
//...
}
}
//Usage
var @group = PrivateGroup.Start(
new GroupId(message.GroupId),
new GroupName(message.Name),
GroupObjective.InferFrom(message.Objective)
);
7. public class Group {
public Group(
Guid id,
string name,
string objective,
GroupType type)
{
if(id == Guid.Empty)
throw new ArgumentException("...", "id");
if(string.IsNullOrEmpty(name))
throw new ArgumentException("...", "name");
if(name.Length > 255)
throw new ArgumentException("...", "name");
if(objective != null && objective.Length == 0)
throw new ArgumentException("...", "objective");
if(objective != null && objective.Length > 500)
throw new ArgumentException("...", "objective");
if(type != GroupType.Private && type != GroupType.Public)
throw new ArgumentException("...", "type");
//...
}
}
8. public class PrivateGroup {
public static PrivateGroup Start(
GroupId id,
GroupName name,
GroupObjective objective)
{
//...
}
}
9. public class GroupId {
private readonly Guid value;
public GroupId(Guid value)
{
if(value == Guid.Empty)
throw new ArgumentException("...", "value");
this.value = value;
}
public override bool Equals(object other)
{
if(other == null || other.GetType() != this.GetType()) return false;
return ((GroupId)other).value.Equals(this.value);
}
public override int GetHashCode()
{
return this.value.GetHashCode();
}
//...
}
10. public class GroupName {
private readonly string value;
public GroupName(string value)
{
if(string.IsNullOrEmpty(value))
throw new ArgumentException("...", "value");
if(value.Length > Metadata.MaximumGroupNameLength)
throw new ArgumentException("...", "value");
this.value = value;
}
//...
}
//Usage
@group.Rename(new GroupName(message.Name));
11. public class GroupObjective {
private static readonly GroupObjective NotSpecified = new GroupObjective(null);
private readonly string value;
private GroupObjective(string value)
{
this.value = value;
}
public static GroupObjective InferFrom(string value)
{
if(value == null) return NotSpecified;
if(value.Length == 0)
throw new ArgumentException("...", "value");
if(value.Length > Metadata.MaximumGroupObjectiveLength)
throw new ArgumentException("...", "value");
return new GroupObjective(value);
}
}
12. public class GroupObjective {
//...
public static GroupObjective InferFromMarkdown(string value)
{
if(value == null) return NotSpecified;
MarkDownDocument parsedDocument;
if(!MarkDownParser.TryParse(value, out parsedDocument))
throw new ArgumentException("...", "value");
var document = parsedDocument.Sanitize();
if(document.Text.Length == 0)
throw new ArgumentException("...", "value");
if(document.Text.Length > Metadata.MaximumGroupObjectiveLength)
throw new ArgumentException("...", "value");
return new GroupObjective(document.ToString());
}
}
13. public class GroupObjective {
private static readonly GroupObjective NotSpecified =
new GroupObjective(MimeType.PlainText, null);
private readonly MimeType mimeType;
private readonly string value;
private GroupObjective(MimeType mimeType, string value)
{
this.mimeType = mimeType;
this.value = value;
}
public static GroupObjective InferFromMarkdown(MarkDownDocument value)
{
if(value == null) return NotSpecified;
var document = value.Sanitize();
if(document.Text.Length == 0)
throw new ArgumentException("...", "value");
if(document.Text.Length > Metadata.MaximumGroupObjectiveLength)
throw new ArgumentException("...", "value");
return new GroupObjective(MimeType.Markdown, document.ToString());
}
}
14. public class GroupObjective {
public static GroupObjective InferFromMarkdown(SanitizedMarkDownDocument document)
{
if(value == null) return NotSpecified;
if(document.Text.Length == 0)
throw new ArgumentException("...", "value");
if(document.Text.Length > Metadata.MaximumGroupObjectiveLength)
throw new ArgumentException("...", "value");
return new GroupObjective(MimeType.Markdown, document.ToString());
}
}
15.
16.
17. public class FillPercentage {
private readonly double value;
public FillPercentage(double value)
{
if(value < 0)
throw new ArgumentOutOfRangeException("value", value,
"The fill percentage must be greater than or equal to 0.");
this.value = value;
}
public static FillPercentage FromPercentNotation(double value)
{
return new FillPercentage(value / 100d);
}
public static implicit operator double(FillPercentage instance)
{
return instance.value;
}
}
18. public class MaximumFillPercentage {
private readonly double value;
public MaximumFillPercentage(double value)
{
if(value < 1)
throw new ArgumentOutOfRangeException("value", value,
"The maximum fill percentage must be greater than or equal to 1.");
this.value = value;
}
public static MaximumFillPercentage FromPercentNotation(double value)
{
return new MaximumFillPercentage(value / 100d);
}
public static implicit operator double(MaximumFillPercentage instance)
{
return instance.value;
}
}
19. public class MaximumFillPercentage : IComparable<FillPercentage> {
//...
public int CompareTo(FillPercentage other)
{
return this.value.Compare(other);
}
}
21. public class FillPercentage {
//...
public bool Exceeds(MaximumFillPercentage maximum) {
return maximum < this;
}
}
22. public class Session
{
// ...
public Session Add(Timeslot timeslot)
{
return new Session(this.StartTime, this.EndTime,
this.MaximumFillPercentage, this.Timeslots.Add(timeslot));
}
public MaximumFillPercentage MaximumFillPercentage { get; }
public FillPercentage CurrentFillPercentage
{
get
{
var sessionDuration = this.EndTime.Subtract(this.StartTime);
var totalTimeslotDuration = this.Timeslots.Aggregate(Duration.Zero,
(current, timeslot) =>
current.Add(timeslot.DurationBetween(this.StartTime, this.EndTime)))
return new FillPercentage(
totalTimeslotDuration / sessionDuration);
}
}
}
23. public class ScheduleDay
{
public void Book(AppointmentTimeslot timeslot)
{
var beforeBooking = FindSessionToBookOn(timeslot);
var afterBooking = beforeBooking.Add(timeslot);
if (afterBooking
.CurrentFillPercentage
.Exceeds(beforeBooking.MaximumFillPercentage))
{
throw new MaximumFillPercentageExceededException(/* ... */);
}
// ...
}
}
28. public class PrivateGroupBehavior : BehaviorModule {
public PrivateGroupBehavior(
ITenantRepository tenantRepository,
IPrivateGroupRepository groupRepository)
{
Receive<StartPrivateGroup>(async message =>
{
var tenant = await tenantRepository.Get(new TenantId(message.TenantId));
var @group = tenant.StartPrivateGroup(
new GroupId(message.GroupId),
new GroupName(message.GroupName);
GroupObjective.InferFromMarkdown(message.GroupObjective));
groupRepository.Add(@group);
});
}
}
29. public class PrivateGroupScenarios {
[Fact] public async Task when_starting_a_private_group() {
using(var context = new GroupContext()) {
//Arrange
context.Tenants.Add(new TenantData { TenantId = 123, Subdomain = "nespresso" });
var module = new PrivateGroupBehavior(
new TenantRepository(context),
new PrivateGroupRepository(context)
);
//Act
await module.Send(new StartPrivateGroup {
TenantId = 123,
GroupId = new Guid("a9a620ca-c8c2-41b7-b7c0-fc03881ed00d"),
Name = "Prototype Retail Machines"
});
//Assert
Assert.Equal(1, context.PrivateGroups.Count());
GroupData actual = context.PrivateGroups.Single();
Assert.Equal(123, actual.TenantId);
Assert.Equal(new Guid("a9a620ca-c8c2-41b7-b7c0-fc03881ed00d"), actual.GroupId);
Assert.Equal("Prototype Retail Machines", actual.Name);
}
}
}
30. public class PrivateGroupScenarios {
[Fact] public Task when_starting_a_private_group() {
var tenantId = new Random().Next(1, 100);
var groupId = Guid.NewGuid();
return new Scenario()
.Given(tenantId, new TenantSnapshot {
TenantId = tenantId,
Subdomain = "nespresso"
})
.When(new StartPrivateGroup {
TenantId = tenantId,
GroupId = groupId,
Name = "Prototype Retail Machines"
})
.Then(groupId, new PrivateGroupSnapshot {
TenantId = tenantId,
GroupId = groupId,
Name = "Prototype Retail Machines"
})
.Assert(); // <- the boring stuff happens here
} //example of testing a state-based model
}
31. public class PrivateGroupScenarios {
[Fact] public Task when_starting_a_private_group() {
var tenantId = new Random().Next(1, 100);
var groupId = Guid.NewGuid();
return new Scenario()
.Given(tenantId, new RegisteredAsTenant {
TenantId = tenantId,
Subdomain = "nespresso"
})
.When(new StartPrivateGroup {
TenantId = tenantId,
GroupId = groupId,
Name = "Prototype Retail Machines"
})
.Then(groupId, new PrivateGroupStarted {
TenantId = tenantId,
GroupId = groupId,
Name = "Prototype Retail Machines"
})
.Assert(); // <- the boring stuff happens here
} //example of testing a event-driven model
}
32. public class PrivateGroupScenarios {
[Fact] public Task when_starting_a_private_group() {
var tenantId = new TenantId(new Random().Next(1, 100));
var subdomain = new Subdomain("nespresso");
var groupId = new GroupId(Guid.NewGuid());
var groupName = new GroupName("Prototype Retail Machines");
return new Scenario()
.Given(tenantId, new RegisteredAsTenant {
TenantId = tenantId,
Subdomain = subdomain
})
.When(new StartPrivateGroup {
TenantId = tenantId,
GroupId = groupId,
Name = groupName
})
.Then(groupId, new PrivateGroupStarted {
TenantId = tenantId,
GroupId = groupId,
Name = groupName
})
.Assert();
} //introducing value objects in your tests
}
33. public class PrivateGroupScenarios {
[Fact] public Task when_starting_a_private_group() {
var tenantId = new TenantId(new Random().Next(1, 100));
var subdomain = new Subdomain("nespresso");
var groupId = new GroupId(Guid.NewGuid());
var groupName = new GroupName("Prototype Retail Machines");
return new Scenario()
.Given(tenantId, new RegisteredAsTenant {
TenantId = tenantId,
Subdomain = subdomain
})
.When(new StartPrivateGroup {
TenantId = tenantId,
GroupId = groupId,
Name = groupName
})
.Then(groupId, new PrivateGroupStarted {
TenantId = tenantId,
GroupId = groupId,
Name = groupName
})
.Assert();
} //introducing value objects in your tests
}
34. public class PrivateGroupScenarios {
[Fact] public Task when_starting_a_private_group() {
var fixture = new ScenarioFixture();
var tenantId = fixture.Create<TenantId>();
var groupId = fixture.Create<GroupId>();
var groupName = fixture.Create<GroupName>();
return new Scenario()
.Given(tenantId, new RegisteredAsTenant {
TenantId = tenantId, Subdomain = fixture.Create<Subdomain>()
})
.When(new StartPrivateGroup {
TenantId = tenantId,
GroupId = groupId,
Name = groupName
})
.Then(groupId, new PrivateGroupStarted {
TenantId = tenantId,
GroupId = groupId,
Name = groupName
})
.Assert();
} //generate anonymous, random test values
}
51. public class MembershipRequest {
public void Approve(PersonId approver) {
if (this.Archived)
throw new MembershipRequestWasArchived(this.GroupId, this.RequestId);
if (this.Declined)
throw new MembershipRequestWasDeclined(this.GroupId, this.RequestId);
if (this.Cancelled)
throw new MembershipRequestWasCancelled(this.GroupId, this.RequestId);
if (this.Approved) return;
// ... happy path ...
}
}
52. public class MembershipRequest {
private enum State {
Requested, Approved, Declined, Cancelled, Archived
}
public void Approve(PersonId approver) {
if (this.CurrentState == State.Archived)
throw new MembershipRequestWasArchived(this.GroupId, this.RequestId);
if (this.CurrentState == State.Declined)
throw new MembershipRequestWasDeclined(this.GroupId, this.RequestId);
if (this.CurrentState == State.Cancelled)
throw new MembershipRequestWasCancelled(this.GroupId, this.RequestId);
if (this.CurrentState == State.Approved) return;
// ... happy path ...
this.CurrentState = State.Approved;
}
}